mercurius-js / mercurius

Implement GraphQL servers and gateways with Fastify
https://mercurius.dev/
MIT License
2.33k stars 234 forks source link

Docs: document schema by http header (#913) #979

Closed brainrepo closed 1 year ago

brainrepo commented 1 year ago

closes #913 This PR explains exposing two different mercurius instances to the same route using the fastify/find-my-way custom constraints.

brainrepo commented 1 year ago

I am exploring alternative ways to solve this issue. The idea is to avoid instantiating multiple Mercurius instances. I developed an idea by looking at @mercurius-js/auth's schema filtering and pruning features. We can use the preExecution hook to change the schema on the fly for the current request. Doing that, we have just one limit. If the schemas differ, the validation is done using the original (default ) schema, and the validation step fails. We can avoid that by giving the preValidation hook the ability to change the schema like done in the preExecution hook. @mcollina @simoneb, do you think this is feasible?

Here a simple example

const app = Fastify()
const schema1 = makeExecutableSchema({
  typeDefs: ...
  resolvers: ... 
})
const schema2 = makeExecutableSchema({
  typeDefs: ...
  resolvers: ... 
})

app.register(mercurius, {
  schema: schema1,
})

app.ready(err => {
  if (err) throw err
  app.graphql.addHook('preExecution', (schema, document, context) => {

    if (context.reply.request.headers.schema === "schema2") {
      return { schema: schema2}
    }

    return { schema }
  })
})

Not sure which is the impact on loaders and jit. Do you have any clue?

mcollina commented 1 year ago

I think using the constraints is the best way to solve this. Adding support for multiple schemas in Mercurius will make the code harder to read, add a bunch if edge case we don't know about, and increase the maintenance cost.

simoneb commented 1 year ago

@mcollina sounds good, thanks for the feedback. @brainrepo let's go ahead and document this option for the time being, while we think about other options to do this. Based on Matteo's feedback, implementing support for this within mercurius may not be a compelling option, on which case we may consider building a plugin instead, which hides away the implementation details.

brainrepo commented 1 year ago

Thanks @mcollina , @simoneb . @simoneb I think I haven't the right to merge.