v5 (latest)FeaturesRequest Customization

Request Customization

For each type of request, GraphQL Yoga uses a specific parser to parse the incoming request and extract the GraphQL operation from it. Then it applies some validation logic to the extracted object, then it passes it to the GraphQL execution engine. Yoga mostly follows GraphQL-over-HTTP standards for this validation and parsing logic. See the GraphQL-over-HTTP compliance test results of GraphQL Yoga

The parsers are expected to return GraphQLParams object that contains the following properties:

  • query: The GraphQL operation as a string.
  • variables: The variables for the operation.
  • operationName: The name of the operation.
  • extensions: The extensions for the operation.

It doesn’t matter how the request is sent, Yoga engine expects the request to parsed in the form of a GraphQLParams object.

Request Parser

Request parsers are responsible for extracting the GraphQL operation and the other relevant information from the incoming request. Each parser is responsible for a specific type of request based on the content type and the HTTP method.

GraphQL-over-HTTP Spec

These parsers are implemented following the GraphQL-over-HTTP spec.

GET Parser

This request parser extracts the GraphQL operation from the query string by following GraphQL-over-HTTP spec.

See the implementation See the relevant part in GraphQL-over-HTTP spec

Example Request
fetch('/graphql?query=query { __typename }')

POST JSON Parser

This request parser extracts the GraphQL operation from the JSON body of the POST request by following GraphQL-over-HTTP spec.

See the implementation.

Example Request
fetch('/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    query: 'query { __typename }'
  })
})

GraphQL Multipart Request Spec

The parser for multipart requests is implemented following the GraphQL Multipart Request Spec.

POST Multipart Parser

This request parser extracts the GraphQL operation from the multipart request by following the GraphQL Multipart Request Spec. It handles the HTTP request by parsing it as multipart/form-data and extracting the GraphQL operation from it.

See the implementation.

Example Request
const formData = new FormData()
formData.append('operations', JSON.stringify({ query: 'query { __typename }' }))
fetch('/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'multipart/form-data'
  },
  body: formData
})

Extra Parsers

These parsers are not part of any spec but are de-facto standards in the GraphQL community.

POST GraphQL String Parser

This request parser extracts the GraphQL operation from the body of the POST request as a string.

See the implementation.

Example Request
fetch('/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/graphql'
  },
  body: 'query { __typename }'
})

POST FormUrlEncoded Parser

This request parser extracts the GraphQL operation from the form data as url encoded in the POST body. The context is similar to the GET parser but the data is sent in the body of the request.

See the implementation

Example Request
fetch('/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  body: 'query=query { __typename }'
})

Write your own parser

If you want to handle a specific type of request body that is not part of the list above, you can write your own parser. We use onRequestParse to hook into the request parsing process and add your own logic.

Request parsers are functions that take the request object and return a promise that resolves to a GraphQLParams object.

import { GraphQLParams, Plugin } from 'graphql-yoga'
 
const useMyParser: Plugin = () => {
  return {
    onRequestParse({ request, url, setRequestParser }) {
      const contentType = request.headers.get('Content-Type')
      if (contentType === 'application/my-content-type') {
        setRequestParser(async function myParser() {
          const body = await request.text()
          const params: GraphQLParams = getParamsFromMyParser(body)
          return params
        })
      }
    }
  }
}

Request Validation

Request validation is the process of validating the incoming request to ensure that it follows the GraphQL-over-HTTP spec. Besides the required validation rules, Yoga applies some extra rules to ensure the security and the performance of the server such as disallowing extra paramters in the request body. However, you can customize this kind of behaviors on your own risk.

Extra Parameters in GraphQLParams

Yoga doesn’t allow extra parameters in the request body other than query, operationName, extensions, and variables. And it returns a 400 HTTP error if it finds any extra parameters. But you can customize this behavior by passing an array of extra parameter names to the extraParamNames option.

import { createYoga } from 'graphql-yoga'
 
const yoga = createYoga({
  /* other options */
  extraParamNames: ['extraParam1', 'extraParam2']
})

Then you can send extra parameters in the request body.

const res = await yoga.fetch('/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    query: 'query { __typename }',
    extraParam1: 'value1',
    extraParam2: 'value2'
  })
})
 
console.assert(res.status === 200)