Traefik Routing is not enough for gRPC

Hi everybody
I am using traefik v2.0 as api gateway for our company gRPC services.
we are using url path for choose between services:
api.example.com/service1 for invoke service 1 grpc service
api.example.com/service2 for invoke service 2 grpc service

in gRPC request for api.example.com/service1 request header will be something like this:
Host: api.example.com/service1
Url: {proto_package_name}|.{proto_service_name}/method_name

in this condition you can not use Path, PathPrefix rules as mentioned in docs

I had to use HostRegexp to discriminate urls.
Unfortunately this condition is not handled in code.
in file regex.go
line 314
in getHost function you are truncating url after colon :
and this means any url on non 80 port will be changed before compare with reqex

i some days ago suggested new routing rule in this issue

now i have to comment out line 314-316 and build traefik again to use for my purpose
i think this scenario is not so rare to try to discriminate grpc requests based on url path.

BTW: i did not get any feedback on my issue rather than traefiker bot. :smile:

1 Like

I'm not very familiar with gRPC, but what I do know is that host header is defined by RFC 7230 section 5.4. It does not and cannot contain URLs, so it appears that what you are trying to do cannot work in principle.

Edit: I just realize that gRPC is based on http2 and I'm quoting http1. I had a quick look-over http2 and I did not find any indication that a host header could contain url either.

Dear Andrew
Thank you for response.
Please take look at gRPC over Http2 Docs

  • Path → ":path" "/" Service-Name "/" { method name } # But see note below.

There is no way to use path header for identity caller destination url.
I agree with you that use host header to send url path is not good idea.
but decisions about how to send request header was made by gRPC developers.
I think Traefik as potential api gateway for gRPC must choice a clear approach to
route gRPC requests based on url path.
Unfortunately i have no clear suggestion to how to support url based routing for gRPC requests.
:frowning:

1 Like

I think in this situation, we have two identities:
Method and Path

If we take http1 and grpc standards and mix them, we can achieve this conclusion:

Assuming we send request to localhost:8000/somepath and the proto's generating url is mypackage.MyService/MyRPC, in the current version of traefik, the host and path are set to:
Host: localhost
Path: /mypackage.MyService/MyRPC

but with those two identities from http1, we can have:
Host: localhost
Path: /somepath
Method: /mypackage.MyService/MyRPC

Now we don't remove that /somepath from everywhere! and we have access to it!

I believe this is much more standard and cleaner, based on both http1 and grpc.

Hello,

you can route by using HeadersRegexp

https://docs.traefik.io/v2.0/routing/routers/#rule

which header can we use to capture those paths after host?

I checked and it looked like there was a X-Forwarded-Host that would contain the whole host and path.

But there are a couple of questions:
1- Is this header set AFTER the traefik routes or BEFORE it?
2- Is this header client-dependent? As this is a server, we need to be sure that every client with whatever thing they're requesting, must include this header.

Thanks for quick response.