An Introduction to the Serverless Framework

👋

@nathanjdunn

wtf is 'serverless', anyway?

🤷‍♀️

when might you use serverless functions

the problems...

getting started

npm install -g serverless
sls create --template hello-world --path hello-world
# serverless.yml

service: hello-world

provider:
  name: aws
  runtime: nodejs6.10

functions:
  helloWorld:
    handler: handler.helloWorld
    events:
      - http:
          path: hello-world
          method: get
          cors: true
// handler.js

'use strict';

module.exports.helloWorld = (event, context, callback) => {
  const response = {
    statusCode: 200,
    headers: {
      'Access-Control-Allow-Origin': '*', // Required for CORS support to work
    },
    body: JSON.stringify({
      message: 'Go Serverless v1.0! Your function executed successfully!',
      input: event,
    }),
  };

  callback(null, response);
};
sls deploy
serverless invoke --function helloWorld
serverless invoke local --function helloWorld

Warning!

Experimental code ahead!

service: flood-watch

provider:
  name: aws
  runtime: nodejs4.3
  region: eu-west-1
  iamRoleStatements:
  - Effect: "Allow"
    Action:
      - "s3:PutObject"
      - ...
    Resource: "arn:aws:s3:::floods/*"

functions:
  floodsOverview:
    handler: handler.getFloodsData
    events:
      - schedule: rate(15 minutes)
  floodWatch:
    handler: handler.floodWatchSkill
    events:
      - alexaSkill
module.exports.getFloodsData = function(event, context, callback) {
    request('https://api.ffc-environment-agency.fgs.metoffice.gov.uk/api/public/statements')
      .then((floodsData) => {
        let floodWarnings = JSON.parse(floodsData).statements;

        let warning = floodWarnings.filter(function(floodWarning) {
            let parsedDate = Date.parse(floodWarning.issued_at);

            return moment(parsedDate).format('DDMMYYYY') == 
            moment().format('DDMMYYYY');
        })[0];

        if (typeof warning == 'object') {
            let filesystem = new S3FS('floods', {region: 'eu-west-1'});

            filesystem.writeFile(
                'current.json', 
                JSON.stringify(warning), 
                function (err) {
                    if (err) throw err;
                }
            );
        }
    });
}
module.exports.floodWatchSkill = function(event, context, callback) {
    let alexa = Alexa.handler(event, context);
    alexa.appId = 'amzn1.ask.skill.88bf3bae-SECRET-APP-ID';
    alexa.registerHandlers(handlers);
    alexa.execute();
};

let handlers = {
    'LaunchRequest': function () {
        this.emit('GetOverviewIntent');
    },
    'GetOverviewIntent': function () {
        let filesystem = new S3FS('floods', {region: 'eu-west-1'});

        filesystem.exists('current.json', (fileExists) => {
            if (fileExists) {
                filesystem.readFile('current.json', "utf-8", (err, warning) => {
                    if (err) throw err;

                    let floodWarning = JSON.parse(warning);

                    this.emit(':tell', 
                        floodWarning.public_forecast.english_forecast
                    );
                });
            }
        });
    },
    'Unhandled': function() {
        this.emit(':ask', 
            'Sorry, I didn\'t get that. Please try again.', 'Please try again.'
        );
    }
};

Demo

In conclusion...

An Introduction to the Serverless Framework

By Nathan Dunn

An Introduction to the Serverless Framework

  • 318