fastify / fastify-dx

Archived
901 stars 42 forks source link

Add support for x-vhost HTTP header #2

Closed micheleriva closed 2 years ago

micheleriva commented 2 years ago

Is your feature request related to a problem? Please describe. There are cases where it is not possible to edit the host file (i.e., CI phase), but still, the multi-tenancy layer needs to work.

Describe the solution you'd like Given the following app.mjs content:

export const tenants = {
  foo: 'foo.dev',
  bar: 'bar.dev',
}

it would be handy to configure a x-vhost HTTP header which will tell universify which tenant we want to reach:

curl -H "x-vhost: foo.dev" -X GET http://localhost:3000

Testing frameworks such as Cypress already support the possibility to add custom HTTP headers to their test calls.

davidmeirlevy commented 2 years ago

Let's say a client is calling the server in production with:

curl -H "x-vhost: foo.dev" -X GET http://bar.dev

What should be the expected result?

micheleriva commented 2 years ago

@davidmeirlevy nice one! v-host should take precedence, in my opinion, as this will be the parameter primarily used during the testing phase. What are your thoughts?

davidmeirlevy commented 2 years ago

Let's say not all tenants are friendly to each other, and foo makes a HTTP request to itself (foo.dev/api/posts), with a x-host header of "bar.dev". Should it get bar's posts or foo's? I believe foo's.

micheleriva commented 2 years ago

@davidmeirlevy good point! What if we make it incompatible? I mean, you're making a request to foo.dev/api/posts with an x-vhost header, unless explicitly configured with a configuration flag, it should throw an error imho.

davidmeirlevy commented 2 years ago

I made a solution for it in my own project by taking 2 different hosts into consideration:

  1. the default tenant + the default tenant host URL (both configured as environment variables). only from this URL, you can access another domain with the x-host header. on localhost, it's literally localhost. in some production areas - there's no host URL at all, so the operation (from this url) is disabled in production unless specified otherwise.

  2. the internal host URL. inside a Kubernetes cluster (or docker-compose), the ssr service has a "name" that other services can use to call it internally. so in those cases, x-service and y-service want to call the ssr-service, and they make an HTTP request to: http://ssr-service, and it works thanks to the internal network of the compose / k8s cluster. in this case, the ssr-service must know its own URL inside the internal network and insist on an x-host header.

galvez commented 2 years ago

Closing this until we revisit multi-tenant support.