Skip to content

MarcoDaniels/elm-aws-cloudfront

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

elm-aws-cloudfront

Create AWS CloudFront Lambda@Edge functions in Elm.


This package uses an Elm headless worker under the hood requiring ports and a small JavaScript snippet to be bundled and deployed into AWS CloudFront Lambda@Edge. Check the examples folder.

Elm part:

port module MyModule exposing (main)

import CloudFront exposing (Model, Msg, cloudFront)
import CloudFront.Header exposing (withHeader)
import CloudFront.Lambda exposing (originResponse, toResponse)
import Json.Decode as Decode
import Json.Encode as Encode

port inputEvent : (Decode.Value -> msg) -> Sub msg

port outputEvent : Encode.Value -> Cmd msg

-- Optional flags can be used on init
-- main : Program {token : String} (Model {token : String}) Msg
main : Program () (Model ()) Msg
main =
    ( inputEvent, outputEvent )
        |> (originResponse
                (\{ response, request } _ ->
                    response
                        |> withHeader { key = "cache-control", value = "public, max-age=1000" }
                        |> toResponse
                )
                |> cloudFront
           )

JavaScript part:

const {Elm} = require('./elm');
// optinal flags can be passed on init
// const app = Elm.MyModule.init({flags: {token: 'my-token'}});
const app = Elm.MyModule.init();
exports.handler = (event, context, callback) => {
    const caller = (output) => {
        callback(null, output);
        app.ports.outputEvent.unsubscribe(caller);
    }
    app.ports.outputEvent.subscribe(caller);
    app.ports.inputEvent.send(event);
}

This repository also provides a nix builder to build and bundle the application to be ready to deploy into AWS. This requires to have the Elm ports named with:

port inputEvent : (Decode.Value -> msg) -> Sub msg

port outputEvent : Encode.Value -> Cmd msg

As the bundled JavasScript will automatically add the input and output ports with the specific name.

The nix builder requires the elm-srcs.nix and registry.dat files, and for that the elm2nix package is needed to generate them.

makeLambda.buildElmAWSCloudFront {
  src = ./src;
  elmSrc = ./elm-srcs.nix;
  elmRegistryDat = ./registry.dat;
  lambdas = [
    { module = ./src/MyModuleTwo.elm; }
    {
      module = ./src/MyModuleOne.elm;
      flags = [ ''token:"token-goes-here"'' ''url:"url-goes-here"'' ];
    }
  ];
}