Best practices for GraphQL clients
Best practices for building GraphQL clients that call Indeed APIs.
Follow these best practices when you build a GraphQL client.
Request only the data that you need
GraphQL enables your client to request exactly the data it needs. Do not request fields that your client does not use.
Indeed tracks field usage to determine when a field is safe to deprecate. Requests for unused fields skew that data.
Give your GraphQL operations unique, descriptive names
Name every operation, and use Pascal case.
Descriptive names communicate the meaning and context of your operations to service implementers, which matters most during schema changes.
Check how your client library handles operation names. Some libraries assign a unique dynamic name to each invocation of the same operation, which degrades observability.
Recommended
query FetchJobForHomepageModal($id: ID) { job(id: $id) { result { title } }}Not recommended
query($id: ID) { job(id: $id) { result { title } }}Use variables for arguments in GraphQL requests
Your client can use variables to substitute different values for a literal in an operation.
Variables let you reuse an operation definition instead of rebuilding it, keep the definition readable, and avoid mishandling personally identifiable information (PII).
Variables also help the server. Without them, a GraphQL server parses and validates every permutation of the operation and cannot cache it.
Recommended
query SurveyAnswers($questionId: QuestionAnswersInput) { questionAnswers(input: $questionId) { result { answerId answerText } }}Variables
{ questionId: 124324}Not recommended
query SurveyAnswers { questionsAnswers(input: { questionId: 124324 }) { result { questionId answerId answerText } }}Use standard error codes for common errors
Use standard error codes so that API consumers can handle errors consistently.
For JVM-based languages, the graphql-exceptions library provides these error codes in the ErrorCode enum.
| Error code | Description |
|---|---|
BAD_USER_INPUT | The input parameter value is invalid. Use this error code for input validation beyond standard GraphQL Non-Null and type checks. |
FORBIDDEN | The request includes valid authentication credentials, but they do not allow the query or mutation. This error code is the GraphQL equivalent of HTTP 403 Forbidden. When you use FORBIDDEN, avoid exposing information that could enable enumeration attacks. |
INTERNAL_SERVER_ERROR | The server encounters an unexpected failure and cannot provide a response. Use this generic error only for failures that the server cannot handle. |
QUERY_TOO_COMPLEX | The query exceeds the allowed complexity for one request. |
QUERY_TOO_NESTED | The query contains too many nested levels. |
UNAUTHENTICATED | The server does not attempt the query, mutation, or field resolution because the request lacks sufficient authentication credentials. This error code is the GraphQL equivalent of HTTP 401 Unauthorized. |
Ruby on Rails clients
In Ruby on Rails, store the query in a Ruby constant. The client library takes the operation name from that constant.
If you invoke a mutation inline, the name you write does not necessarily appear in Apollo Studio:
<OperationName>{ variables....}The library allocates a dynamic name instead:
GraphQL__Client__OperationDefinition_70349176031380Store the query in a constant:
CreateOrUpdateTimePunchMutation = TimePunchCreation.queryThe library then appends the Ruby module and class names to build the operation name:
TimeBackend__ExportShiftBooking__CreateOrUpdateTimePunchMutation__CreateOrUpdateTimePunch