@3fv/serverless-offline 中文文档教程

发布于 4年前 浏览 50 项目主页 更新于 3年前

Serverless Offline

注意 只有在 PR 1130 在基础 repo 中获得批准 之后才会发布

这个 Serverless 插件模拟 AWS λ和本地计算机上的 API 网关 以加快您的开发周期。 为此,它会启动一个 HTTP 服务器,像 APIG 一样处理请求的生命周期并调用您的处理程序。

特点:

  • Node.js, Python, Rubyλ runtimes.
  • Velocity templates support.
  • Lazy loading of your handler files.
  • And more: integrations, authorizers, proxies, timeouts, responseParameters, HTTPS, CORS, etc…

这个插件是由它的用户更新的,我只是做维护并确保 PR 与社区相关。 换句话说,如果您发现错误或想要新功能,请成为< href="https://github.com/dherault/serverless-offline/graphs/contributors">贡献者:v:! 请参阅贡献部分

Documentation

Installation

首先,将 Serverless Offline 添加到您的项目中:

npm install serverless-offline --save-dev

然后在项目的 serverless.yml 文件中的插件部分添加以下条目:<代码>无服务器离线。 如果没有插件部分,您需要将其添加到文件中。

请注意,serverless-offline 的“插件”部分必须位于 serverless.yml 的根级别。

它应该如下所示:

plugins:
  - serverless-offline

您可以通过运行 serverless 命令检查是否已成功安装插件line:

serverless --verbose

控制台应该显示 Offline 作为您的 Serverless 项目中现在可用的插件之一。

Usage and command line options

在您的项目根目录中运行:

serverless offlinesls offline

列出插件运行的所有选项:

sls offline --help

所有 CLI 选项都是可选

--apiKey                    Defines the API key value to be used for endpoints marked as private Defaults to a random hash.
--corsAllowHeaders          Used as default Access-Control-Allow-Headers header value for responses. Delimit multiple values with commas. Default: 'accept,content-type,x-api-key'
--corsAllowOrigin           Used as default Access-Control-Allow-Origin header value for responses. Delimit multiple values with commas. Default: '*'
--corsDisallowCredentials   When provided, the default Access-Control-Allow-Credentials header value will be passed as 'false'. Default: true
--corsExposedHeaders        Used as additional Access-Control-Exposed-Headers header value for responses. Delimit multiple values with commas. Default: 'WWW-Authenticate,Server-Authorization'
--disableCookieValidation   Used to disable cookie-validation on hapi.js-server
--enforceSecureCookies      Enforce secure cookies
--hideStackTraces           Hide the stack trace on lambda failure. Default: false
--host                  -o  Host name to listen on. Default: localhost
--httpPort                  Http port to listen on. Default: 3000
--httpsProtocol         -H  To enable HTTPS, specify directory (relative to your cwd, typically your project dir) for both cert.pem and key.pem files
--ignoreJWTSignature        When using HttpApi with a JWT authorizer, don't check the signature of the JWT token. This should only be used for local development.
--lambdaPort                Lambda http port to listen on. Default: 3002
--noPrependStageInUrl       Don't prepend http routes with the stage.
--noAuth                    Turns off all authorizers
--noTimeout             -t  Disables the timeout feature.
--prefix                -p  Adds a prefix to every path, to send your requests to http://localhost:3000/[prefix]/[your_path] instead. Default: ''
--printOutput               Turns on logging of your lambda outputs in the terminal.
--resourceRoutes            Turns on loading of your HTTP proxy settings from serverless.yml
--useChildProcesses         Run handlers in a child process
--useWorkerThreads          Uses worker threads for handlers. Requires node.js v11.7.0 or higher
--websocketPort             WebSocket port to listen on. Default: 3001
--webSocketHardTimeout      Set WebSocket hard timeout in seconds to reproduce AWS limits (https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html#apigateway-execution-service-websocket-limits-table). Default: 7200 (2 hours)
--webSocketIdleTimeout      Set WebSocket idle timeout in seconds to reproduce AWS limits (https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html#apigateway-execution-service-websocket-limits-table). Default: 600 (10 minutes)
--useDocker                 Run handlers in a docker container.
--layersDir                 The directory layers should be stored in. Default: ${codeDir}/.serverless-offline/layers'
--dockerReadOnly            Marks if the docker code layer should be read only. Default: true
--allowCache                Allows the code of lambda functions to cache if supported.
--overrideLayersDir         Forces docker to use a mapped host directory instead of downloading layers, incredibly useful for debugging
--overrideCodeDir           Forces docker to use a mapped host directory instead of package artifact of named handler, incredibly useful for debugging

的:任何 CLI 选项都可以添加到您的 serverless.yml。 例如:

custom:
  serverless-offline:
    httpsProtocol: "dev-certs"
    httpPort: 4000
    stageVariables:
      foo: "bar"

通过命令行传递的选项会覆盖 YAML 选项。

默认情况下,您可以将请求发送到 http://localhost:3000/。 请注意:

  • You'll need to restart the plugin if you modify your serverless.yml or any of the default velocity template files.
  • When no Content-Type header is set on a request, API Gateway defaults to application/json, and so does the plugin. But if you send an application/x-www-form-urlencoded or a multipart/form-data body with an application/json (or no) Content-Type, API Gateway won't parse your data (you'll get the ugly raw as input), whereas the plugin will answer 400 (malformed JSON). Please consider explicitly setting your requests' Content-Type and using separate templates.

Usage with invoke

要使用 Lambda.invoke,您需要将 lambda 端点设置为无服务器离线端点:

const { Lambda } = require('aws-sdk')

const lambda = new Lambda({
  apiVersion: '2015-03-31',
  // endpoint needs to be set only if it deviates from the default, e.g. in a dev environment
  // process.env.SOME_VARIABLE could be set in e.g. serverless.yml for provider.environment or function.environment
  endpoint: process.env.SOME_VARIABLE
    ? 'http://localhost:3002'
    : 'https://lambda.us-east-1.amazonaws.com',
})

然后可以在处理程序中调用所有 lambda,

exports.handler = async function() {
  const params = {
    // FunctionName is composed of: service name - stage - function name, e.g.
    FunctionName: 'myServiceName-dev-invokedHandler',
    InvocationType: 'RequestResponse',
    Payload: JSON.stringify({ data: 'foo' }),
  }

  const response = await lambda.invoke(params).promise()
}

您也可以使用 aws cli 调用指定 --endpoint-url

aws lambda invoke /dev/null \
  --endpoint-url http://localhost:3002 \
  --function-name myServiceName-dev-invokedHandler

可用函数名称列表及其对应的 serverless.yml 函数键 在服务器启动后列出。 如果您使用自定义命名,这很重要 serverless-offline 函数的方案将使用您的自定义名称。 左侧是 serverless.yml 中的函数键 (下例中的invokedHandler)右边是函数名 用于外部调用函数如aws-sdkmyServiceName-dev-invokedHandler 在下面的示例中):

