A basic API gateway serving both internal and services - built with Kong, Docker, & PostgreSQL
-
Install Docker from here if you don't have it already
-
Install docker-compose as well
apt install docker-compose
- clone the repo
git clone https://github.com/rafian-git/simple-kong-docker-API-gateway.git
- change directory into project folder
cd simple-kong-docker-API-gateway
- start the project running docker-composer
docker-compose up -d
Note that the -d flag will running the containers as a background process. The compose file does 4 things:
- Creates PostgreSQL container as a backend data store (configuration info) for Kong .
- Creates an ephemeral to initialize the Postgres database.
- Builds a container for the Hello world Node.js microservice.
- Runs the Kong API Gateway as a container.
- Verify by checking running containers
docker ps
- Verify if the Kong Gateway and Admin API are responding:
curl http://localhost:8000
curl http://localhost:8001
- To get the list of all available Admin API endpoints:
curl http://localhost:8001/endpoints
Now, create a local service and name it anything with hyphen separated words like your-service-name. We will forward our requests to our external service(hosted in another remote machine). For the sake of this project we will consider a public API as our external service. You'll find a lot of public APIs to play with here or here. We will be using catfact.ninja in this project. This is a two part process as both the service and then the route must be established like so:
curl -i -X POST --url http://localhost:8001/services/ --data 'name=your-service-name' --data 'url=https://catfact.ninja/'
curl -i -X POST --url http://localhost:8001/services/your-service-name/routes --data 'hosts[]=your-service-name'
You can now test both the plubic API and the proxied service using cURL:
curl https://catfact.ninja/breeds
curl http://localhost:8000/breeds --header 'your-service-name'
Both will return the same result if you've done it right.
you can directly hit http://server-public-ip-address:8000/breeds instead of using curl if you're running it on a virtual server with public IP.
Following the recipe above, we can build an endpoint for the Node.js microservice:
curl -i -X POST --url http://localhost:8001/services/ --data 'name=hello-world-service' --data 'url=http://kong-app:3000'
curl -i -X POST --url http://localhost:8001/services/hello-world-service/routes --data 'hosts[]=hello-world-service'
Remember that this service is running in the kong-app container and is exposed to the isolated Docker network via port 3000 but callers cannot access it without going through the API gateway. We can reach the hello-world-service using the Host header just like the previous one:
curl http://localhost:8000 --header 'Host: hello-world-service'
Use the below endpoint to see a list of all the services enabled so far:
curl http://localhost:8001/services
Adding rate limiting (a maximum of 5 requests per minute in this case) to a service is as simple as running a single command:
curl -X POST http://localhost:8001/services/hello-world-service/plugins/ --data "name=rate-limiting" --data "config.minute=5" --data "config.policy=local"
If you hit the hello-world-service endpoint again, you will see additional headers in the response indicating the rate limit. Hit it more than 5 times to check if the plugin is working
curl http://localhost:8000 --header 'Host: hello-world-service'
You'll find a lot of ready plugins here
Key-based authorization can be add to the hello-world-service endpoint by enabling the key-auth plugin, creating a user (QA in this example) and then providing the access key:
curl -i -X POST --url http://localhost:8001/services/hello-world-service/plugins/ --data 'name=key-auth'
curl -i -X POST --url http://localhost:8001/consumers/ --data "username=QA"
curl -i -X POST --url http://localhost:8001/consumers/QA/key-auth/ --data 'key=Hello_Kong!'
Test the time-service endpoint both with and without specifying an API key:
curl http://localhost:8000 --header 'Host: hello-world-service'
curl http://localhost:8000 --header 'Host: hello-world-service' --header "apikey: Hello_Kong!"
& you're done! Find out more if you want - Docs