dulnan / nuxt-graphql-middleware

GraphQL in the backend, fetch in the frontend. With TypeScript support.
https://nuxt-graphql-middleware.dulnan.net
MIT License
57 stars 11 forks source link

feat: client options and client context #45

Closed dulnan closed 1 week ago

dulnan commented 3 weeks ago

This introduces a new feature called "client options". It should make it easier to pass context information from within the Nuxt app to the GraphQL middleware on the server.

A common use case is to pass the current language along with every request to the middleware.

Currently to achieve the same you'd have to set fetchOptions via useGraphqlState() in a plugin by setting additional query params on the outgoing request.

New graphqlMiddleware.clientOptions.ts file

Similar to the existing serverOptions file, this new file can be used to define options that are used for everything non-server/nitro related. Currently a single method can be implemented called buildClientContext.

buildClientContext()

import { defineGraphqlClientOptions } from 'nuxt-graphql-middleware/dist/runtime/clientOptions'

export default defineGraphqlClientOptions<{
  language: string
  country: string
}>({
  buildClientContext() {
    const language = useCurrentLanguage()
    const country = useCurrentCountry()
    return {
      language: language.value,
      country: country.value,
    }
  },
})

This method should return an object with both string properties and values. Whenever a request to the middleware is made, this method is called and the object is passed along via query parameters:

const data = await useGraphqlQuery('loadProduct', {
  id: '123',
})

The resulting request URL:

/api/graphql_middleware/loadProduct?id=123&__gqlc_language=en&__gqlc_country=US

On the server, these query params are then extracted and converted back to an object with the same properties as returned in buildClientContext().

This context object is then passed to all serverOptions methods:

import { defineGraphqlServerOptions } from 'nuxt-graphql-middleware/dist/runtime/serverOptions'

export default defineGraphqlServerOptions({
  graphqlEndpoint(event, operation, operationName, context) {
    // Use the language from the client context.
    const language = context?.client?.language || 'en'
    return `http://backend_server/${language}/graphql`
  },
})