serverless offline
...
offline: Starting Offline: local/us-east-1.
offline: Offline [http for lambda] listening on http://localhost:3002
offline: Function names exposed for local invocation by aws-sdk:
           * invokedHandler: myServiceName-dev-invokedHandler

列出为目标公开的可用手动调用路径 通过 aws-sdkaws-cli,使用 SLS_DEBUG=*serverless offline。 调用服务器启动后,将显示完整的端点列表:

SLS_DEBUG=* serverless offline
...
offline: Starting Offline: local/us-east-1.
...
offline: Offline [http for lambda] listening on http://localhost:3002
offline: Function names exposed for local invocation by aws-sdk:
           * invokedHandler: myServiceName-dev-invokedHandler
[offline] Lambda Invocation Routes (for AWS SDK or AWS CLI):
           * POST http://localhost:3002/2015-03-31/functions/myServiceName-dev-invokedHandler/invocations
[offline] Lambda Async Invocation Routes (for AWS SDK or AWS CLI):
           * POST http://localhost:3002/2014-11-13/functions/myServiceName-dev-invokedHandler/invoke-async/

您可以使用 REST 客户端手动定位这些端点以调试您的 lambda 如果你愿意的话。 如果您是 通过 aws-sdk 调用它。

The process.env.IS_OFFLINE variable

将在您的处理程序中为 "true" 并彻底检查插件。

Docker and Layers

要使用无服务器离线层,您需要将 useDocker 选项设置为 true。 这可以通过使用 --useDocker 命令,或者像这样在您的 serverless.yml 中:

custom:
  serverless-offline:
    useDocker: true

这将允许 docker 容器查找有关层的任何信息,下载并使用它们。 为此,您必须使用:

  • AWS as a provider, it won't work with other provider types.
  • Layers that are compatible with your runtime.
  • ARNs for layers. Local layers aren't supported as yet.
  • A local AWS account set-up that can query and download layers.

如果您为 AWS 角色使用最低权限主体,则此策略应该可以帮助您:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "lambda:GetLayerVersion",
            "Resource": "arn:aws:lambda:*:*:layer:*:*"
        }
    ]
}

一旦您运行启动 Docker 容器的函数,它将遍历所有层对于该功能,请按顺序将它们下载到您的层文件夹,并保存层的哈希值,以便将来可以重复使用。 如果它们在未来发生变化,您只需要重新下载您的图层。 如果您希望重新下载图层,只需删除图层文件夹即可。

然后您应该能够像往常一样调用函数,并且它们是针对您的 docker 容器中的层执行的。

Additional Options

有 2 个附加选项可用于 Docker 和 Layer 使用。

  • layersDir
  • dockerReadOnly

layersDir

默认情况下,图层是按项目下载的,但是,如果您想跨项目共享它们,可以将它们下载到一个公共位置。 例如,layersDir: /tmp/layers 将允许它们在项目之间共享。 确保在使用此设置时,您正在写入层的目录可以由 docker 共享。

dockerReadOnly

对于某些编程语言和框架,希望能够写入文件系统以用于使用本地 SQLite 数据库进行测试或其他仅用于测试的修改。 为此,您可以设置 dockerReadOnly: false,这将允许修改本地文件系统。 这并没有严格模仿 AWS Lambda,因为 Lambda 有一个只读文件系统,所以这应该作为最后的手段使用。

Token authorizers

无服务器文档 您可以使用 API 密钥作为简单的身份验证方法。

Serverless-offline 将模拟 APIG 的行为并创建一个打印在屏幕上的随机令牌。 使用此令牌,您可以访问将 x-api-key: generatedToken 添加到请求标头的私有方法。 所有 api 密钥将共享相同的令牌。 要指定自定义令牌,请使用 --apiKey cli 选项。

Custom authorizers

仅支持自定义授权方。 自定义授权程序在执行 Lambda 函数之前执行并返回错误或策略文档。

向自定义授权方传递一个 event 对象,如下所示:

{
  "type": "TOKEN",
  "authorizationToken": "<Incoming bearer token>",
  "methodArn": "arn:aws:execute-api:<Region id>:<Account id>:<API id>/<Stage>/<Method>/<Resource path>"
}

methodArn 不包括帐户 ID 或 API ID。

该插件仅支持从标头中检索令牌。 您可以按如下方式配置标头:

"authorizer": {
  "type": "TOKEN",
  "identitySource": "method.request.header.Authorization", // or method.request.header.SomeOtherHeader
  "authorizerResultTtlInSeconds": "0"
}

Remote authorizers

您可以通过在运行 sls offline start 之前设置环境变量 AUTHORIZER 来模拟来自远程授权者的响应

