Security News
Input Validation Vulnerabilities Dominate MITRE's 2024 CWE Top 25 List
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
@h4ad/serverless-adapter
Advanced tools
This library enables you to utilize any Cloud or Event Source to respond to web and API requests using your existing Node.js application framework.
Install | Usage | Support | Examples | Architecture | Credits
Run REST APIs and other web applications using your existing Node.js application framework (Express, Koa, Hapi and Fastify), on top of AWS Lambda, Huawei and many other clouds.
This library was a refactored version of @vendia/serverless-express, I created a new way to interact and extend event sources by creating contracts to abstract the integrations between each library layer.
Why you would use this libray instead of @vendia/serverless-express?
addAdapter
method when building your handler.Using NPM:
npm install --save @h4ad/serverless-adapter
Using Yarn:
yarn add @h4ad/serverless-adapter
You can quickly use this library as follows:
import { ServerlessAdapter } from '@h4ad/serverless-adapter';
import { ApiGatewayV2Adapter, AlbAdapter, SQSAdapter, SNSAdapter } from '@h4ad/serverless-adapter/lib/adapters/aws';
import { ExpressFramework } from '@h4ad/serverless-adapter/lib/frameworks/express';
import { DefaultHandler } from '@h4ad/serverless-adapter/lib/handlers/default';
import { PromiseResolver } from '@h4ad/serverless-adapter/lib/resolvers/promise';
import app from './app';
// if you create your app asynchronously
// check the docs about the LazyFramework.
// ServerlessAdapter.new(null)
// .setFramework(new LazyFramework(new ExpressFramework(), async () => createAsyncApp()))
export const handler = ServerlessAdapter.new(app)
.setFramework(new ExpressFramework())
.setHandler(new DefaultHandler())
.setResolver(new PromiseResolver())
.addAdapter(new AlbAdapter())
.addAdapter(new SQSAdapter())
.addAdapter(new SNSAdapter())
.build();
Too fast? Ok, I can explain.
First, you need to create an instance of the builder with ServerlessAdapter.new(app)
. The variable app
is the
instance of your framework (Express, Fastify, Koa, etc).
So you need to specify for this library which framework
you will use to handle the request
with setFramework
, you
can only use one. If you use express in our backend, use ExpressFramework
, see more in support.
Then you specify which handler
you will use to interact with the serverless cloud with setHandler
, currently we only
have one, the DefaultHandler. In the next releases, maybe we will add support
for Azure, Huawei and others, for now, you can use this default.
Then you specify with setResolver
which resolver
you will use to wait for the library to forward the request to
your framework
, and then get the response
back to your cloud. I recommend you
use PromiseResolver, it's the most cloud-agnostic resolver
.
By now, you've already added the basic abstractions of this library, now, you can add the adapters
that will add
support for receiving and processing different sources of addAdapter
events. In the example I
added AlbAdapter, SQSAdapter
and SNSAdapter. With these adapters you can connect your lambda to three different
event sources and you can add more if you wish.
Finally, we call build
which will assemble your handler that you can expose directly to your cloud.
Final thoughts:
framework
only once.handler
only once.resolver
only once.adapters
as you like, use and extend as you wish.We are in beta, so some adapters may not work as expected, feel free to create an issue or provide feedback on current behavior.
By design we have these contracts that define the layers of the library: Frameworks, Adapters, Resolvers and Handlers.
If you don't know what each thing means, see Architecture.
Currently, we support these frameworks:
We support these event sources:
We support these resolvers:
We support these handlers:
In Huawei, we added support to FunctionGraphV2 with Http Function and Event Function.
The difference between Http Function and Event Function is that in Http Function you must expose port 8000 and Huawei will proxy Api Gateway requests to your application. So, on implementation, this library will create an http server to listen on port 8000 and forward the request to your framework.
In Event Function, you will receive the event from event source in the same way you receive in AWS, an object with some structure, you can see the supported event sources here.
To integrate your app with Huawei FunctionGrapth with the Http Function type, you must do the following:
import { ServerlessAdapter } from '@h4ad/serverless-adapter';
import { ExpressFramework } from '@h4ad/serverless-adapter/lib/frameworks/express';
import { HttpHuaweiHandler } from '@h4ad/serverless-adapter/lib/handlers/huawei';
import { DummyResolver } from '@h4ad/serverless-adapter/lib/resolvers/dummy';
import { DummyAdapter } from '@h4ad/serverless-adapter/lib/adapters/dummy';
import app from './app';
// instead exposing handler, you have the dispose function
// this dispose function is never called
// but you can to close the http server created with him
const dispose = ServerlessAdapter.new(app)
.setHandler(new HttpHuaweiHandler())
.setFramework(new ExpressFramework())
// dummy resolver and adapter is used because
// they are necessary in the core of the library to build
// but is optional to make huawei http function works.
.setResolver(new DummyResolver())
.addAdapter(new DummyAdapter())
.build();
You don't need to expose a variable called
handler
when you choose Http Function, you just need to call build to the library create a http server.
By the way of Huawei architecture in Http Function, they have no use for Resolvers and Adapters, so you need to use the dummy versions because the library requires it.
You need to configure a file called bootstrap
in the root of folder that you upload to Huawei, is like the file Procfile
but for Huawei.
In my setup, I configure like:
node /opt/function/code/index.js
The path /opt/function/code
is where your code is uploaded when you deploy something and index.js
is the file that contains the ServerlessAdapter
.
In the end, the structure of the zip file you upload looks like this:
bootstrap
index.js
With Http Function you need to use HttpHuaweiHandler, but with Event Function you should use DefaultHandler.
So, to add support to Api Gateway you do the following:
import { ServerlessAdapter } from '@h4ad/serverless-adapter';
import { HuaweiApiGatewayAdapter } from '@h4ad/serverless-adapter/lib/adapters/huawei';
import { ExpressFramework } from '@h4ad/serverless-adapter/lib/frameworks/express';
import { DefaultHandler } from '@h4ad/serverless-adapter/lib/handlers/default';
import { CallbackResolver } from '@h4ad/serverless-adapter/lib/resolvers/callback';
import app from './app';
export const handler = ServerlessAdapter.new(app)
.setFramework(new ExpressFramework())
.setHandler(new DefaultHandler())
.setResolver(new CallbackResolver())
.addAdapter(new HuaweiApiGatewayAdapter())
.build();
You must use the callback resolver because I couldn't get it to work with the PromiseResolver. Maybe it's a bug in the library or something specific in Huawei, if you have a tip please create an issue.
You can see some examples of how to use this library here.
The main purpose of this library is to allow the developer to add support for any cloud and as many event sources as he wants, without having to create an issue to request the feature or copy the library code because the library doesn't expose good APIs for you to extend its functionality
So I refactored @vendia/serverless-express with 4 layers of abstraction: Framework, Handler, Resolver and Adapter.
The FrameworkContract is responsible for forwarding to IncomingMessage and ServerResponse for your application instance. With this abstraction you can implement any framework you want, they just need to accept both parameters and call end in ServerResponse, so the library knows when to continue and return the response.
The HandlerContract is responsible to get the input from the serverless and then manage to call each layer of abstraction to return a response. With this abstraction, you can implement different ways to receive input from your serverless environment. They usually have the same structure, but if you need to deal with a very different cloud, you can use this abstraction to add support for that cloud.
Handler is a good choice for implementing (
monsters) ways to receive input. For example, we can create an http server as its handler to test our serverless code without having to launch the framework. Because? I don't know, but you can.
The ResolverContract is responsible for waiting for the framework to handle the
request and then returning the response to the cloud. Using AWS for example, you have three ways to wait for the
response: returning a promise, calling the callback, and using in-context methods, each option has its own benefits,
but generally the promise option will be the better because any good cloud provider will support promises.
Finally, the masterpiece of this library, the AdapterContract is responsible for handling the received event, transforming the request in a way that your application can understand and then transforming the response in a way your cloud can understand.
Well, with these four contracts, you'll be able to add support to any cloud that exists (no more excuses not to use cloud X with NodeJS).
The real reason I created this library was because I wanted to add API Gateway and SQS support at the same time to save some money. But, @vendia/serverless-express was not supported, so I created a PR, but until I finished this library, that PR was never accepted.
So I build my own library based on that library with better APIs so I never have to wait for the maintainer to accept my PR just to extend the library's functionality :)
Honestly, I just refactored all the code that the @vendia team and many other contributors wrote, thanks so much to them for existing and giving us a brilliant library that is the core of my current company.
FAQs
Run REST APIs and other web applications using your existing Node.js application framework (NestJS, Express, Koa, Hapi, Fastify and many others), on top of AWS, Azure, Digital Ocean and many other clouds.
The npm package @h4ad/serverless-adapter receives a total of 1,603 weekly downloads. As such, @h4ad/serverless-adapter popularity was classified as popular.
We found that @h4ad/serverless-adapter demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.
Research
Security News
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.