Home API gateway
Post
Cancel

API gateway

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:

Main

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/

This post is licensed under CC BY 4.0 by the author.
Trending Tags