示例:

Unix:export AUTHORIZER='{"principalId": "123"}'

Windows:SET AUTHORIZER='{"principalId": "123"}'

JWT authorizers

对于 HTTP API,JWT 授权方 serverless.yml 中定义的可用于验证令牌和令牌中的范围。 然而此时, JWT 的签名未通过定义的发行者进行验证。 由于这是一个安全风险,此功能是 仅通过 --ignoreJWTSignature 标志启用。 确保只为本地开发工作设置此标志。

Custom headers

您可以在请求中使用一些自定义标头来更好地控制 requestContext 对象。

HeaderEvent key
cognito-identity-idevent.requestContext.identity.cognitoIdentityId
cognito-authentication-providerevent.requestContext.identity.cognitoAuthenticationProvider

通过这样做,您现在可以使用自定义标头更改这些值。 这可以帮助您更轻松地进行身份验证或从 cognitoAuthenticationProvider 值中检索 userId。

Environment variables

您可以使用环境变量在事件上下文中自定义身份参数。

Environment VariableEvent key
SLSCOGNITOIDENTITYPOOLIDevent.requestContext.identity.cognitoIdentityPoolId
SLSACCOUNTIDevent.requestContext.identity.accountId
SLSCOGNITOIDENTITY_IDevent.requestContext.identity.cognitoIdentityId
SLS_CALLERevent.requestContext.identity.caller
SLSAPIKEYevent.requestContext.identity.apiKey
SLSCOGNITOAUTHENTICATION_TYPEevent.requestContext.identity.cognitoAuthenticationType
SLSCOGNITOAUTHENTICATION_PROVIDERevent.requestContext.identity.cognitoAuthenticationProvider

您可以使用 serverless-dotenv-plugin.env 文件加载环境变量.

AWS API Gateway Features

Velocity Templates

无服务器文档 ~ AWS doc

您可以提供响应和请求模板对于每个功能。 这是可选的。 为此,您必须将特定于函数的模板文件放置在与函数文件相同的目录中,并将 .req.vm 扩展名添加到模板文件名中。 例如, 如果您的函数在代码文件中:helloworld.js, 您的响应模板应在文件中:helloworld.res.vm,您的请求模板应在文件 helloworld.req.vm 中。

CORS

Serverless doc

如果端点配置将 CORS 设置为 true,插件将使用关联路由的 CLI CORS 选项。 否则,不会添加任何 CORS 标头。

Catch-all Path Variables

AWS doc

这样设置贪心路径/store/{proxy+} 将拦截对 /store/list-products/store/add-product 等的请求...

ANY method

AWS 文档

开箱即用。

Lambda and Lambda Proxy Integrations

无服务器文档 ~ AWS 文档

开箱即用。 请参阅 manual_test 目录中的示例。

HTTP Proxy

无服务器文档 ~ AWS 文档 - AWS::ApiGateway::Method ~ AWS 文档 - AWS::ApiGateway::Resource

示例启用代理:

custom:
  serverless-offline:
    resourceRoutes: true

    YourCloudFormationMethodId:
      Type: AWS::ApiGateway::Method
      Properties:
        ......
        Integration:
          Type: HTTP_PROXY
          Uri: 'https://s3-${self:custom.region}.amazonaws.com/${self:custom.yourBucketName}/{proxy}'
          ......
custom:
  serverless-offline:
    resourceRoutes:
      YourCloudFormationMethodId:
        Uri: 'http://localhost:3001/assets/{proxy}'

Response parameters

AWS 文档

您可以使用 ResponseParameters 设置响应的标头。

可能无法正常工作。 请公关。 (难度:很难?)

示例响应速度模板:

"responseParameters": {
  "method.response.header.X-Powered-By": "Serverless", // a string
  "method.response.header.Warning": "integration.response.body", // the whole response
  "method.response.header.Location": "integration.response.body.some.key" // a pseudo JSON-path
},

WebSocket

为了将消息发送回客户端的用法:

POST http://localhost:3001/@connections/{connectionId}

或者,

const apiGatewayManagementApi = new AWS.ApiGatewayManagementApi({
  apiVersion: '2018-11-29',
  endpoint: 'http://localhost:3001',
});

apiGatewayManagementApi.postToConnection({
  ConnectionId: ...,
  Data: ...,
});

在 lambda 处理函数中接收到事件

支持 websocketsApiRouteSelectionExpression 的基本形式:< code>$request.body.xyz,默认值为$request.body.action

当前不支持授权者和 wss://。

Usage with Webpack

使用 serverless-webpack 来编译和捆绑你的 ES-next 代码

Velocity nuances

考虑这个用于 POST 端点的 requestTemplate:

"application/json": {
  "payload": "$input.json('$')",
  "id_json": "$input.json('$.id')",
  "id_path": "$input.path('$').id"
}

现在让我们做带有此正文的请求:{ "id": 1 }

AWS 这样解析事件:

{
  "payload": {
    "id": 1
  },
  "id_json": 1,
  "id_path": "1" // Notice the string
}

而离线解析:

{
  "payload": {
    "id": 1
  },
  "id_json": 1,
  "id_path": 1 // Notice the number
}

使用 $input.path 后访问属性将返回一个AWS 上的字符串(期望像 "1""true" 这样的字符串)但不在 Offline 上(1true >). 您可能会发现其他差异。

Debug process

Serverless 离线插件会响应整体的框架设置,并在调试模式下向控制台输出额外的信息。 为此,您必须设置 SLS_DEBUG 环境变量。 您可以在命令行中运行以下命令以切换到调试模式执行。

Unix:export SLS_DEBUG=*

Windows:SET SLS_DEBUG=*

如果您已经安装了 node-inspector 模块和 chrome 浏览器,您的项目也可以进行交互式调试。 然后,您可以在项目的根目录中运行以下命令行。

