8

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?

majurageerthan
  • 2,169
  • 3
  • 17
  • 30
gr3g
  • 2,866
  • 5
  • 28
  • 52
  • It appears that `serverless-offline` will proxy requests to `http://localhost:3000` by default, and this will handle requests against multiple endpoints/functions. But it sounds like you have something different going on - can you post your `serverless.yml`? I don't really know the answer to this question, as this is a very bleeding edge project, but I might be able to talk through a few things. – killthrush Sep 24 '17 at 14:33
  • I had multiple services/.yml's: so different API Gateways that had to run on different servers. – gr3g Sep 25 '17 at 16:08

4 Answers4

6

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.

iaforek
  • 2,860
  • 5
  • 40
  • 56
6

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

majurageerthan
  • 2,169
  • 3
  • 17
  • 30
4

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

John Paulo Rodriguez
  • 1,280
  • 18
  • 21
3

Check this package out: https://github.com/edis/sls-multi-gateways

It simulates AWS API Gateways’ API mappings on your local environment.

It allows you to run multiple API gateways under a single port (on your local), forwarding requests to each service based on base paths you configure.

For example, if you have two serverless apps — one for authentication and one for products. You can assign a different base path for each serverless app. So when you receive a request to localhost:3000/auth/* , it sends the request to the auth serverless app. And when you receive a request to localhost:3000/products/* , it sends the request to the products serverless app.