GraphQL in practice

GraphQL in practice

The SEEK API’s GraphQL endpoint is served over HTTP. GraphQL is not tied to a certain programming language or client library; as long as you can make HTTP requests, you can integrate with the SEEK API.

Requests and responses

You can send any GraphQL operation that you see on this site or create in the Playground as an HTTP POST request. This works with any HTTP client that you already use and are familiar with. The following examples include tracing headers per our development & debugging documentation.
A simple query can be bundled into a JSON request body like so:
RequestResponse
Copy
POST https://graphql.seek.com/graphql HTTP/1.1
Authorization: Bearer PARTNER_TOKEN_HERE
Content-Type: application/json
User-Agent: example-application/1.2.3
X-Request-Id: a9e3d78d-576d-470b-b1d2-52f4921be25c
X-Session-Id: b5a8774c-c450-4906-a25c-861bce129106
{
  "query": "{ version }"
}
If your operation has arguments, they must be parameterised with variables. This is analogous to SQL prepared statements and prevents code injection .
RequestResponse
Copy
POST https://graphql.seek.com/graphql HTTP/1.1
Authorization: Bearer PARTNER_TOKEN_HERE
Content-Type: application/json
User-Agent: example-application/1.2.3
X-Request-Id: 6837f359-0335-418c-80dc-9d98a57a330c
X-Session-Id: b5a8774c-c450-4906-a25c-861bce129106
{
  "query": "query($id: String!) { hiringOrganization (id: $id) { name } }",
  "variables": {
    "id": "seekAnzPublicTest:organization:seek:93WyyF1h"
  }
}
See the official GraphQL documentation for more details.

Client libraries and tools

While the SEEK API works fine with plain old HTTP clients, you can make the most of it with the GraphQL ecosystem.
  • GraphQL client libraries make it easier to compose and run GraphQL operations.
    They are available in a variety of popular languages, including C#, Go, Java and JavaScript.
  • GraphQL code generators automatically generate models and types in your language from the SEEK API’s schema.
    The SEEK API validates responses against its own schema at runtime, so you should never receive a non-conforming response.

Request batching

The SEEK API provides a couple of ways to batch multiple operations in a single request. This may be desirable to reduce HTTP overhead in certain scenarios, like processing a batch of events received via webhook.
There are a couple of caveats, however:
  1. Higher response latency can be expected as a batch is constrained by its slowest operation.
  2. Operations are not processed atomically across the batch, so you’ll need to handle partial failures.

GraphQL field-based batching

GraphQL has native support for bundling multiple fields into a single operation:
QueryVariables
query($id: String!) {
  # first query field
  hiringOrganization(id: $id) {
    name
  }
  # second query field
  version
}
This approach has the following characteristics:
  • Queries and mutations cannot be combined in a request.
  • Queries are executed concurrently.
  • Mutations are executed sequentially .
    This can be useful to avoid race conditions when applying multiple changes to an object, like updating both the contacts and status of a given position opening.
  • Broad support in GraphQL client libraries as it’s part of the specification .

HTTP request-based batching

The SEEK API also lets you pack multiple operations into the request body. The response body will contain an array of results in the same order.
JSON
Copy
[
  {
    "query": "query($id: String!) { hiringOrganization (id: $id) { name } }",
    "variables": {
      "id": "seekAnzPublicTest:organization:seek:93WyyF1h"
    }
  },
  {
    "query": "{ version }"
  }
]
This approach has the following characteristics:
  • Queries and mutations can be combined in a request.
  • Queries are executed concurrently.
  • Mutations are executed concurrently.
    This can be useful to speed up independent operations, like uploading two separate candidates.
  • Limited support in GraphQL client libraries.

Request caching

Some GraphQL client libraries support client-side caching and may even enable it by default. For example, the Apollo Client for JavaScript prescribes an in-memory cache that assumes each object has a unique id or _id string field.
Such heuristics may not work well with the SEEK API, which uses a non-primitive object identifier and various field names from the HR-JSON standard:
JSON
Copy
{
  "profileId": {
    "value": "seekAnzPublicTest:candidateProfile:apply:7DtW6Q68gk2R4okNGhvg1Y"
  }
}
We recommend that you disable client-side caching for machine-to-machine requests. For requests that originate from a browser or mobile app, client libraries like Apollo Client may allow you to customise the cache , or turn it off:
TypeScript
Copy
new ApolloClient({
  defaultOptions: {
    query: {
      fetchPolicy: 'no-cache',
    },
    watchQuery: {
      fetchPolicy: 'no-cache',
    },
  },
});

Request limits

  1. Operations should not select an overly-expensive set of response fields.
    The SEEK API exposes an interconnected graph of objects, so it’s possible to ask for a deeply nested fields and/or a large number of fields. Requests that are deemed too expensive will be blocked. This limit is in place to prevent denial of service attacks; you shouldn’t bump into it in regular use.
  2. A batched request may contain up to 10 items.
    This matches the maximum number of events that we will send to your software in a single webhook. Requests that contain more than 10 items will be blocked.
  3. The events query should not be polled for new events more than once a minute.
    Webhooks should be used if you require low latency or deal with high volumes.