初始安装: npm install -g node-inspector

对于每次调试运行: node-debug sls offline

系统会以等待状态启动。 这样也会自动启动chrome浏览器,等待你设置断点进行检查。 根据需要设置断点,然后单击播放按钮继续调试。

根据断点,您可能需要在单独的浏览器窗口中调用函数的 URL 路径,以便运行无服务器函数并使其可用于调试。

Resource permissions and AWS profile

Lambda 函数在执行期间承担 IAM 角色:框架创建此角色并设置 serverless.ymliamRoleStatements 部分中提供的所有权限。

但是,无服务器离线使用您的本地 AWS 配置文件凭据来运行 lambda 函数,这可能会导致一组不同的权限。 默认情况下,aws-sdk 会为您在配置文件中指定的默认 AWS 配置文件加载凭证。

您可以直接在代码中或通过设置适当的环境变量来更改此配置文件。 在将 serverless 离线调用到不同的配置文件之前设置 AWS_PROFILE 环境变量将有效地更改凭据,例如

AWS_PROFILE=; serverless offline

Scoped execution

下游插件可能会绑定到 before:offline:start:end 挂钩以在服务器关闭时释放资源。

Simulation quality

此插件出于许多实际目的模拟 API 网关,足以用于开发 - 但不是完美的模拟器。 具体来说,Lambda 当前在 Node.js v10.x 和 v12.x 上运行 (AWS Docs),而 Offline 在您自己的运行时上运行,其中没有强制执行内存限制。

Usage with serverless-dynamodb-local and serverless-webpack plugin

运行 serverless offline start。 与 serverless offline 相比,start 命令将触发一个 init 和一个 end 生命周期钩子,这是需要的serverless-offline 和 serverless-dynamodb-local 关闭资源。

将插件添加到您的 serverless.yml 文件:

plugins:
  - serverless-webpack
  - serverless-dynamodb-local
  - serverless-offline # serverless-offline needs to be last in the list

Credits and inspiration

这个插件最初是 Nopik无服务器服务

License

麻省理工学院

Contributing

是的,谢谢! 这个插件是社区驱动的,它的大部分功能来自不同的作者。 请更新文档和测试并将您的名字添加到 package.json 文件中。 我们尽量遵循 Airbnb 的 JavaScript 风格指南

Contributors

dnalborczykdheraultcomputerpuncleonardoalifracodaniel-cottone
dnalborczykdheraultcomputerpuncleonardoalifracodaniel-cottone
mikestaubBilal-Sdl748frsechetzoellner
mikestaubBilal-Sdl748frsechetzoellner
johncmckimThisIsNoZakudarthtrevinomiltadorgertjvr
johncmckimThisIsNoZakudarthtrevinomiltadorgertjvr
juanjoDiazperkyguyjack-seekhueniverserobbtraister
juanjoDiazperkyguyjack-seekhueniverserobbtraister
dortega3000ansraliantjoubertredratandreipopoviciAndorbal
dortega3000ansraliantjoubertredratandreipopoviciAndorbal
AyushG3112franciscocpgkajwiklundondrowansulaysumaria
AyushG3112franciscocpgkajwiklundondrowansulaysumaria
jormaecheaawwong1c24wvmadmanencounter
jormaecheaawwong1c24wvmadmanencounter
Bob-Thomasnjriordanbebbitrevor-leachemmoistner
Bob-Thomasnjriordanbebbitrevor-leachemmoistner
OrKoNadieuadieuapalumboanishknycameroncooper
OrKoNadieuadieuapalumboanishknycameroncooper
cmuto09dschepDimaDK24dwbellistoneabadjiev
cmuto09dschepDimaDK24dwbellistoneabadjiev
Arkfillegarunskijames-relyeajoewestcottLoganArnett
Arkfillegarunskijames-relyeajoewestcottLoganArnett
ablythemarccampbellpurefanmzmiric5paulhbarker
ablythemarccampbellpurefanmzmiric5paulhbarker
pmuenspierreisramonEmiliorschickselcukcihan
pmuenspierreisramonEmiliorschickselcukcihan
patrickheeneyrma4okclschneidjcrabhatadam-nielsen
patrickheeneyrma4okclschneidjcrabhatadam-nielsen
adamelliottsweetingagaineralebianco-doxeekoterpillartriptec
adamelliottsweetingagaineralebianco-doxeekoterpillartriptec
constbcspotcodealiatsisarnasakaila
constbcspotcodealiatsisarnasakaila
ac360austin-paynebencoolingBorjaMacedoBrandonE
ac360austin-paynebencoolingBorjaMacedoBrandonE
guerrerocarloschrismcleodchristophgysinClement134rlgod
guerrerocarloschrismcleodchristophgysinClement134rlgod
dbunkerdobrynindomaslasauskasenolanminibikini
dbunkerdobrynindomaslasauskasenolanminibikini
em0neyerauergbroquesguillaumebalassy
em0neyerauergbroquesguillaumebalassy
idmontiejacintoAriasjgriggjsnajdrhoryd
idmontiejacintoAriasjgriggjsnajdrhoryd
jaydp17jeremygibersonjosephwarrickjlsjonasjoostfarla
jaydp17jeremygibersonjosephwarrickjlsjonasjoostfarla
kenleytomlinlalifraco-devsparkDynamicSTOPmedikooneverendingqs
kenleytomlinlalifraco-devsparkDynamicSTOPmedikooneverendingqs
msjonkerTakenomjmacojongeriusthepont
msjonkerTakenomjmacojongeriusthepont
WooDzuPsychicCatRaph22wwsnogribnoysup
WooDzuPsychicCatRaph22wwsnogribnoysup
starsprungshineli-not-used-anymorestesiestevemaoittus
starsprungshineli-not-used-anymorestesiestevemaoittus
tiagogoncalves89tuanmhGregoirevdagcphostYaroslavApatiev
tiagogoncalves89tuanmhGregoirevdagcphostYaroslavApatiev
zacacollierallenhartwigdemetriusnuneshszelectrikdevelopment
zacacollierallenhartwigdemetriusnuneshszelectrikdevelopment
jgilbert01polaris340kobanyanleruitga-sslivingmine
jgilbert01polaris340kobanyanleruitga-sslivingmine
lteachermartinmicundanori3tsuppasmanikryanzyy
lteachermartinmicundanori3tsuppasmanikryanzyy
m0ppersfootballencartabryanvaz
m0ppersfootballencartabryanvaz

