Portable Serverless Apps

Portable Serverless Apps

ServerlessDays, London, July 6th, 2018

Can you design serverless applications that run in multiple environments, for example having the same code executed in AWS Lambda and Docker containers? Or the same business logic being triggered via an API or while processing a real-time stream of data? In this session, we’ll review some best practices that make serverless development more readable, testable and reusable.

7c9b8b368924556d8642bdaed3ded1f5?s=128

Danilo Poccia

July 06, 2018
Tweet

Transcript

  1. 4.

    "use strict"; console.log('Loading function'); exports.handler = async (event, context) =>

    { console.log('request: ' + JSON.stringify(event)); let name; // default value is undefined if (event.queryStringParameters != null) { name = event.queryStringParameters.name; } console.log('name: ', name); if ((name == undefined) || (name == '')) { name = 'World'; } const greetings = 'Hello ' + name + '!'; console.log('greetings: ', greetings); const responseCode = 200; const responseBody = { message: greetings; }; const response = { statusCode: responseCode, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(responseBody) }; console.log('response: ' + JSON.stringify(response)); return buildResponse(); }; { “message": "Hello Danilo!” } { “message": "Hello World!” }
  2. 6.

    “use strict"; console.log('Loading function'); // Your business logic function greetingsFor(name)

    { console.log('name: ', name); if ((name == undefined) || (name == '')) { name = 'World'; } const greetings = 'Hello ' + name + '!'; console.log('greetings: ', greetings); return greetings; } // Event wrapper for Amazon API Gateway exports.handler = async (event, context) => { let buildResponse = (message) => { const responseCode = 200; const responseBody = { message: message }; const response = { statusCode: responseCode, headers: { 'Content-Type' : 'application/json' }, body: JSON.stringify(responseBody) }; console.log('response: ' + JSON.stringify(response)); return response; }; console.log('request: ' + JSON.stringify(event)); let name; // default value is undefined if (event.queryStringParameters != null) { name = event.queryStringParameters.name; } return buildResponse(greetingsFor(name)); }; // If not running on AWS Lambda, use Express if (!(process.env.LAMBDA_TASK_ROOT && process.env.AWS_EXECUTION_ENV)) { const express = require('express'); const app = express(); let buildResponse = (message) => { const responseBody = { message: message }; const response = JSON.stringify(responseBody); console.log('response: ' + response); return response; }; app.get('/', function (req, res) { res.send( buildResponse(greetingsFor(req.query.name)) ); }); console.log("Listening..."); app.listen(process.env.PORT || 3000); } Business Logic Event Wrapper Web Interface
  3. 8.

    "use strict"; console.log('Loading function'); // Your business logic function greetingsFor(name)

    { console.log('name: ', name); if ((name == undefined) || (name == '')) { name = 'World'; } const greetings = 'Hello ' + name + '!'; console.log('greetings: ', greetings); return greetings; } "use strict"; const app = require('../../app.js'); const chai = require('chai'); const expect = chai.expect; var event, context; describe('Tests index', function () { it('verifies successful response', async () => { const result = await app.lambda_handler(event, context, (err, result) => { expect(result).to.be.an('object'); expect(result.statusCode).to.equal(200); expect(result.body).to.be.an('string'); let response = JSON.parse(result.body); expect(response).to.be.an('object'); expect(response.message).to.be.equal("Hello World!”); expect(response.location).to.be.an("string"); }); }); }); Business Logic Unit Tests