One of the common synonyms for “serverless” is “Function as a Service”: there is a place in the cloud that we upload a function to, and it runs when some event is triggered. Web services are easily modeled as functions in Clojure/Script, so that’s how we’re going to set ours up.
Yesterday in part one we set up our ClojureScript environment to prepare for writing an AWS Lambda function that will use the Node.js runtime. Today, we need to do two things: write our JWT translation functions and route requests to them.
The JWT functions themselves are simple. In
Each function creates a
core.async channel and uses
callback functions to put its value there. We’ll be passing those channels
back to the gateway function we defined in part one. Note that in this case
jsonwebtoken does have synchronous versions of these functions, but I
used the async versions since almost all the real work you end up doing will
require this pattern.
Now lets build our routes using
bidi routes are simple data
structures that can be passed to the
match-route function and resolve
to whatever value you give them; in our case, symbols for our JWT functions.
You can test the routes out in the REPL:
Let’s add a little JS/CLJS/JSON plumbing:
And now we can alter our gateway function to handle input, output, and routes:
We’re destructuring the event map
cljs-lambda will be passing our gateway
into its path, request method, and body. We match the route, pass the
JSON-decoded body to the correct handler, take the result off the returned
channel, and format it to go back out into the API Gateway world. Note that
instead of returning a map literal now, our gateway function returns the
core.async channel generated by
cljs-lambda knows when it gets
a channel back to take a result off of it and return that to the gateway.
Let’s test it out in the REPL:
So we’ve got everything we need for our simple web service. In part three, we’ll deploy it to AWS and hook it up to the API Gateway and the wider web.