So you want to handle a web request?

Date:
$ npm install --global hydrator
$ mkdir my-proj && cd my-proj
$ echo "response.ok('Hello, world! ' + new Date());" > index.hydrator.js
$ hydrator deploy
Project is deployed to http://sparkling-waterfall-62f644.rehydrated.site
$

Wait, it’s that easy to build and deploy a dynamic website? Yes! Here’s why:


Handling web requests dynamically is complicated. It used to be mind-bogglingly more so. The perpetual collaborative layer cake of abstraction has thankfully made it less difficult over time. Services like Digital Ocean abstract the physicality of a server. Services like Heroku abstract the common virtual machinery of the server and let you focus (mostly) on the application-specific code. But it’s still not as simple as pointing a URL to a process. Even as a Web Development Professional, I continue to find getting a small project started more complex than it needs to be, especially with the pace of change these days. Behind the problematic “How it feels to learn JavaScript in 2016” rant there is the good point about how web development is still tricky to get restarted in after a break, let alone from scratch.

AWS Lambda gets really, really close to the URL–process ideal. The code necessary can be entirely focused on the specific problem. However, being an enterprise-level tool that needs to address many usecases, it requires quite a bit of configuration to get started. Also, its development workflow has a lot of room for improvement. Heroku’s toolbelt solves a lot of the workflow issues with simple commands like heroku create and deploys being a git push, but there still needs to be code to deal with request parsing, routing, response generation, etc.

The static site world has the routing problem solved: URLs map to files. The URL structure and the folder structure are 1:1, easy to inspect and understand. Deploying static sites is also about as easy as it can get now. Surge is wonderfully simple with only the command surge to deploy, with the inherent limitation of static-server sites. There are may others that sync with Dropbox, respond to git pushes, and so on.

There is quite a lot that can be done with only client-side dynamic code. But much of that client-side capability comes with the need for a build process, and sometimes you just need the server to be dynamic.

Can we take the static file simplicity and add some dynamism? PHP traces its origin back to the URL-executable file approach, and has several positive aspects through its environment and ecosystem, but also has some unfortunate technical baggage from its organic evolution.

Can we avoid needing a separate language for the server and any executable code on the client? Being able to transfer skills from one context to another is a powerful feature, the power to mess with something in the browser console then decide it needs to happen server-side and simply copy–paste it over. It’s also one fewer dependency.

Can we reduce or even eliminate the development environment configuration? Anil Dash asked on Twitter last year about barriers to coding, why people stopped. So many of the technical answers were along these lines:

@alexhern @anildash so much of learning to be a programmer is "how the fuck do I get these dependencies installed" — @tinysubversions

@anildash the yak shave of figuring out the environment. — @Bopuc

@anildash One thing that still fucks with me is "add the __ to your PATH variable". what newb knows wtf that means? — @dtwps

@anildash literally stuff like "where do I type code into?" "How do I get python on my computer?" "How do I save a program and make it run" — @alexhern

@anildash I did learn to code, but setting up development environments and tools was a consistent barrier and/or irritation. Ugh. @spolsky — @michaelbolton

And can we make it trivial to publish the app to the world? It’s one thing to use a template to get all the boilerplate in place. It’s another entirely to make the code accessible to anyone on the web.

@anildash theory -> practice hugely underdocumented. Once I left codecademy, I suddenly realised I didn't know basic shit. — @alexhern

@anildash I haven't stopped, but sheer bulk and churn of what's “required” becomes overwhelming, discouraging. I can't imagine starting >~2010 — @AaronWinters916

Can we include basic build processes so people can try new JavaScript features without all the rigamarole needed to ensure compatibility during deployment? And can we do so in a way that doesn’t forget about getting basic things done?

@anildash Also most languages are arcanely complex compared to the simple ideas newbs like myself want to explore. — @jim_unwin

This talk at Manhattan.JS last year about the Bloomberg “What is code?” piece by Paul Ford really stuck with me:

"we wanted it to be modularized w/o build process for people with different env" - @tophtucker at manhattan.js I love it. cc: @adamrpearce — @kosamari

It was super nice to see where things are & send PR w/o figuring out goddam build process for 4h before you actually code. — @kosamari

The accessibility that comes with not using a build process and depending on an environment is often ignored.


So back to this snippet of shell commands:

$ npm i -g hydrator
$ mkdir my-proj && cd my-proj
$ echo "response.ok('Hello, world! ' + new Date());" > index.hydrator.js
$ hydrator deploy

There is still the ladder of complexity for those new to node & npm, but it’s neat to to fit a 0–60 website deployment into a tweet’s worth of characters.

For example, here is a functionally useful server-side webapp in 138 significant characters (that outputs 100% valid HTML5):

response.ok(`
    <!doctype html>
    <html>
        <head>
            <title>Coinflip</title>
        </head>
        <body>
            <h1>${ Math.random() > 0.5 ? 'Heads' : 'Tails' }</h1>
        </body>
    </html>
`);

The only step between that code snippet in a folder being accessible online is a hydrator deploy command. No additional configuration or boilerplate required. Any text editor will do, any browser will do. There’s no routing system to grok, no virtual machine to run. It uses regular JavaScript that (syntactically) works in the browser.

response.ok() is a bit magical and seems to come from nowhere, but it’s not unlike window.addEventListener(); and so on. Code pretty much always has those kinds of implicitly available tools, and we can take advantage of that to reduce boilerplate. While the framework has additional capability to avoid needing to mash strings together, the basic approach doesn’t require anything more than saying “respond okay with this string”. I’m wary of doing too much magic, but this feels like a good balance that avoids straying too far from fundamentals. For the most part, what magic is there is limited to taking a single input and transforming it into an output.


For now, API keys are required while the hosting platform grows and matures. However, the goal is for a developer, expert or new, to be able to do exactly this:

$ npm install --global hydrator
$ mkdir hello-world && cd hello-world
$ echo "response.ok('Hello, world! ' + new Date());" > index.hydrator.js
$ hydrator deploy --email [email protected]

and from near-scratch1, they get a dynamic website deployed to the world.

Plus, the first step is only necessary once, as is the email address option. (An email address is required the first deploy as a way to have soft user accounts and allow for recovery in case the local copy of the credentials is lost.)

Feel free to install Hydrator and give it a try locally with hydrator serve. You can request an API key here or using hydrator auth --email <[email protected]>.


1. //TODO: Remove the node/npm step. For now, the CLI requires node & npm pre-installed. The plan is to encapsulate this in a GUI using something like Electron.