Serverless Offline: handle multiple API gateways
You can easily debug your serverless application with the Serverless Framework and the Serverless Offline Plugin when you only have one, but how do you handle the case when you have multiple API Gateways/services?
Should I run serverless offline
for every service, with a different port configured in each .yml
?
and hardcode that port in the environment variables so I can access that port if process.env.offline
is true?
Solution 1:
If you want to run two or more Serverless API Gateways at the same time locally you can easily do it with --port
parameter.
Basically, open two command line windows and in the first window, go to your first service directory and run:
sls offline start --port 3001
in the other window, go to your second service and run:
sls offline start --port 3002
This way you you will have two services listening on two ports (in this examples http://localhost:3001
and http://localhost:3002
).
There is one catch (at the moment) if you also use serverless-dynamodb-local plugin:
If you don't use DynamoDB plugin then you are okay and can stop reading now :)
DynamoDB plugin is using the same --port
parameter and that causes java.net.BindException: Address already in use
See this issue: https://github.com/99xt/serverless-dynamodb-local/issues/135
The workaround for this is to keep serverless-offline-local
plugin enabled in only one service (if you have two or more).
Example,
In my-service-1
you keep all dynamodb config in serverless.yaml
file and start this service with default port: sls offline start --migrate true
. In the next service, let's call it my-service-2
you remove serverless-dynamodb-local
from plugins
in serverless.yaml
(there is no need for any other changes) and then you can start the service with: sls offline start --port 3001
.
First service will start DynamoDB and the second one will be able to use it.
Solution 2:
Update for the Accepted answer in 2022
according to the documentation, --port
is no longer available
use --httpPort
instead, like below code
sls offline --httpPort 3001
or 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"
from official documentation
Solution 3:
What I do is create another service that has all the functions of other services. Below is my folder structure.
main/
├── service1/
│ ├── ...
│ └── serverless.yml
├── service2/
│ ├── ...
│ └── serverless.yml
├── serverless.yml # offline service with serverless-offline plugin
├── node_modules # 1 node_modules for every services
└── ...
You can remove serverless-offline
plugin on the service1 and service2.
Update!
I've develop a script for generating offline serverless.yml. Check out the example here: https://github.com/Necromancerx/serverless-offline-template