Deploy an elm HTTP API to AWS Lambda using serverless. Define your API in elm and then use the npm package to bridge the interface between the AWS Lambda handler and your elm program.
NOTE: The master branch is on version 4.0.0 which is not yet released. This will include the following changes from release 3.
- Opaque
Conn
andPlug
types - A more efficient pipeline
- Proper JavaScript interop (#2)
You define a Serverless.Program
, which among other things, is configured with a Pipeline
.
main : Serverless.Program Config Model Msg
main =
Serverless.httpApi
{ configDecoder = configDecoder -- Decode once per Lambda container
, requestPort = requestPort
, responsePort = responsePort
, endpoint = Endpoint -- Processing starts with this msg
, initialModel = Model [] -- Fresh custom model per connection
, pipeline = pipeline -- Pipelines process connections
, subscriptions = subscriptions
}
- pipelines are lists of
Plug
s - each plug receives a connection (called
Conn
) and transforms it in some way - connections contain the HTTP request, the as yet unsent response, and some other stuff which is specific to your application
Basically, the pipeline takes the place of the usual update
function in a traditional elm app. And instead of transforming your Model
, you transform a Conn
, which contains your Model
, but also has the request, response, and per deployment configuration.
pipeline : Plug
pipeline =
pipeline
|> plug (cors "*" [ GET, OPTIONS ]) -- Plugs transform a connection
|> plug authentication -- Plugs are chained in a pipeline
-- ...
|> fork router -- Routers fork pipelines
For routing, we use ktonon/url-parser, which is a fork of evancz/url-parser adapted for use outside of the browser. A router function can then be used to map routes to new pipelines for handling specific tasks. Router functions can be plugged into the pipeline.
router : Conn -> Plug
router conn =
case -- Route however you want, here we
( conn |> method -- use HTTP method
, conn |> path |> parseRoute route NotFound -- and parsed request path
)
of
( GET, Home ) ->
responder responsePort <|
\_ -> ( 200, text "Home" )
-- vvvvvvvvvv -- -- UrlParser gives structured routes
( GET, Quote lang ) ->
Quote.pipeline lang -- Defer to another module
_ ->
responder responsePort <|
\conn -> ( 404, text <| (++) "Nothing at: " <| path conn )
There are two demos:
- ./demo: which is kept in sync with the master branch of this repository
- elm-serverless-demo: a separate repository which works with (the latest release)
The following is a list of known middleware:
- ktonon/elm-serverless-cors add CORS to your response headers
elm-serverless
targets Node.js 6.10. To get a development environment setup, fork and clone this repo. npm install
will also install elm packages for the base library as well as the demo. npm test
will perform the full range of tests including:
- ./test/bridge: unit tests for the JavaScript package
- ./test/demo: end-to-end tests for the included demo
- ./test/Serverless: unit tests for the elm package
The demo tests are written in JavaScript using supertest and mocha and rely on a running test instance of the demo server, which is started automatically when you run npm test
. You can also launch tests in watch mode with the command npm run test:watch
.
An AWS Lambda function would be pretty limited without an interface to the rest of AWS. AWS SDK for elm is a work in progress. I don't think there is a huge amount of work to be done here as we can probably generate the elm interface from the AWS SDK json files. But it is definitely non-trivial.