fastify / fastify-swagger

Swagger documentation generator for Fastify
MIT License
915 stars 201 forks source link

static mode postProcessor for each request (multi-tenant hosting) #683

Closed jonaskello closed 1 year ago

jonaskello commented 1 year ago

Prerequisites

🚀 Feature Proposal

I have the same need as in #92 of setting the authorizationUrl but based not only on the hosting environment but also on the request. The app I have is multi-tenant and each tenant has a different authorizationUrl. Which tenant is calling is determined by the domain.

Motivation

I don't think this can be achieved with the current postProcessor() introduced in #92 since it only runs once at setup.

Example

For example calling tenant1.myapp.com/theservice/docs means that the authorizationUrl should be something like https://login.myapp.com/auth/realms/tenant1/protocol/openid-connect/auth.

Calling tenant2.myapp.com/theservice/docs means that the authorizationUrl should be something like https://login.myapp.com/auth/realms/tenant2/protocol/openid-connect/auth.

mcollina commented 1 year ago

Thanks for reporting! Would you like to send a Pull Request to address this issue? Remember to add unit tests.

jonaskello commented 1 year ago

Yes, I could probably take a stab at a PR. However I would need some pointers to get started. From what I understand this package just decorates the server instance with swagger and then the swagger-ui package reads that object.

I'm thinking having the swagger object at server instance level would not really work if I would mutate it for each request? I would somehow have to have an original at the server instance level and then mutate it for each request, but then I guess swagger-ui would need to read it from the request rather than from the server instance? Should I decorate the request object instead of the server instance and then also change in the swagger-ui package?

climba03003 commented 1 year ago

I suggest to allow onSend hook in swagger-ui. https://github.com/fastify/fastify-swagger-ui/blob/ec929867f98ce64991953b3565ddfcd673b9e5cd/lib/routes.js#L56-L59

Then, the solution is relatively simple.


import fastifySwaggerUI from '@fastify/swagger-ui`

fastify.register(fastifySwaggerUI, {
  uiHook: {
    onSend(request, reply, payload, done) {
      // only update the /json path
      if(request.url.endsWith('/json')) {
        // check the host and mutate the result here
      }
    }
  }
})
jonaskello commented 1 year ago

Thanks, that seems like a simple solution :-). I'll open a new issue over at the fastify-swagger-ui and make a PR for that.