How to implement dynamic URL of a service


#1

We’re currently evaluating the latest Kong version, especially Services and Routes API.
And what is unclear is how to implement dynamic upstream routing based on a original URL.
I.e our project is running inside docker containers together with gateway (currently Openresty).
Gateway proxies external url incoming to external interface into internal docker overlay network.

The routing rules currently implemented are looking like this.

http://api.com/profile -> http://profile:9090/
http://api.com/auth -> http://auth:9090/

In Openresty it’s implemented like this (it’s just plain NGINX though)

 location ~ ^/(?<my_service>.+?)/(?<my_service_url>.*)$ {
  set         $upstream_endpoint http://$my_service:9090/$my_service_url$is_args$args;
  proxy_pass  $upstream_endpoint;
}

The same I was able to achive with deprecated API functionality since it supported regex in upstream URLs. Now, Services are not supporting this at all.

How to achieve the same goal with Routes / Services ?
Is it possible at all, or custom plugin should be created ?


#2

@eshepelyuk How about:

$ http :8001/services name=profile url=http://profile:9090 -f
$ http :8001/routes service.id=... hosts[]="api.com" paths[]="/profile" -f

Where ... is the id of the previously created Service. Note the use of -f to specify a form-encoded payloads, which is a bit easier to use from the CLI. Because the Route’s strip_path property defaults to true, the upstream request’s path will not include the my_service capture group as you seem to want (e.g. /profile).

The same way, the other service can be defined as:

$ http :8001/services name=auth url=http://auth:9090 -f
$ http :8001/routes service.id=... hosts[]="api.com" paths[]="/auth" -f

The same I was able to achive with deprecated API functionality since it supported regex in upstream URLs.

Did it? I have no recollection that the API entity supported regexes anywhere but in their downstream uris attribute. Which became the Routes’ paths attribute (a more appropriate name).

Services and Routes do not limit any of the possibilities offered by APIs. They introduce more granularity for endpoint-specific behaviour (e.g. plugins), and better flexibility.

If you haven’t done so, I encourage you to read up on them:


#3

@thibaultcha what if I’d tell that there’s several dozens (~ 100) of such services in our application.

Following the way you’ve suggested we’ll end up having ~ 100 service / route pairs.
Apart of the issue with maintanability and keeping those routes consintent, won’t it result into a performance degradation ?

Anyway having service / route for ~100 service seems just overcomplicated comparing to small portion of nginx config in openresty that performing the same job currently.


#4

@eshepelyuk Indeed. We currently support regex capture groups from the request’s URL (the Route’s paths attribute supports regexes, as noted). As of today, it’d require a small plugin to be developer that would inject such a captured group into the upstream request’s URL (see kong.service.request.set_path()).

The Enterprise Edition request transformer plugin supports this out of the box (although I seem to recall that documentation is still incoming for this feature).


#5

Thanks for the explanation.
Back to the plugin development, can this be achieved using existing serverless plugin ? It is posisble to change the resulting path from access phase via Serverless Plugin