This repository is the entry point for the Global Forest Watch API. The API consists of many microservices, which are managed and routed to by this gateway. This application is also responsible for transparently proxying requests to the old API, which continues to service requests for endpoints that have not yet been rebuilt.
The API is made up of many microservices that communicate with one another using HTTP. This repository contains the gateway that maintains a list of available services (in a MongoDB database) and routes requests to the services based on the given path, and also routes requests to the old Python API.
- If a given path matches existing microservices, it is directed there.
The Dispatcher middleware and DispatcherService are responsible for determining where to route requests.
There are two ways to discover microservices:
- Themselves, with services REST API
- A Worker that it is watching a consul-template file with the location of each microservice.
In local, we need add the microservice configuration (name, ip and port) to the consul.json. In this way, each time that the api-gateway refresh your microservices registered, he consult the file and call /info endpoint of all microservices that are configured in the file
When the api-gateway reads each location of the microservices, it makes a request to the endpoint /info of each microservice (see microservice-client and microservice-node-skeleton) to obtain the microservice's configuration (urls, swagger, etc).
Example result request:
{
"id": "skeleton-service_1.0.0",
"name": "Skeleton Service",
"tags": ["gfw"],
"urls": [{
"url": "/users",
"method": "GET",
"endpoints": [{
"method": "GET",
"path": "/api/v1/users"
}]
}, {
"url": "/users",
"method": "POST",
"endpoints": [{
"method": "POST",
"path": "/api/v1/users"
}]
}],
"swagger": {
"swagger": "2.0",
"info": {
"title": "Example microservice",
"description": "Example microservice",
"version": "1.0.0"
},
"host": "example.vizzuality.com",
"schemes": ["https", "http"],
"produces": ["application/json"],
"paths": {
"/users": {
"get": {},
"post": { }
}
},
"definitions": {}
}
}
The requirements for the API Gateway greatly depend on how you plan on running it. There are two ways to run the API:
- Natively
- Using Docker containers
In both cases, you will need git
to checkout the project.
If you want to run the API Gateway natively, you will need to install and configure:
If you are going to use containers, you will need:
- Docker
- docker-compose
- Create folders (to save dbs): /var/docker/data/redisdb and /var/docker/data/mongodb
Start by checking out the project from github
git clone https://github.com/Vizzuality/api-gateway.git
cd api-gateway
Once this is done, you can either run the application natively, or inside a docker container. If you decide to run it natively, you will need to first install the required npm libraries, and the start the application:
npm install
./gateway.sh start
If, on the other hand, you plan on using docker instead, you only need to fire up the containers
./gateway.sh develop
The application will be running on port 8000 of the corresponding host (typically localhost)
The application is deployed to Heroku, and thus is thankfully rather easy to deploy.
Setup Heroku for the repository:
heroku git:remote -a api-gateway-staging -r staging
And deploy as normal:
git push staging master
It is necessary to define these environment variables:
- NODE_ENV => Environment (prod, staging, dev)
The following environment variables can be used to setup HTTP Basic Authentication:
BASIC_AUTH
: 'on'/'off' depending on if the authentication is activeBASIC_AUTH_USERNAME
: usernameBASIC_AUTH_PASSWORD
: password
To activate the auth login in api-gateway, you set the AUTH_ENABLED environment variable to true:
AUTH_ENABLED = true
To config oauth providers (twitter, facebook and google), you can create a file 'auth.json' in the config folder or declare environment variables. The auth.json file has the next structure:
{
"google": {
"clientID": "<clientIdGoogle>",
"clientSecret": "<clientSecretGoogle>",
"scope": "https://www.googleapis.com/auth/plus.me"
},
"facebook": {
"clientID": "<clientIdFacebook>",
"clientSecret": "<clientSecretFacebook>",
"scope": "email"
},
"twitter": {
"consumerKey": "<consumerKeyTwitter>",
"consumerSecret": "<consumerSecretTwitter>"
}
}
```
In environment variables:
FB_CLIENTID = FB_CLIENTSECRET = FB_SCOPE = GOOGLE_CLIENTID = GOOGLE_CLIENTSECRET = GOOGLE_SCOPE = <Google scope. Ex: https://www.googleapis.com/auth/plus.me> TW_CONSUMERKEY = TW_CONSUMERSECRET =
If you don't want enable any oauth provider, you don't set the environment variables or properties in json of this provider
## Documentation
The services are documented using [Swagger](http://swagger.io/) specifications.
# TODO:
* [ ] Add support to several endpoint in each service url