GraphQL over HTTP

GraphQL over HTTP


Pioneer is a GraphQL over HTTP spec compliant server implementation (opens in a new tab)

GraphQL spec define how a GraphQL operation is supposed to be performed through HTTP. The spec specify that operations can be done through either GET and POST request. Both of these are supported by Pioneer.

HTTP Strategy

Pioneer have a feature to specify how operations can be handled through HTTP. There are situations where a GraphQL API should not perform something like mutations through HTTP GET, or the user of the library preffered just using HTTP POST for all operations (excluding subscriptions).

HTTPStrategy (opens in a new tab) is a enum that can be passed in as one of the arguments when initializing Pioneer to specify which approach you prefer.

let server = Pioneer(
    httpStrategy: .csrfPrevention

Here are the available strategies:

onlyPost-Query Mutation
onlyGetQuery Mutation-
queryOnlyGetQueryQuery Mutation
mutationOnlyPostQuery MutationMutation
csrfPreventionQuery*Query Mutation
bothQuery MutationQuery Mutation

*: Apollo's CSRF and XS-Search prevention (opens in a new tab) is enabled. More here



Cross-Origin Resource Sharing (CORS) is an HTTP-header-based protocol that enables a server to dictate which origins can access its resources. Put another way, your server can specify which websites can tell a user's browser to talk to your server, and precisely which types of HTTP requests are allowed.

Any CORS middleware should be applied before Pioneer take effect.

CSRF and XS-Search

When enabling any CORS policy, usually the browser will make an additional request before the actual request, called the preflight request with the method of OPTIONS. These preflight request provide headers that describe the kind of request that the potentially untrusted JavaScript wants to make. Your server returns a response with Access-Control-* headers describing its policies (as described above), and the browser uses that response to decide whether it's OK to send the real request.

However, the browser may not send these preflight request if the request is deemed "simple". While your server can still send back Access-Control-* headers and let the browser know to hide the response from the problematic JavaScript, it is very likely that the GraphQL server had already executed the GraphQL operations from that "simple" request and might performed unwanted side-effects (Called the Cross Site Request Forgery).

To avoid CSRF (and also XS-Search attacks), GraphQL servers should refuse to execute any operation coming from a browser that has not "preflighted" that operation.

Enabling CSRF and XS-Search Prevention

Pioneer uses the same mechanic to prevent these types of attacks as Apollo Server (opens in a new tab), described here (opens in a new tab).

If you set the http strategy to .queryOnlyGet or .onlyPost and as long as you ensure that only mutations can have side effects, you are somewhat protected from the "side effects" aspect of CSRFs even without enabling CSRF protection.

To enable it, just change the HTTPStrategy to .csrfPrevention (opens in a new tab), which will add additional restrictions to any GraphQL request going through HTTP.

let server = Pioneer(
    httpStrategy: .csrfPrevention


While this mechanic is recommended to improve your server security, there is a couple consideration to be take account of.

It should have no impact on legitimate use of your graph except in these two cases:

  • You have clients that send GET requests and are not Apollo Client Web, Apollo iOS, or Apollo Kotlin
  • You implemented and have enabled file uploads through your GraphQL server using multipart/form-data.

If either of these apply to you and you want to keep the prevention mechanic, you should configure the relevant clients to send a non-empty Apollo-Require-Preflight header along with all requests.

GraphQL over HTTP spec compliance

As of Pioneer v1, Pioneer is spec compliant with the GraphQL over HTTP spec (opens in a new tab).

Details on compliance (opens in a new tab)

  • 78 audits in total
  • 75 pass
  • ⚠️ 3 warnings (optional)
Last updated on October 28, 2023