4

I have a question regarding a specific case with our product.

Let's say I have two services; Service A and Service B. (The number of services varies from an installation to installation). They are deployed into our Docker Swarm. They do not publish any ports, meaning that they are not reachable from outside our Swarm cluster. And I have an Nginx container, which publishes a port to outside of Swarm, and which we use as reverse proxy.

Service A and Service B do very similar things, which one will be called is up to our client's preferences. We would like our clients to use the same endpoint (say HTTP POST /some-event) to access those services but also pick a service (Service A or Service B) by providing something extra with the request context.

For example, we thought of implementing yet another server with access to Service A and Service B, creating access keys for both services, writing them to database and providing our clients with the access keys. This new server will be the only recipient of HTTP POST /some-event and will route the request to Service A or Service B depending on the access key provided with request context (say in header, etc.) But this seemed like reinventing the wheel.

I am also looking into Netflix Zuul, but this solution involves writing a Zuul configuration every time we deploy our product (depending on how many service we deploy with each installation).

So the question is; what might be alternative ways of achieving dynamic routing with Headers for requests made to the same resource/service? Thanks!

  • 1
    Why writing a Zuul configuration is an issue? – Arseni Mourzenko Oct 30 '16 at 21:08
2

I do something similar to what you describe in my design. Though I solved it by routing on domain name. Imo, different services should be distributed under different domains/sub-domains.

However, If you are set on using headers for routing, you could do something like this:

upstream service1 { server 127.0.1.1:65535; }
upstream service2 { server 127.0.1.2:65535; }

map $http_x_access_key $access_key 
{
  123 "service1";
  456 "service2";
}

server 
{
  listen 80;
  server_name example.com;
  location / 
  {
     proxy_pass http://$access_key;
     # proxy settings
     # ...
  }
}

http://nginx.org/en/docs/http/ngx_http_map_module.html


If you need to access a db layer in order to resolve the request, then I would suggest writing your own reversed proxy to solve this. You should be able to do so in just a few lines, and you will be able to extend the functionality further down the line if needed.

  • 1
    This is a good solution, but had some drawbacks for my use case. First, I really really didn't want to hard-code access keys 123 and 456 into the nginx.conf, I wanted them to be parametric. So I had to use zuul with a route filter, and accessed db to resolve which service the client is trying to access and retrieve where the services are located. But your suggestion definitely made me decide on using a reverse proxy to handle this case. – Hasan Can Saral Nov 5 '16 at 16:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.