Serverless Middlewares


Middlewares allows adding a reusable capability to lambda functions at Develop/Prepare time. Create middlewares similar to lambda functions with a resource entry in serverless/template.yaml and typescript code at serverless/functions/middlewares/. SOMOD defines multiple ways to attach middleware to a lambda function as described in the later sections of this page. During the preparation step, SOMOD bundles the code of the attached middleware and the actual function together. When deployed, the lambda function will have code from multiple middlewares and the original lambda function code.

Middleware Callstack

The middlewares are called in the order of their attachment to the function.

(event, context) (response) || /\ __________||___________________||__________ | || Middleware 1 || | | ______||___________________||______ | | | || Middleware 2 || | | | | __||___________________||__ | | | | | || Function || | | | | | | \/ || | | | | | | ---------------> | | | | | | | | | | | | | | | | | |___________________________| | | | | | | | |___________________________________| | | | |___________________________________________|

Each middleware does its job and invokes the next in the sequence and waits for the result. The obtained result can be post-processed before returning to the previous middleware. Any metadata generated at a middleware can be added to the event object so that the same is available for consumption at the middleware and lambda function down the line.

Middleware Code Syntax

The type definition for the middleware is available from the somod package

// serverless/functions/middlewares/myMiddleware.ts import { Middleware } from "somod"; const myMiddleware: Middleware = async (next, event, context) => { // use event.somodMiddlewareContext.set(key, value) to set the metadata // use event.somodMiddlewareContext.get(key) to get the metadata // pre processing const result = await next(); // post processing return result; }; export default myMiddleware;

Middleware Resource Syntax

The middleware is added as a resource of type SOMOD::Serverless::FunctionMiddleware in serverless/template.yaml similar to a lambda function. The middleware resource is not added to the prepared template.yaml, instead its properties are merged into the attached functions.

Resources: MyMiddleware: Type: SOMOD::Serverless::FunctionMiddleware Properties: CodeUri: SOMOD::FunctionMiddleware: name: myMiddleware # refers to serverless/functions/middlewares/myMiddleware.ts allowedTypes: # when provided, this middleware can only be attached to functions of allowed type - functionType1 - functionType2 Environment: # Environment variables are merged to the attached function Variables: MY_ENV1: value1 Layers: # Layers are merged into the attached function - SOMOD::Ref: resource: myLayer

Middleware Attachment Strategies

In the previous sections, we have understood how middlewares work and how to create them. Now let us understand how to attach middleware to a function.

Attach directly during development

Add the resource id of the middleware resource in the middlewares property of the SOMOD::Function keyword in the function resource.

Example:-

Resources: MyFunction1: Type: AWS::Serverless::Function Properties: CodeUri: SOMOD::Function: # ... middlewares: - resource: MyMiddleware1 # attaches MyMiddleware1 in current module to this function - module: AnotherModule # attaches MyMiddleware2 from AnotherModule to this function resource: MyMiddleware2 # ...

Attach by extending the Function resource

Add the resource id of the middleware resource in the middlewares property of the SOMOD::Function keyword in the extended function resource.

Example:-

Resources: MyFunction1: Type: AWS::Serverless::Function SOMOD::Extend: module: OriginalModule resource: OriginalFunction rules: "$.CodeUri['SOMOD::Function'].middlewares": "APPEND" # Append the middlewares when extending Properties: CodeUri: SOMOD::Function: # ... middlewares: - resource: MyMiddleware1 # attaches MyMiddleware1 in current module to OriginalModule.OriginalFunction - module: AnotherModule # attaches MyMiddleware2 from AnotherModule to OriginalModule.OriginalFunction resource: MyMiddleware2 # ...

Attach by using Extension

The above two strategies allow attaching the middleware to selected functions. By using the extension, the middleware can be attached to functions of all/selected types.

// extension.ts export const functionMiddlewares = [ "MyMiddleware1", // MyMiddleware1, MyMiddleware2 are the resource id of the middleware resources in this module "MyMiddleware2" ];

Rules when using the extension

  • Middlewares listed in functionMiddlewares must exist in the serverless/template.yaml of the current module.
  • Middleware resources can be directly declared in the current module or may be extended.
  • During the preparation phase, middlewares from all installed extensions are attached to all available functions.
  • A middleware can restrict the type of function to attach to by using the allowedTypes property.

Passing data between Middlewares

A middleware can pass the data to the next middleware or function in the chain using the somodMiddlewareContext utility in the event object

// event is the parameter to middleware event.somodMiddlewareContext.set("middleware1-data", data); // set function takes 2 arguments // key - string : identifies the data // value - any : any valid javascript object

Middlewares in the chain or the serverless function can retrieve the data from previous middlewares using the same utility

// event is the parameter to middleware/function event.somodMiddlewareContext.get("middleware1-data"); // get function takes 1 argument // key - string : id of the data to retrieve

Now we have fully understood the capabilities of SOMOD to create serverless applications. In the next chapter, let us understand how SOMOD helps to create UI in modules.

Does this page need improvements?
Edit This Page in GitHub
Did this page help you?
Provide feedback in the GitHub Discussion Page
Need More help?

Write an email to opensource@sodaru.com

This documentation is built using
Developed and Maintained By
Sodaru Technologies
https://sodaru.com
© 2023