Skip to content

GraphQL Endpoints

Derek Clarkson edited this page Nov 19, 2022 · 2 revisions

In principle matching GraphQL queries with responses works the same as processing RESTful API requests. However there are some differences due to the nature of GraphQL.

As GraphQL uses a single HTTP path rather than multiple like REST does, GraphQL endpoints do not use a method/path signature to select a response. Instead they use a method/selector signature where the method is either 'GET' or 'POST' as per the GraphQL standard for HTTP queries, and the selector is either an operations or query selector.

XCTest

Here is an example of specifying a GraphQL endpoint in an XCTest:

GraphQLEndpoint(.GET, .operations("getConfig"), response: .ok(body: .json(["featureFlag": true])))

YAML

And here is an example from a YAML config file:

graphQL:
  method: get
  operations: getConfig
  response:
    status: 200
    body:
      json:
        featureFlag: true

Selectors

Operation selectors

Operation selectors work by examining the operation names in incoming query and matching them against a list of supplied operation names. If all the supplied operation names exist in the incoming query then it's a match. For example:

Incoming query Swift API selector YAML selector Match
query empireHeros {
  hero(episode: EMPIRE) {
    name
  }
}
query jediHeros {
  hero(episode: JEDI) {
    name
  }
}
.operations("starTrekHero")
operations: starTrekHero
No
.operations("jediHero")
operations: jediHero
Yes
.operations("jediHero", "empireHero")
operations: 
  - jediHero
  - empireHero
Yes
.operations("jediHero", "empireHero", "starTrekHero")
operations: 
  - jediHero
  - empireHero
  - starTrekHero
No

Query selectors

The other way to match an incoming GraphQL query is to write a GraphQL query that matches it. Basically it's like using a query on a query. If the query is a subset of the incoming query in terms of names and fields, then it is considered to be a match and the corresponding response will be returned. For example:

Incoming query Swift API selector YAML selector Match
query empireHeros {
  hero(episode: EMPIRE) {
    name
    rank
  }
}
query jediHeros {
  hero(episode: JEDI) {
    name
    rank
  }
}
.query("""
    query jediHeros {
      hero(episode: JEDI) {
        name
      }
    }
    """)
graphQL
  method: get
  query: |
    query jediHeros {
      hero(episode: JEDI) {
        name
      }
    }
Yes
.query("query { hero { name }}")
graphQL
  method: get
  query: query { hero { name }}
Yes
.query("query jediHeros { hero { name rank }}")
graphQL
  method: get
  query: query jediHeros { hero { name rank }}
Yes
.query("query jediHeros { hero { name age }}")
graphQL
  method: get
  query: query jediHeros { hero { name age }}
No
.query("query { villain { name }}")
graphQL
  method: get
  query: query { villain { name }}
No

Responses

GraphQL has the same range of responses that RESTful HTTP requests have using the same values. Generally this will be JSON responses as that is how GraphQL works. However any other type of response can be generated.

Please see the Endpoint responses document for an outline of how to specify the response for an endpoint.

Clone this wiki locally