1.2.3 • Published 3 years ago

brianda-router v1.2.3

Weekly downloads
224
License
ISC
Repository
github
Last release
3 years ago

brianda-router

API router like express for lambda functions.

Overview

Brianda router is an API router for AWS Lambda functions with serverless framework, this library extract the express basics, to create a router for Lambda functions.

When is necessary use a router?

Well, often we create many functions handlers for many resources in our serveless.yml like:

  users-service
      handler: v2/handlers/users-service.main
      events:
        - http:
            path: v2/users
            method: get
            cors: true
            authorizer: aws_iam
  orders-service:
      handler: v2/handlers/orders-service.main
      events:
        - http:
            path: v2/orders
            method: get
            cors: true
            authorizer: aws_iam
  reports-service:
    handler: v2/handlers/reports-service.main
    events:
      - http:
          path: v2/reports
          method: get
          cors: true
          authorizer: aws_iam
  ...

For each function, AWS cloudFormation, create more than one resource, like:

    AWS:Lambda:Function
    AWS:Lambda:Version
    AWS:Lambda:LogGroup
    AWS:Lambda:Permission
    AWS:ApiGateway:Method
    etc...

So, When we have many functions in one stack, we could get the 200 resource limitation error.

Note: For more information, please check this article

Installation

npm install brianda-router

Using

First required step.

We need first, modify our serverless.yml

    v2-app:
        handler: handlers/app.main
        events:
          - http:
              path: v2/{proxy+}
              method: ANY
              cors: true
              authorizer: aws_iam

Here is an inplementation example:

Note: Brianda router is ever async based functions.

    const Brianda = require("brianda-router");
    
    // Very similar to express
    const app = Brianda();
    
    app.get("/users", async (req, res) => {
      // ... Do anything with req
      return res.send("Hello Brianda!");
    });
    
    exports.main = app.toLambda();

When we use the next middleware execution, we have to return the next function with event to pass to the next middleware function like this:

    app.use(async (req, res, next) => {
      // This apply for all methods in app router
      return next(req);
    });

Using multiples routers in a router.

    const app = Brianda();
    const admin = Brianda();
    
    admin.use(async (req, res, next) => {
      // Protected route
      if (req.headers.authorization) {
        // Token verification
        return next(req);
      }
      
      res.statusCode = 401;
      return res({ message: "No authorized"});
    });
    
    admin.get("/secrets", async (req, res) => {
      return res("top secret!");
    });
    
    app.use('/admin', admin);
    
    exports.main = app.toLambda();

Working with path parameters

Often we need transport data in a idiomatic way to client like /api/user/bpinedah, well:

    app.get("/user/:username", async (req, res) => {
      // Do anything with params like this:
      const username = req.params.username;
      
      return res.send(username);
    });

Query string parameters

Query string params is available too, example: /api/user?usermane=bpinedah

    app.get("/user", async (req, res) => {
      // Do anything with params like this:
      const username = req.query.username;
      
      return res.send(username);
    });

Wildcard on route

Sometimes we need to apply one function to anything after specific route slash sequence, like api/users/*

    app.use("/users/(.*)", async (req, res, next) => {
      // This apply to anything after this route
     return  next(req);
    })

Multiple middlewares

When we want to do anything with request data, before or after of handler controller, we need to apply middlewares functions like this:

    app.post("/users/create", async (req, res, next) => {
      // Do anything with req before pass to handler function
      req.body.hello = "Brianda";
      return next(req);
    }, async (req, res, next) => {
      // Handler function... do anything with req.body
      const data = { message: `Hello from ${req.body.hello}`};
      
      return next(data);
    }, async (req, res) => {
      // Last middleware function
      console.log(req); // { message: "Hello from Brianda" }
      
      return res.send(req);
    })

Response events

If we need to listen when the request is finished, we have res.on(event, cb) method to add new listener to any event. By now the end event is the only one available, we work hard to add new events.

    app.use(async (req, res, next) => {
      res.on("end", data => {
        console.log(data); // {Response end data}
        return next(req);
      });
    });

Response end object

The response end event object, have the next properties:

    const endObject = {
      headers: {},
      statusCode: 200,
      params: {},
      query: {},
      body: {} // or any data
    };
    
    console.log(endObject);

Notes

  • The entire native event request from Lambda API Gateway is present ever in each request, thus always will can access to the object.
  • We will work in a new features like no async inclusion and avoid return statement in each function to return the response.
  • By now we decided leave out to the context object, however we 'll work to include in the request.
  • All implicit method not supported by now.

    Contributions

    For any contrbution, please contact me.

  • Bruno Pineda - bpinedah

    Changes log

  • v1.0.2 - Fix unhandled error for all (*) method through use() function by now not supported.

  • v1.0.3 - More description on documentation about usage.
  • v1.2.0 - Event emitters added (end event by now).
  • v1.2.1 - Fix an error on Pipeline functions.
  • v1.2.2 - Fix router proxy detection regex.
1.2.3

3 years ago

1.2.2

4 years ago

1.2.1

4 years ago

1.2.0

4 years ago

1.0.3

4 years ago

1.0.2

4 years ago

1.0.1

4 years ago

1.0.0

4 years ago