Project Icon

lambda-api

为 AWS Lambda 设计的轻量级 Serverless API 框架

Lambda API 是专为 AWS Lambda 和 API Gateway 开发的轻量级 Web 框架。它具备强大的路由、中间件和错误处理功能,同时保持零依赖,实现快速加载和高效执行。框架支持多种编程风格,包括异步/await、Promise 和回调。此外,它还提供全面的日志记录和 CORS 支持,适用于各种规模的 Serverless API 开发。

Lambda API

Build Status npm npm Coverage Status

Lightweight web framework for your serverless applications

Lambda API is a lightweight web framework for AWS Lambda using AWS API Gateway Lambda Proxy Integration or ALB Lambda Target Support. This closely mirrors (and is based on) other web frameworks like Express.js and Fastify, but is significantly stripped down to maximize performance with Lambda's stateless, single run executions.

Using AWS SDK v2?

lambda-api@v1 is using AWS SDK v3. If you are using AWS SDK v2, please use lambda-api@v0.12.0.

Simple Example

// Require the framework and instantiate it
const api = require('lambda-api')();

// Define a route
api.get('/status', async (req, res) => {
  return { status: 'ok' };
});

// Declare your Lambda handler
exports.handler = async (event, context) => {
  // Run the request
  return await api.run(event, context);
};

For a full tutorial see How To: Build a Serverless API with Serverless, AWS Lambda and Lambda API.

Why Another Web Framework?

Express.js, Fastify, Koa, Restify, and Hapi are just a few of the many amazing web frameworks out there for Node.js. So why build yet another one when there are so many great options already? One word: DEPENDENCIES.

These other frameworks are extremely powerful, but that benefit comes with the steep price of requiring several additional Node.js modules. Not only is this a bit of a security issue (see Beware of Third-Party Packages in Securing Serverless), but it also adds bloat to your codebase, filling your node_modules directory with a ton of extra files. For serverless applications that need to load quickly, all of these extra dependencies slow down execution and use more memory than necessary. Express.js has 30 dependencies, Fastify has 12, and Hapi has 17! These numbers don't even include their dependencies' dependencies.

Lambda API has ZERO dependencies. None. Zip. Zilch.

Lambda API was written to be extremely lightweight and built specifically for SERVERLESS applications using AWS Lambda and API Gateway. It provides support for API routing, serving up HTML pages, issuing redirects, serving binary files and much more. Worried about observability? Lambda API has a built-in logging engine that can even periodically sample requests for things like tracing and benchmarking. It has a powerful middleware and error handling system, allowing you to implement just about anything you can dream of. Best of all, it was designed to work with Lambda's Proxy Integration, automatically handling all the interaction with API Gateway for you. It parses REQUESTS and formats RESPONSES, allowing you to focus on your application's core functionality, instead of fiddling with inputs and outputs.

Single Purpose Functions

You may have heard that a serverless "best practice" is to keep your functions small and limit them to a single purpose. I generally agree since building monolith applications is not what serverless was designed for. However, what exactly is a "single purpose" when it comes to building serverless APIs and web services? Should we create a separate function for our "create user" POST endpoint and then another one for our "update user" PUT endpoint? Should we create yet another function for our "delete user" DELETE endpoint? You certainly could, but that seems like a lot of repeated boilerplate code. On the other hand, you could create just one function that handled all your user management features. It may even make sense (in certain circumstances) to create one big serverless function handling several related components that can share your VPC database connections.

Whatever you decide is best for your use case, Lambda API is there to support you. Whether your function has over a hundred routes, or just one, Lambda API's small size and lightning fast load time has virtually no impact on your function's performance. You can even define global wildcard routes that will process any incoming request, allowing you to use API Gateway or ALB to determine the routing. Yet despite its small footprint, it gives you the power of a full-featured web framework.

Table of Contents

Installation

npm i lambda-api --save

Requirements

Configuration

Require the lambda-api module into your Lambda handler script and instantiate it. You can initialize the API with the following options:

PropertyTypeDescription
baseStringBase path for all routes, e.g. base: 'v1' would prefix all routes with /v1
callbackNameStringOverride the default callback query parameter name for JSONP calls
loggerboolean or objectEnables default logging or allows for configuration through a Logging Configuration object.
mimeTypesObjectName/value pairs of additional MIME types to be supported by the type(). The key should be the file extension (without the .) and the value should be the expected MIME type, e.g. application/json
serializerFunctionOptional object serializer function. This function receives the body of a response and must return a string. Defaults to JSON.stringify
versionStringVersion number accessible via the REQUEST object
errorHeaderWhitelistArrayArray of headers to maintain on errors
s3ConfigObjectOptional object to provide as config to S3 sdk. S3ClientConfig
// Require the framework and instantiate it with optional version and base parameters
const api = require('lambda-api')({ version: 'v1.0', base: 'v1' });

Recent Updates

For detailed release notes see Releases.

v0.11: API Gateway v2 payload support and automatic compression

Lambda API now supports API Gateway v2 payloads for use with HTTP APIs. The library automatically detects the payload, so no extra configuration is needed. Automatic compression has also been added and supports Brotli, Gzip and Deflate.