Serverless Offline

NOTE This is only published until the PR 1130 is approved in the base repo

This Serverless plugin emulates AWS λ and API Gateway on your local machine to speed up your development cycles. To do so, it starts an HTTP server that handles the request's lifecycle like APIG does and invokes your handlers.

Features:

  • Node.js, Python, Rubyλ runtimes.
  • Velocity templates support.
  • Lazy loading of your handler files.
  • And more: integrations, authorizers, proxies, timeouts, responseParameters, HTTPS, CORS, etc…

This plugin is updated by its users, I just do maintenance and ensure that PRs are relevant to the community. In other words, if you find a bug or want a new feature, please help us by becoming one of the contributors :v: ! See the contributing section.

Documentation

Installation

First, add Serverless Offline to your project:

npm install serverless-offline --save-dev

Then inside your project's serverless.yml file add following entry to the plugins section: serverless-offline. If there is no plugin section you will need to add it to the file.

Note that the "plugin" section for serverless-offline must be at root level on serverless.yml.

It should look something like this:

plugins:
  - serverless-offline

You can check wether you have successfully installed the plugin by running the serverless command line:

serverless --verbose

the console should display Offline as one of the plugins now available in your Serverless project.

Usage and command line options

In your project root run:

serverless offline or sls offline.

to list all the options for the plugin run:

sls offline --help

All CLI options are optional:

--apiKey                    Defines the API key value to be used for endpoints marked as private Defaults to a random hash.
--corsAllowHeaders          Used as default Access-Control-Allow-Headers header value for responses. Delimit multiple values with commas. Default: 'accept,content-type,x-api-key'
--corsAllowOrigin           Used as default Access-Control-Allow-Origin header value for responses. Delimit multiple values with commas. Default: '*'
--corsDisallowCredentials   When provided, the default Access-Control-Allow-Credentials header value will be passed as 'false'. Default: true
--corsExposedHeaders        Used as additional Access-Control-Exposed-Headers header value for responses. Delimit multiple values with commas. Default: 'WWW-Authenticate,Server-Authorization'
--disableCookieValidation   Used to disable cookie-validation on hapi.js-server
--enforceSecureCookies      Enforce secure cookies
--hideStackTraces           Hide the stack trace on lambda failure. Default: false
--host                  -o  Host name to listen on. Default: localhost
--httpPort                  Http port to listen on. Default: 3000
--httpsProtocol         -H  To enable HTTPS, specify directory (relative to your cwd, typically your project dir) for both cert.pem and key.pem files
--ignoreJWTSignature        When using HttpApi with a JWT authorizer, don't check the signature of the JWT token. This should only be used for local development.
--lambdaPort                Lambda http port to listen on. Default: 3002
--noPrependStageInUrl       Don't prepend http routes with the stage.
--noAuth                    Turns off all authorizers
--noTimeout             -t  Disables the timeout feature.
--prefix                -p  Adds a prefix to every path, to send your requests to http://localhost:3000/[prefix]/[your_path] instead. Default: ''
--printOutput               Turns on logging of your lambda outputs in the terminal.
--resourceRoutes            Turns on loading of your HTTP proxy settings from serverless.yml
--useChildProcesses         Run handlers in a child process
--useWorkerThreads          Uses worker threads for handlers. Requires node.js v11.7.0 or higher
--websocketPort             WebSocket port to listen on. Default: 3001
--webSocketHardTimeout      Set WebSocket hard timeout in seconds to reproduce AWS limits (https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html#apigateway-execution-service-websocket-limits-table). Default: 7200 (2 hours)
--webSocketIdleTimeout      Set WebSocket idle timeout in seconds to reproduce AWS limits (https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html#apigateway-execution-service-websocket-limits-table). Default: 600 (10 minutes)
--useDocker                 Run handlers in a docker container.
--layersDir                 The directory layers should be stored in. Default: ${codeDir}/.serverless-offline/layers'
--dockerReadOnly            Marks if the docker code layer should be read only. Default: true
--allowCache                Allows the code of lambda functions to cache if supported.
--overrideLayersDir         Forces docker to use a mapped host directory instead of downloading layers, incredibly useful for debugging
--overrideCodeDir           Forces docker to use a mapped host directory instead of package artifact of named handler, incredibly useful for debugging

Any of the CLI options can be added to your serverless.yml. For example:

custom:
  serverless-offline:
    httpsProtocol: "dev-certs"
    httpPort: 4000
    stageVariables:
      foo: "bar"

Options passed on the command line override YAML options.

By default, you can send your requests to http://localhost:3000/. Please note that:

  • You'll need to restart the plugin if you modify your serverless.yml or any of the default velocity template files.
  • When no Content-Type header is set on a request, API Gateway defaults to application/json, and so does the plugin. But if you send an application/x-www-form-urlencoded or a multipart/form-data body with an application/json (or no) Content-Type, API Gateway won't parse your data (you'll get the ugly raw as input), whereas the plugin will answer 400 (malformed JSON). Please consider explicitly setting your requests' Content-Type and using separate templates.

Usage with invoke

To use Lambda.invoke you need to set the lambda endpoint to the serverless-offline endpoint:

const { Lambda } = require('aws-sdk')

const lambda = new Lambda({
  apiVersion: '2015-03-31',
  // endpoint needs to be set only if it deviates from the default, e.g. in a dev environment
  // process.env.SOME_VARIABLE could be set in e.g. serverless.yml for provider.environment or function.environment
  endpoint: process.env.SOME_VARIABLE
    ? 'http://localhost:3002'
    : 'https://lambda.us-east-1.amazonaws.com',
})

All your lambdas can then be invoked in a handler using

exports.handler = async function() {
  const params = {
    // FunctionName is composed of: service name - stage - function name, e.g.
    FunctionName: 'myServiceName-dev-invokedHandler',
    InvocationType: 'RequestResponse',
    Payload: JSON.stringify({ data: 'foo' }),
  }

  const response = await lambda.invoke(params).promise()
}

You can also invoke using the aws cli by specifying --endpoint-url

aws lambda invoke /dev/null \
  --endpoint-url http://localhost:3002 \
  --function-name myServiceName-dev-invokedHandler

List of available function names and their corresponding serverless.yml function keys are listed after the server starts. This is important if you use a custom naming scheme for your functions as serverless-offline will use your custom name. The left side is the function's key in your serverless.yml (invokedHandler in the example below) and the right side is the function name that is used to call the function externally such as aws-sdk (myServiceName-dev-invokedHandler in the example below):

serverless offline
...
offline: Starting Offline: local/us-east-1.
offline: Offline [http for lambda] listening on http://localhost:3002
offline: Function names exposed for local invocation by aws-sdk:
           * invokedHandler: myServiceName-dev-invokedHandler

To list the available manual invocation paths exposed for targeting by aws-sdk and aws-cli, use SLS_DEBUG=* with serverless offline. After the invoke server starts up, full list of endpoints will be displayed:

SLS_DEBUG=* serverless offline
...
offline: Starting Offline: local/us-east-1.
...
offline: Offline [http for lambda] listening on http://localhost:3002
offline: Function names exposed for local invocation by aws-sdk:
           * invokedHandler: myServiceName-dev-invokedHandler
[offline] Lambda Invocation Routes (for AWS SDK or AWS CLI):
           * POST http://localhost:3002/2015-03-31/functions/myServiceName-dev-invokedHandler/invocations
[offline] Lambda Async Invocation Routes (for AWS SDK or AWS CLI):
           * POST http://localhost:3002/2014-11-13/functions/myServiceName-dev-invokedHandler/invoke-async/

You can manually target these endpoints with a REST client to debug your lambda function if you want to. Your POST JSON body will be the Payload passed to your function if you were to calling it via aws-sdk.

The process.env.IS_OFFLINE variable

Will be "true" in your handlers and thorough the plugin.

Docker and Layers

To use layers with serverless-offline, you need to have the useDocker option set to true. This can either be by using the --useDocker command, or in your serverless.yml like this:

custom:
  serverless-offline:
    useDocker: true

This will allow the docker container to look up any information about layers, download and use them. For this to work, you must be using:

  • AWS as a provider, it won't work with other provider types.
  • Layers that are compatible with your runtime.
  • ARNs for layers. Local layers aren't supported as yet.
  • A local AWS account set-up that can query and download layers.

If you're using least-privilege principals for your AWS roles, this policy should get you by:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "lambda:GetLayerVersion",
            "Resource": "arn:aws:lambda:*:*:layer:*:*"
        }
    ]
}

