Skip to content

Typescript decorators to simplify aws lambda functions development with serverless

License

Notifications You must be signed in to change notification settings

hpfs74/serverless-api-decorators

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

75 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Serverless api decorators

serverless Build Status MIT license Conventional Commits

sls-api-decorator is a PoC on using typescript decorators to decorate classes that rapresents a service (in serverless idiom) and their methods that will map to endpoints. It supports only aws lambdas.

It basically allow the developer to define a set of aws lambda functions as methods of the same class.

Loading the sls-api-decorators plugin will automatically generate the lambda definitions in serverless.yaml

@Endpoint()
export class MyService {

  @Lambda()
  public sayHello(event) {
    return { message : 'Hello there'}
  }
}

sayHello function is wrapped in a promise and will automatically handle thrown errors.

How to use

Create a serverless project

sls create -t aws-nodejs

  • specify your service name and comment out functions section

####Install serverless-webpack plugin

  • npm i -S serverless-webpack

set up to run with typescript

 npm i -S typescript ts-node
plugins:
  - serverless-webpack

create webpack.config.js

// webpack.config.js

var path = require('path');
var webpack = require('webpack');

module.exports = {
  entry: './api/index.ts',
  output: {
    libraryTarget: 'commonjs',
    path: path.join(__dirname, '.webpack'),
    filename: 'index.js'
  },
  target: 'node',
  module: {
    loaders: [
      { test: /\.ts(x?)$/, loader: 'ts-loader' }
    ]
  },
  resolve: {
    extensions: ['.ts', '.js', '.tsx', '.jsx', '']
  },
};

create tsconfig.json

{
  "compilerOptions": {
    "target": "es2015",
    "module": "commonjs",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "sourceMap": true,
    "declaration": true
  },
  "exclude": [
    "node_modules"
  ]
}

add npm scripts

  "scripts": {
    "start": "npm run webpack",
    "webpack": "sls webpack serve'"
  }

Install sls-api-decorators

npm i -S sls-api-decorators

Edit you plugins section and add typescript output folder.

plugins:
  - serverless-webpack
  # this will dynamically set the functions in serverless.yaml
  - sls-api-decorators

custom:
  # this will be the same output folder set up in webpack.config.js
  artifactsFolder: .webpack

create api/user/user.service.ts

The following will define a service with base path users that will expose two endpoints:

  • users/
  • users/error

The latter being to demostrate error throwing.

// user.service.ts

import  * as Debug  from "debug";
   import {Service, Endpoint} from "sls-api-decorators";


   const debug = Debug('bazooka');


   @Endpoint({
     // name of the service (not in the serverless meaning of service)
     // will be used in the future for di purpose
     name: 'userService',
     // this will rapresent the base path for this service
     // i.e.: http://localhost:8000/users
     path: 'users',
     // Allow xOrigin request [TBD]
     xOrigin: true
   })
   class UserService {
     constructor() { }

     @Lambda({
       // name to reference this method in the serverless ecosystem
       // i.e.: to be used with invoke command
       name: 'hello',
       // sub-path for this endpoint
       // i.e.: http://localhost:8000/users/
       path: '/',
       // method to which this function should listen
       // i.e.: 'get' or ['get', 'post'] [TBD]
       method: 'get',
       // this is just required from serverless-webpack plugin
       integration: 'lambda'
     })
     public welcome(event) {
       debug('Running welcome');

       return { message: 'Go Serverless Webpack (Typescript) v1.0! Your function executed successfully!', event };

     }

     // demostrate use of path params and arguments injection
     // arguments being injected from event.path
     @Lambda({
       name: 'getById',
       path: '/{id}',
       method: 'get',
       integration: 'lambda'
     })
     public getById(id) {
       debug('Running get by id:', id);

       return {
         id: 'abc',
         name: 'dcavaliere',
         email: 'cavaliere.davide@gmail.com'
        };

     }

     @Lambda({
       name: 'error',
       path: 'error',
       method: 'get',
       integration: 'lambda'
     })
     public error(event) {
       debug('throwing an error');
       // throwing an error will reject the lambda cb
       throw new Error('something weird just happened');
     }
   }

   export { UserService };

create api/index.ts

The following will expose the service to be used by serverless

this should be replaced in future versions by a DI system

// api/index.ts

import { Api } from 'sls-api-decorators/lib/application';
import { UserService } from './user/user.service';
import { User } from './user/user.model';


@Api({
  // used for DI purposes
  name : 'app'
  // need to define factories and servises
  factories: [User],
  services: [UserService]
})
class App { }


const app = new App();

export { app };

run npm start sit back and start coding :)

About

Typescript decorators to simplify aws lambda functions development with serverless

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 93.8%
  • JavaScript 6.2%