Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
@serverless/emulator
Advanced tools
[![serverless](http://public.serverless.com/badges/v3.svg)](http://www.serverless.com) [![Build Status](https://travis-ci.org/serverless/emulator.svg?branch=master)](https://travis-ci.org/serverless/emulator)
Website • Newsletter • Gitter • Forum • Meetups • Twitter
Emulate your Serverless functions locally.
npm install
to install all dependenciesscripts/sync-storage
to sync the example storage
artifacts with the Local Emulators storage
locationnpm run build
to build the project (the build artifacts can be found in dist
)npm start
to start the emulatorYou can run npm run watch
to automatically re-build the files in the src
directory when they change.
Additionally you can use Docker to run and develop everything inside a container.
Spinning up the Docker container is as easy as docker-compose run -p 4002:4002 node bash
. Make sure to run the steps in Getting started.
Or, if you need a build a Docker image and run it, do:
docker build -t local-emulator .
docker run --rm -it -p 4002:4002 local-emulator
The following documents provide some insights on how to configure and use the Local Emulator.
The Local Emulator can be configured with the following options you can pass in via the CLI:
--port
- number
- Optional port (defaults to 4002
)Command | Description |
---|---|
npm start | Will start the Local Emulator at localhost with the default port |
npm start -- --port 4711 | Starts the local Emulator at localhost with the port 4711 |
The Local Emulator is a software which makes it possible to emulate different cloud provider FaaS offerings (such as AWS Lambda or Google Cloud Functions) on your local machine in an offline-focused manner.
It can be used to deploy and invoke serverless functions w/o the need to go through the process of setting up and configuring a cloud provider account or deploying the functions into the infrastructure before being able to use them.
This enables new ways of doing offline-first serverless development with a way faster feedback loop.
Technically speaking the Local Emulator is a long running process (Daemon) which exposes an API and accepts different calls to API endpoints in order to perform actions and control its behavior.
Note: The API is only used to control the Local Emulator. It is NOT the same as an API Gateway.
Functions are deployed via the API and are stored in the ~/.serverless/local-emulator
directory according to the following filesystem structure:
|__ storage
|__ functions
|__ <service-name>
|__ <function-name>
|__ code
|__ function.json
The root directory is the storage
directory. It's a place where all artifacts will be stored.
The functions
directory is the place where all the function-related artifacts are stored.
A directory for the specific service contains directories for each individual function.
The code
directory is the place where the actual (unzipped) function code is stored.
The function.json
file contains important information about the function configuration (e.g. what runtime
this function uses or which provider
it's written for) and other metadata.
The proposed directory structure makes it easy for the Local Emulator to follow a convention-over-configuration approach where artifacts are stored in a predictable way without having to introduce a local DB with state information about all the deployed functions and services.
On every function deployment the following happens behind the scenes:
service
and function
a separate directory will be created (if not already present).zip
file will be extracted and moved into the code
directoryfunction
configuration which is passed in via the API will be written into the function.json
filefunction.json
Every function needs information about its configuration. This information is passed in via the API when the function is deployed.
Upon deployment this data is persisted in the function.json
file.
The function.json
files can be found in ~/.serverless/local-emulator/storage/functions/<service-name>/<function-name>
.
The Local Emulator needs those file to e.g. make decision which middlewares to execute or which runtime-specific wrapper to use.
Here's a list with different example functions and their corresponding provider-related function.json
config files:
When invoking a function the Local Emulator will simply look for the function directory (see above how the naming schema helps with the lookup), determines the provider
, runtime
and handler
based on the config in the function.json
file and starts the execution phase which will happen in a dedicated child process (more on that later).
The invocation data is extracted from the incoming API requested and passed to a so-called runtime-specific "wrapper script" via stdin
. This "wrapper script" is responsible to setup the execution environment, require the function and pass the event payload to the function (you can think of it as a language specific container). Furthermore it will marshall the returned data and pass it back to the Local Emulators parent process which will then transform it into a JSON format and sends it back via an API response.
The whole invocation happens in a child_process.spawn()
call to ensure that the Local Emulator won't crash when a function misbehaves.
This abstraction layer makes it easy to introduce other runtimes later on. Furthermore the way the incoming event data is handled by the Local Emulator is always the same and independent of the function handler signature since the wrapper encapsulates the logic to marshall and unmarshall the data which is handed over to the function.
Here's a sample call to invoke an AWS function within the wrapper script (which is written in Node.js). It will require and prepare the function (according to the CLI options
) and pass the echoed data as the function parameters (via stdin
) to it:
# NOTE: This is not the actual payload. It's used to show the technical parts / architecture of a function invocation
echo '{ event: { foo: "bar" }, context: {}, callback: (error, result) => {} }' | runtimes/node.js <full-path-to-function-file> <exported-function-name>
The Local Emulator provides a middleware concept which makes it possible to use custom code to modify the data which is used inside the Local Emulator when exercising core logic (e.g. setting up the execution environment, invoking functions, etc.).
The core Local Emulators runMiddleware
functionality ensures that the raw data object which is passed into it will be copied over into an input
object and removed from the root of the object. Furthermore it creates a blank output
object which can be used by middlewares to store the computed results.
Let's take a quick look at an example to see how this works behind the scenes.
We assume that the data which is passed into the Local Emulators runMiddleware
function has the following shape:
{
foo: 'bar',
baz: 'qux'
};
The data will be prepared and passed into the middlewares in the following format:
{
input: {
foo: 'bar',
baz: 'qux'
},
output: {}
}
Middlewares can do whatever they want with this data.
However the computed result should be written into the output
object since this is returned by the Local Emulators runMiddlewares
function after all middlewares are executed.
Middlewares can be implemented against different lifecycle events. Right now the lifecycle events are:
Lifecycle | Description | Provided object | Expected returned object |
---|---|---|---|
preLoad
| Before the function is loaded and the execution environment is configured. |
{
input: {
serviceName: ,
functionName ,
functionConfig:
},
output: {}
}
|
{
input: {
// ...snip...
},
output: {
functionName: ,
functionFileName: ,
env:
}
}
|
postLoad
| After the function was loaded and the execution environment was configured. |
TBD
|
TBD
|
preInvoke
| Right before the payload is passed to the function which should be invoked. |
{
input: {
serviceName: ,
functionName: ,
functionConfig: ,
payload:
},
output: {}
}
|
{
input: {
// ...snip...
},
output: {
// NOTE: those params should
// include the callback function parameter!
}
}
|
postInvoke
| After the function is invoked, but before it's result is passed back via the API. |
{
input: {
serviceName: ,
functionName: ,
functionConfig: ,
payload: ,
errorData: ,
outputData:
},
output: {}
}
|
{
input: {
// ...snip...
},
output: {
errorData: ,
outputData:
}
}
|
Take a look at our core-middlewares
to see some example implementations.
Middlewares are loaded and executed in the following order:
core-middlewares
in an alphabetical orderThe Local Emulator exposes different APIs which makes it possible to interact with it and perform specific actions.
Examples for such actions could e.g. be the deployment or invocation of functions.
Right now only an HTTP API is implemented. However other API types such as (g)RPC are imaginable.
The Local Emulator exposes a HTTP API which makes it possible for other services to interact with it via HTTP calls.
POST /v0/emulator/api/functions
Request:
functionName
- string
- required The name of the functionserviceName
- string
- required The service the function belongs tofunctionConfig
- object
: - required Additional (provider dependent) function configurationzipFilePath
- string
- required The path to the local zip fileResponse:
functionName
- string
- The name of the functionserviceName
- string
- The service the function belongs tofunctionConfig
- object
- Additional (provider dependent) function configurationzipFilePath
- string
- The path to the local zip filePOST /v0/emulator/api/functions/invoke
Request:
functionName
- string
- required The name of the functionserviceName
- string
- required The service the function belongs topayload
- object
- required The event payload the function should receiveResponse:
POST /v0/emulator/api/utils/heartbeat
Request:
ping
- string
- required The string the Local Emulator should returnResponse:
pong
- string
- The string the Local Emulator should returntimestamp
- integer
- Timestamp which indicates when the response was computedFAQs
[![serverless](http://public.serverless.com/badges/v3.svg)](http://www.serverless.com) [![Build Status](https://travis-ci.org/serverless/emulator.svg?branch=master)](https://travis-ci.org/serverless/emulator)
We found that @serverless/emulator demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 6 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
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.