Once you run a function that boots up the Docker container, it'll look through the layers for that function, download them in order to your layers folder, and save a hash of your layers so it can be re-used in future. You'll only need to re-download your layers if they change in the future. If you want your layers to re-download, simply remove your layers folder.

You should then be able to invoke functions as normal, and they're executed against the layers in your docker container.

Additional Options

There are 2 additional options available for Docker and Layer usage.

  • layersDir
  • dockerReadOnly

layersDir

By default layers are downloaded on a per-project basis, however, if you want to share them across projects, you can download them to a common place. For example, layersDir: /tmp/layers would allow them to be shared across projects. Make sure when using this setting that the directory you are writing layers to can be shared by docker.

dockerReadOnly

For certain programming languages and frameworks, it's desirable to be able to write to the filesystem for things like testing with local SQLite databases, or other testing-only modifications. For this, you can set dockerReadOnly: false, and this will allow local filesystem modifications. This does not strictly mimic AWS Lambda, as Lambda has a Read-Only filesystem, so this should be used as a last resort.

Token authorizers

As defined in the Serverless Documentation you can use API Keys as a simple authentication method.

Serverless-offline will emulate the behaviour of APIG and create a random token that's printed on the screen. With this token you can access your private methods adding x-api-key: generatedToken to your request header. All api keys will share the same token. To specify a custom token use the --apiKey cli option.

Custom authorizers

Only custom authorizers are supported. Custom authorizers are executed before a Lambda function is executed and return an Error or a Policy document.

The Custom authorizer is passed an event object as below:

{
  "type": "TOKEN",
  "authorizationToken": "<Incoming bearer token>",
  "methodArn": "arn:aws:execute-api:<Region id>:<Account id>:<API id>/<Stage>/<Method>/<Resource path>"
}

The methodArn does not include the Account id or API id.

The plugin only supports retrieving Tokens from headers. You can configure the header as below:

"authorizer": {
  "type": "TOKEN",
  "identitySource": "method.request.header.Authorization", // or method.request.header.SomeOtherHeader
  "authorizerResultTtlInSeconds": "0"
}

Remote authorizers

You are able to mock the response from remote authorizers by setting the environmental variable AUTHORIZER before running sls offline start

Example:

