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.
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.
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;
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
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.
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 # ...
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 # ...
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" ];
serverless/template.yaml
of the current module.allowedTypes
property.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.
Write an email to opensource@sodaru.com