Rendering React with Amazon Lambda

Gerald Monaco
3 min readAug 9, 2015

--

I’ve been playing around with Amazon’s new AWS service, Lambda. It lets you write write functions and execute them on demand without having to worry about provisioning or scaling servers. You could also theoretically write your entire backend with just lambda functions.

I like React, but I wanted to see if I could speed up initial page loads (and support browsers that have JavaScript disabled, and SEO…) without worrying about running a server. Enter an even newer service from Amazon, API Gateway.

With API Gateway, you can build an interface for accessing and securing text-based APIs via proxying or Lambda functions. As it turns out, you can also render and serve your React application too.

I’ll quickly go through the steps that I used to get this working. I assume you are already familiar with developing React apps using the NPM, but that you’re not terribly familiar with Lambda or the API Gateway.

Our Lambda Function

I just started a new NPM module for my test, adding in the react package. Node.js lambda functions use a <FunctionName>.js format, where the module exports a handler function. So my index.js file looks like this:

var React = require(‘react’),
DOM = React.DOM;
var testComponent = React.createFactory(React.createClass({
render: function() {
return DOM.span(null, “hello”);
}
}));
exports.handler = function(e, context) {
context.succeed(React.renderToStaticMarkup(DOM.body(null,
testComponent(null)
)));
};

Pretty simple. When exports.handler is called by Amazon, we’ll make the lambda succeed and pass in our rendered HTML markup.

Next, zip up your index.js and node_modules (make sure that index.js is at the root, not inside a folder). Next, create a new Lambda function, skipping the blueprint selection:

Select a role, then create the function. In my case, the defaults were fine.

Our API Gateway

Start by creating a new API:

Next we need to create a GET method for when the browser hits our API, and have it call our lambda. I just created one on the root like so:

Now the confusing part. By default, API Gateway assumes your API is application/json. We need text/html. So enter your Method Response:

And change the Response Model for 200 to text/html. Now go back and edit the Integration Response. Edit the application/json mapping template to text/html, and change Output Passthrough to Mapping Template. Finally, enter:

$input.path(‘$’)

This is just telling Amazon to take the output from our function (a JSON string) and write it out directly, instead of as JSON. It should look like this:

Click the check next to Mapping Template to save it. Now you just need to Deploy API and test it out!

If everything was done correctly, you should see hello as the output. You may want to verify that the correct headers are being set too.

Where To Go Next

This is a pretty simple example. For a production app, you would want to set up routing in your React app. Unfortunately, API Gateway doesn’t currently seem to support wildcard or RegEx in paths (though simple Resources can be parameterized). That means if you want to render more than just the home page, you’ll have to somehow import some of your routes into API Gateway.

--

--