Unix: export AUTHORIZER='{"principalId": "123"}'

Windows: SET AUTHORIZER='{"principalId": "123"}'

JWT authorizers

For HTTP APIs, JWT authorizers defined in the serverless.yml can be used to validate the token and scopes in the token. However at this time, the signature of the JWT is not validated with the defined issuer. Since this is a security risk, this feature is only enabled with the --ignoreJWTSignature flag. Make sure to only set this flag for local development work.

Custom headers

You are able to use some custom headers in your request to gain more control over the requestContext object.

HeaderEvent key
cognito-identity-idevent.requestContext.identity.cognitoIdentityId
cognito-authentication-providerevent.requestContext.identity.cognitoAuthenticationProvider

By doing this you are now able to change those values using a custom header. This can help you with easier authentication or retrieving the userId from a cognitoAuthenticationProvider value.

Environment variables

You are able to use environment variables to customize identity params in event context.

Environment VariableEvent key
SLSCOGNITOIDENTITYPOOLIDevent.requestContext.identity.cognitoIdentityPoolId
SLSACCOUNTIDevent.requestContext.identity.accountId
SLSCOGNITOIDENTITY_IDevent.requestContext.identity.cognitoIdentityId
SLS_CALLERevent.requestContext.identity.caller
SLSAPIKEYevent.requestContext.identity.apiKey
SLSCOGNITOAUTHENTICATION_TYPEevent.requestContext.identity.cognitoAuthenticationType
SLSCOGNITOAUTHENTICATION_PROVIDERevent.requestContext.identity.cognitoAuthenticationProvider

You can use serverless-dotenv-plugin to load environment variables from your .env file.

AWS API Gateway Features

Velocity Templates

Serverless doc ~ AWS doc

You can supply response and request templates for each function. This is optional. To do so you will have to place function specific template files in the same directory as your function file and add the .req.vm extension to the template filename. For example, if your function is in code-file: helloworld.js, your response template should be in file: helloworld.res.vm and your request template in file helloworld.req.vm.

CORS

Serverless doc

If the endpoint config has CORS set to true, the plugin will use the CLI CORS options for the associated route. Otherwise, no CORS headers will be added.

Catch-all Path Variables

AWS doc

Set greedy paths like /store/{proxy+} that will intercept requests made to /store/list-products, /store/add-product, etc…

ANY method

AWS doc

Works out of the box.

Lambda and Lambda Proxy Integrations

Serverless doc ~ AWS doc

Works out of the box. See examples in the manual_test directory.

HTTP Proxy

Serverless doc ~ AWS doc - AWS::ApiGateway::Method ~ AWS doc - AWS::ApiGateway::Resource

Example of enabling proxy:

custom:
  serverless-offline:
    resourceRoutes: true

or

    YourCloudFormationMethodId:
      Type: AWS::ApiGateway::Method
      Properties:
        ......
        Integration:
          Type: HTTP_PROXY
          Uri: 'https://s3-${self:custom.region}.amazonaws.com/${self:custom.yourBucketName}/{proxy}'
          ......
custom:
  serverless-offline:
    resourceRoutes:
      YourCloudFormationMethodId:
        Uri: 'http://localhost:3001/assets/{proxy}'

Response parameters

AWS doc

You can set your response's headers using ResponseParameters.

May not work properly. Please PR. (Difficulty: hard?)

Example response velocity template:

"responseParameters": {
  "method.response.header.X-Powered-By": "Serverless", // a string
  "method.response.header.Warning": "integration.response.body", // the whole response
  "method.response.header.Location": "integration.response.body.some.key" // a pseudo JSON-path
},

WebSocket

Usage in order to send messages back to clients:

POST http://localhost:3001/@connections/{connectionId}

Or,

const apiGatewayManagementApi = new AWS.ApiGatewayManagementApi({
  apiVersion: '2018-11-29',
  endpoint: 'http://localhost:3001',
});

apiGatewayManagementApi.postToConnection({
  ConnectionId: ...,
  Data: ...,
});

Where the event is received in the lambda handler function.

There's support for websocketsApiRouteSelectionExpression in it's basic form: $request.body.x.y.z, where the default value is $request.body.action.

Authorizers and wss:// are currently not supported.

Usage with Webpack

Use serverless-webpack to compile and bundle your ES-next code

Velocity nuances

Consider this requestTemplate for a POST endpoint:

"application/json": {
  "payload": "$input.json('$')",
  "id_json": "$input.json('$.id')",
  "id_path": "$input.path('$').id"
}

Now let's make a request with this body: { "id": 1 }

AWS parses the event as such:

{
  "payload": {
    "id": 1
  },
  "id_json": 1,
  "id_path": "1" // Notice the string
}

Whereas Offline parses:

{
  "payload": {
    "id": 1
  },
  "id_json": 1,
  "id_path": 1 // Notice the number
}

Accessing an attribute after using $input.path will return a string on AWS (expect strings like "1" or "true") but not with Offline (1 or true). You may find other differences.

Debug process

Serverless offline plugin will respond to the overall framework settings and output additional information to the console in debug mode. In order to do this you will have to set the SLS_DEBUG environmental variable. You can run the following in the command line to switch to debug mode execution.

Unix: export SLS_DEBUG=*

Windows: SET SLS_DEBUG=*

Interactive debugging is also possible for your project if you have installed the node-inspector module and chrome browser. You can then run the following command line inside your project's root.

Initial installation: npm install -g node-inspector

For each debug run: node-debug sls offline

The system will start in wait status. This will also automatically start the chrome browser and wait for you to set breakpoints for inspection. Set the breakpoints as needed and, then, click the play button for the debugging to continue.

Depending on the breakpoint, you may need to call the URL path for your function in seperate browser window for your serverless function to be run and made available for debugging.

Resource permissions and AWS profile

