Use an API gateway in front of multiple services

Learn how to use an API gateway in front of multiple services

Using an API gateway is perfect to expose a single web API domain without exposing the underlying implementation. Especially, when using a decoupled architecture with multiple services.

API Gateway architecture

In this tutorial, you will learn how to connect an API gateway in front of 3 different applications (cf. schema above).

Note: My tutorial required to have 3 applications - a billing API, core API and a messaging API. You don't necessarily need to have 3 applications to put an API gateway. Only one application is enough. Feel free to adapt the tutorial to your real need.

Clone API Gateway

I have prepared an API Gateway template project that you can find here. Fork it, and I will guide you to make the appropriate changes. Our API Gateway is based on NGINX - one of the most used web server out there. Written in C++, NGINX is lightweight and can handle thousands of requests per second without any issue.

Repository to fork: https://github.com/Qovery/nginx-gateway

Edit configuration

Once the repo forked, you will have access to nginx.conf.template and routes.conf.template - which are the two configuration files. The nginx.conf.template is the configuration of the NGINX server. This is where you can tweak your server. We will not modify it since I have set up a good configuration for an API gateway. Feel free to dig into it and check out the NGINX documentation to learn more.

However, the routes.conf.template is the file that we need to modify to route the incoming traffic from api.foo.bar to the right service. Our route configuration file looks like this:

routes.conf.template
location ~* ^/api/billing/?(.*)$ {
proxy_pass http://$BILLING_BACKEND$request_uri;
}
location ~* ^/api/messaging/?(.*)$ {
proxy_pass http://$MESSAGING_BACKEND$request_uri;
}
location ~* ^/api/(.*)$ {
proxy_pass http://$CORE_BACKEND$request_uri;
}
location ~* ^/?(.*)$ {
proxy_pass http://$CORE_BACKEND$request_uri;
}

Here are the explanation of those rules:

  1. All the traffic matching the path /api/billing/* is redirect to the BILLING backend.
  2. All the traffic matching the path /api/messaging/* is redirect to the MESSAGING backend.
  3. All the traffic matching the path /api/* is redirect to the CORE backend.
  4. All the traffic by default is redirected to the CORE backend.

Notes:

  1. The rule definition order is from the first to the last to apply. If there is a conflicting rule, then the first matched applies.
  2. The internal network is in HTTP, that is why the value of the proxy_pass directive starts with http://.
  3. The connections on api.foo.bar are in HTTPS.
  4. You can make complex rules like the one below:
more complex rule
location ~* ^/api/v1/user/(.*)/app/(.*)/index/(.*)/search/?(.*)$ {
proxy_pass http://$CORE_BACKEND/api/v1/user/$1/app/$2/index/$3/search/$4$is_args$args;
}

Create API Gateway app

Commit and push your changes. Then go to the Qovery web console, and add your API gateway inside the same environment of your applications.

  • Build mode: Dockerfile
  • Port: 80

Add environment variables

For our gateway, we need to create 3 environment variable aliases corresponding to the internal network names of our applications.

  • XXX_HOST_INTERNAL -> ALIAS -> BILLING_BACKEND with scope ENVIRONMENT
  • YYY_HOST_INTERNAL -> ALIAS -> MESSAGING_BACKEND with scope ENVIRONMENT
  • ZZZ_HOST_INTERNAL -> ALIAS -> CORE_BACKEND with scope ENVIRONMENT

How to find the correct environment variable

When you have multiple applications within the same environment, it is difficult to find the appropriate environment variable. A workaround is to:

  1. Go to one of your application
  2. Find the ID of your application in your URL https://console.qovery.com/platform/organization/xxx/projects/yyy/environments/zzz/applications/082e36c4-7fbb-42b2-9046-37ccce21616a/variables
  3. Truncate your application ID and take the first segment. For 082e36c4-7fbb-42b2-9046-37ccce21616a it is 082e36c4
  4. Add the letter z in front of id Z082e36c4.
  5. All the environment variables containing Z082e36c4 are attached to the corresponding app.

Set up custom domain

Add a custom domain to expose your API gateway with the domain of your choice. Check out this documentation to set up your domain.

Deploy API Gateway

Once everything is set up, you can deploy your application.