v0.10: ALB support, method-based middleware, and multi-value headers and query string parameters

Lambda API now allows you to seamlessly switch between API Gateway and Application Load Balancers. New execution stacks enables method-based middleware and more wildcard functionality. Plus full support for multi-value headers and query string parameters.

Routes and HTTP Methods

Routes are defined by using convenience methods or the METHOD method. There are currently eight convenience route methods: get(), post(), put(), patch(), delete(), head(), options() and any(). Convenience route methods require an optional route and one or more handler functions. A route is simply a path such as /users. If a route is not provided, then it will default to /* and will execute on every path. Handler functions accept a REQUEST, RESPONSE, and optional next() argument. These arguments can be named whatever you like, but convention dictates req, res, and next.

Multiple handler functions can be assigned to a path, which can be used to execute middleware for specific paths and methods. For more information, see Middleware and Execution Stacks.

Examples using convenience route methods:

api.get('/users', (req,res) => {
  // do something
})

api.post('/users', (req,res) => {
  // do something
})

api.delete('/users', (req,res) => {
  // do something
})

api.get('/users',
  (req,res,next) => {
    // do some middleware
    next() // continue execution
  }),
  (req,res) => {
    // do something
  }
)

api.post((req,res) => {
  // do something for ALL post requests
})

Additional methods are support by calling METHOD. Arguments must include an HTTP method (or array of methods), an optional route, and one or more handler functions. Like the convenience methods above, handler functions accept a REQUEST, RESPONSE, and optional next argument.

api.METHOD('trace','/users', (req,res) => {
  // do something on TRACE
})

api.METHOD(['post','put'],'/users', (req,res) => {
  // do something on POST -or- PUT
})

api.METHOD('get','/users',
  (req,res,next) => {
    // do some middleware
    next() // continue execution
  }),
  (req,res) => {
  // do something
  }
)

All GET methods have a HEAD alias that executes the GET request but returns a blank body. GET requests should be idempotent with no side effects. The head() convenience method can be used to set specific paths for HEAD requests or to override default GET aliasing.

Routes that use the any() method or pass ANY to api.METHOD will respond to all HTTP methods. Routes that specify a specific method (such as GET or POST), will override the route for that method. For example:

api.any('/users', (req, res) => {
  res.send('any');
});
api.get('/users', (req, res) => {
  res.send('get');
});

A POST to /users will return "any", but a GET request would return "get". Please note that routes defined with an ANY method will override default HEAD aliasing for GET routes.

Returning Responses

Lambda API supports both callback-style and async-await for returning responses to users. The RESPONSE object has several callbacks that will trigger a response (send(), json(), html(), etc.) You can use any of these callbacks from within route functions and middleware to send the response:

api.get('/users', (req, res) => {
  res.send({ foo: 'bar' });
});

You can also return data from route functions and middleware. The contents will be sent as the body:

api.get('/users', (req, res) => {
  return { foo: 'bar' };
});

Async/Await

If you prefer to use async/await, you can easily apply this to your route functions.

Using return:

api.get('/users', async (req, res) => {
  let users = await getUsers();
  return users;
});

Or using callbacks:

api.get('/users', async (req, res) => {
  let users = await getUsers();
  res.send(users);
});

Promises

If you like promises, you can either use a callback like res.send() at the end of your promise chain, or you can simply return the resolved promise:

api.get('/users', (req, res) => {
  getUsers().then((users) => {
    res.send(users);
  });
});

OR

api.get('/users', (req, res) => {
  return getUsers().then((users) => {
    return users;
  });
});

IMPORTANT: You must either use a callback like res.send() OR return a value. Otherwise the execution will hang and no data will be sent to the user. Also, be sure not to return undefined, otherwise it will assume no response.

A Note About Flow Control

While callbacks like res.send() and res.error() will trigger a response, they will not necessarily terminate execution of the current route function. Take a look at the following example:

api.get('/users', (req, res) => {
  if (req.headers.test === 'test') {
    res.error('Throw an error');
  }

  return { foo: 'bar' };
});

The example above would not have the intended result of displaying an error. res.error() would signal Lambda API to execute the error handling, but the function would continue to run. This would cause the function to return a response that would override the intended error. In this situation, you could either wrap the return in an else clause, or a cleaner approach would be to return the call to the error() method, like so:

api.get('/users', (req, res) => {
  if (req.headers.test
项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

白日梦AI

白日梦AI提供专注于AI视频生成的多样化功能,包括文生视频、动态画面和形象生成等,帮助用户快速上手,创造专业级内容。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

讯飞绘镜

讯飞绘镜是一个支持从创意到完整视频创作的智能平台,用户可以快速生成视频素材并创作独特的音乐视频和故事。平台提供多样化的主题和精选作品,帮助用户探索创意灵感。

Project Cover

讯飞文书

讯飞文书依托讯飞星火大模型,为文书写作者提供从素材筹备到稿件撰写及审稿的全程支持。通过录音智记和以稿写稿等功能,满足事务性工作的高频需求,帮助撰稿人节省精力,提高效率,优化工作与生活。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号