Lambda functions assume an IAM role during execution: the framework creates this role and set all the permission provided in the iamRoleStatements section of serverless.yml.

However, serverless offline makes use of your local AWS profile credentials to run the lambda functions and that might result in a different set of permissions. By default, the aws-sdk would load credentials for you default AWS profile specified in your configuration file.

You can change this profile directly in the code or by setting proper environment variables. Setting the AWS_PROFILE environment variable before calling serverless offline to a different profile would effectively change the credentials, e.g.

AWS_PROFILE=<profile> serverless offline

Scoped execution

Downstream plugins may tie into the before:offline:start:end hook to release resources when the server is shutting down.

Simulation quality

This plugin simulates API Gateway for many practical purposes, good enough for development - but is not a perfect simulator. Specifically, Lambda currently runs on Node.js v10.x and v12.x (AWS Docs), whereas Offline runs on your own runtime where no memory limits are enforced.

Usage with serverless-dynamodb-local and serverless-webpack plugin

Run serverless offline start. In comparison with serverless offline, the start command will fire an init and a end lifecycle hook which is needed for serverless-offline and serverless-dynamodb-local to switch off resources.

Add plugins to your serverless.yml file:

plugins:
  - serverless-webpack
  - serverless-dynamodb-local
  - serverless-offline # serverless-offline needs to be last in the list

Credits and inspiration

This plugin was initially a fork of Nopik's Serverless-serve.

License

MIT

Contributing

Yes, thank you! This plugin is community-driven, most of its features are from different authors. Please update the docs and tests and add your name to the package.json file. We try to follow Airbnb's JavaScript Style Guide.

Contributors

dnalborczykdheraultcomputerpuncleonardoalifracodaniel-cottone
dnalborczykdheraultcomputerpuncleonardoalifracodaniel-cottone
mikestaubBilal-Sdl748frsechetzoellner
mikestaubBilal-Sdl748frsechetzoellner
johncmckimThisIsNoZakudarthtrevinomiltadorgertjvr
johncmckimThisIsNoZakudarthtrevinomiltadorgertjvr
juanjoDiazperkyguyjack-seekhueniverserobbtraister
juanjoDiazperkyguyjack-seekhueniverserobbtraister
dortega3000ansraliantjoubertredratandreipopoviciAndorbal
dortega3000ansraliantjoubertredratandreipopoviciAndorbal
AyushG3112franciscocpgkajwiklundondrowansulaysumaria
AyushG3112franciscocpgkajwiklundondrowansulaysumaria
jormaecheaawwong1c24wvmadmanencounter
jormaecheaawwong1c24wvmadmanencounter
Bob-Thomasnjriordanbebbitrevor-leachemmoistner
Bob-Thomasnjriordanbebbitrevor-leachemmoistner
OrKoNadieuadieuapalumboanishknycameroncooper
OrKoNadieuadieuapalumboanishknycameroncooper
cmuto09dschepDimaDK24dwbellistoneabadjiev
cmuto09dschepDimaDK24dwbellistoneabadjiev
Arkfillegarunskijames-relyeajoewestcottLoganArnett
Arkfillegarunskijames-relyeajoewestcottLoganArnett
ablythemarccampbellpurefanmzmiric5paulhbarker
ablythemarccampbellpurefanmzmiric5paulhbarker
pmuenspierreisramonEmiliorschickselcukcihan
pmuenspierreisramonEmiliorschickselcukcihan
patrickheeneyrma4okclschneidjcrabhatadam-nielsen
patrickheeneyrma4okclschneidjcrabhatadam-nielsen
adamelliottsweetingagaineralebianco-doxeekoterpillartriptec
adamelliottsweetingagaineralebianco-doxeekoterpillartriptec
constbcspotcodealiatsisarnasakaila
constbcspotcodealiatsisarnasakaila
ac360austin-paynebencoolingBorjaMacedoBrandonE
ac360austin-paynebencoolingBorjaMacedoBrandonE
guerrerocarloschrismcleodchristophgysinClement134rlgod
guerrerocarloschrismcleodchristophgysinClement134rlgod
dbunkerdobrynindomaslasauskasenolanminibikini
dbunkerdobrynindomaslasauskasenolanminibikini
em0neyerauergbroquesguillaumebalassy
em0neyerauergbroquesguillaumebalassy
idmontiejacintoAriasjgriggjsnajdrhoryd
idmontiejacintoAriasjgriggjsnajdrhoryd
jaydp17jeremygibersonjosephwarrickjlsjonasjoostfarla
jaydp17jeremygibersonjosephwarrickjlsjonasjoostfarla
kenleytomlinlalifraco-devsparkDynamicSTOPmedikooneverendingqs
kenleytomlinlalifraco-devsparkDynamicSTOPmedikooneverendingqs
msjonkerTakenomjmacojongeriusthepont
msjonkerTakenomjmacojongeriusthepont
WooDzuPsychicCatRaph22wwsnogribnoysup
WooDzuPsychicCatRaph22wwsnogribnoysup
starsprungshineli-not-used-anymorestesiestevemaoittus
starsprungshineli-not-used-anymorestesiestevemaoittus
tiagogoncalves89tuanmhGregoirevdagcphostYaroslavApatiev
tiagogoncalves89tuanmhGregoirevdagcphostYaroslavApatiev
zacacollierallenhartwigdemetriusnuneshszelectrikdevelopment
zacacollierallenhartwigdemetriusnuneshszelectrikdevelopment
jgilbert01polaris340kobanyanleruitga-sslivingmine
jgilbert01polaris340kobanyanleruitga-sslivingmine
lteachermartinmicundanori3tsuppasmanikryanzyy
lteachermartinmicundanori3tsuppasmanikryanzyy
m0ppersfootballencartabryanvaz
m0ppersfootballencartabryanvaz
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文