An API gateway serves as an intermediary between the client and the backend services by providing a unified entry point for all API calls. It accepts incoming requests from clients, routes them to the appropriate backend services, and then aggregates the responses and returns them to the client. This helps to streamline the communication process between the client and the backend services, making it more efficient and easier to manage. An API gateway acts as a reverse proxy to accept all application programming interface (API) calls, aggregate the various services required to fulfill them, and return the appropriate result.
For example, rate limiting can be accomplished with an API gateway. This removes the burden from the API endpoint itself, as no rules or logic is needed on the API endpoint itself.
Let’s see how this works with Kong.
Kong’s website describes Kong as:
Kong Gateway is a lightweight, fast, and flexible cloud-native API gateway. An API gateway is a reverse proxy that lets you manage, configure, and route requests to your APIs [1].
Install Kong using these instructions.
Access Kong with: http://TARGET:8002/overview
We should see the below:
Add service
We can add a test service like this:
1
2
3
4
curl -v -XPOST \
http://localhost:8001/services \
-H 'Content-Type: application/json' \
-d '{"name":"api1","retries":1,"host":"httpbin.org"}'
The response will have a service id that we will use shortly.
Add routes
We can add a route like below. Replace the service id with what you obtained earlier.
1
2
3
4
curl -XPOST \
http://localhost:8001/routes \
-H 'Content-Type: application/json' \
-d '{"name":"api1-route1", "protocols": ["http", "https"], "methods": ["GET"],"hosts": ["your_host"], "paths": ["/api1"], "strip_path": true, "preserve_host": false, "service": {"id":"02facddf-f5ab-4699-a829-c8832ea9e330"} }'
Test
The below will hit https://httpbin.org/headers.
1
2
3
4
5
6
7
8
9
10
11
12
$ curl http://localhost:8000/api1/headers
{
"headers": {
"Accept": "*/*",
"Host": "httpbin.org",
"User-Agent": "curl/7.84.0",
"X-Amzn-Trace-Id": "Root=1-65383479-744ac5662ea208a05177c7c3",
"X-Forwarded-Host": "localhost",
"X-Forwarded-Path": "/api1/headers",
"X-Forwarded-Prefix": "/api1"
}
}
This API exposed is accessible to anyone. We would like to restrict access to it. Normally, you could add that feature to the API endpoint itself. We would like to take that responsibility away.
Enable API keys
We can enable this using a plugin, https://docs.konghq.com/hub/kong-inc/key-auth/:
1
2
3
4
curl -i -XPOST \
http://localhost:8001/services/api1/plugins/ \
-H 'Content-Type: application/json' \
-d '{"name":"key-auth"}
Please note that the api key can be easily sniffed out with this example using just plain old HTTP
Now, when we try to access the API endpoint, we get an error:
1
2
3
4
$ curl http://localhost:8000/api1/headers
{
"message":"No API key found in request"
}
Add a consumer object, then key
Add a consumer object (or user):
1
2
3
4
curl -i -XPOST \
http://localhost:8001/consumers/ \
-H 'Content-Type: application/json' \
-d '{"username":"apiuser1"}
Add a key for the consumer:
1
2
3
4
curl -i -XPOST \
http://localhost:8001/consumers/apiuser1/key-auth \
-H 'Content-Type: application/json' \
-d '{"key":"secret1234"}'
Test (Again)
Now, it works again:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ curl http://localhost:8000/api1/headers -H 'apikey: secret1234'
{
"headers": {
"Accept": "*/*",
"Apikey": "secret1234",
"Host": "httpbin.org",
"User-Agent": "curl/7.84.0",
"X-Amzn-Trace-Id": "Root=1-65383a6e-13af256717575db754bbe038",
"X-Consumer-Id": "9998fce5-4df6-433f-aa97-a90fb006901b",
"X-Consumer-Username": "apiuser1",
"X-Credential-Identifier": "33c5b1e8-6361-4946-b7f7-c1ffa0e51cbf",
"X-Forwarded-Host": "localhost",
"X-Forwarded-Path": "/api1/headers",
"X-Forwarded-Prefix": "/api1"
}
}
References
[1] https://docs.konghq.com/gateway/latest/