Blog by Sumana Harihareswara, Changeset founder
Sometimes Paths Are Useful
Hi, reader. I wrote this in 2014 and it's now more than five years old. So it may be very out of date; the world, and I, have changed a lot since I wrote it! I'm keeping this up for historical archive purposes, but the me of today may 100% disagree with what I said then. I rarely edit posts after publishing them, but if I do, I usually leave a note in italics to mark the edit and the reason. If this post is particularly offensive or breaches someone's privacy, please contact me.
I just finished a six-week batch at Hacker School. As an alumna, I had the option of asking to come back for three months or for a six-week minibatch, and I decided on the latter. I'll be writing more about my lessons, but today I can mostly point to my programming partner's writeup and add a silly story.
I met Greg Hendershott at !!Con months back, and then we ended up in the same batch and found that we laugh at each other's jokes. So we tried to figure out what to work on together. He's way into functional programming, Racket, Clojure, stuff like that, and has for instance written an emacs mode for Racket. In contrast, I'm only fluent in Python and have been concentrating on web dev. We found common ground in Python and an interest in security, and made a webservice that runs a static analyzer on a user-submitted code sample and returns to the user a "report card" of vulnerabilities in their code. That's what I spent the last two weeks on.
In his post, Greg describes how we rejected smaller and smaller web frameworks, finally settling on subclassing from BaseHTTPServer
(built into Python's standard library). When you do that, you have to literally define methods so that the server can handle even the most basic HTTP verbs, like GET
and POST
. We defined POST
but didn't define GET
, because we didn't need to! It felt so tremendously subversive, creating a web service that gave you a 501 (Method Not Supported) if you tried to GET /
, and yet actually did other things. Deliciously wrong.
(Also amazing: reading and subclassing from code whose initial code comments specifically and relevantly cite the work of Tim Berners-Lee and Roy Fielding. I felt such awe and gratitude, that I am part of a grand heritage of innovation and infrastructure. What an inheritance!)
So then a few days later we decided to make a simple web page or two, so that someone using a web browser could use the service. I loved the experience of API-first design, and felt amused when I implemented our server's second method, do_GET
. (One nice thing about long-term collaboration is that you can pair some of the time and also do some bits on your own, bringing them to your partner for code review.) do_GET
, like do_POST
, didn't care about the path, because there's only one thing a user is ever going to do with our service. No URL routing required. A GET
request always caused the server to return index.html.
Then I stubbed out a small index.html page, borrowing bits and pieces from other past projects where I'd solved similar problems. And I thought "well I'll style this a bit" and copied a style.css file from one of my old sites into the project directory, linked to it in the head
element of index.html, futzed with some element names and IDs, and reloaded. Hmm, why no styling? Shift-reload. Still looked bare. I opened up the developer toolbar...
...and saw that "style.css" had the text of index.html. Because I had defined GET
to always return index.html! And when you want a browser to be able to use a stylesheet, well, it'll have to GET
it!
I laughed pretty hard, then inlined the CSS. (And we did end up writing a bit of URL routing so we could serve a favicon to browsers and to serve a capabilities document to service clients.)
I get so much joy out of playing with the building blocks of the Web. It's a great feeling. Thanks for working on this with me, Greg!
Comments
Brendan
14 Nov 2014, 20:32 p.m.
I love this story.