Syntax of GraphQL operations

We have already seen how to build a request to the GraphQL API from an operation. We will now detail the writing of an operation.

This page gives a very condensed overview of the GraphQL query language. For more detailed information you can consult the official documentation.

An operation consists of the following elements :

  1. the type of operation, always specified first

  2. the operation identifier, i.e. its path in the operation graph the operation

  3. variables and their values

  4. the response pattern, which allows the selection of the level of information returned by the API.

The distinction between 2 and 4 does not really exist in GraphQL, an operation being seen as the selection of a certain field in the whole graph of operations.

We will use the logActivity operation to illustrate each of these constituents :

mutation {
    activities {
        logActivity(userId: 222408790, missionId: 500, type: "work", startTime: 1616281275) {
            id
        }
    }
}

Operation type

The Mobilic API uses two types of operation defined by the GraphQL standard :

  • query for all read operations that do not modify the state of the system

  • mutation for all operations that will modify the state of the system (create, edit, delete)

The logActivity operation creates a new activity for a user, it is logically a mutation.

Operation ID

The logactivity operation has been grouped with the other activity operations. Its full path in the mutation operations is activities -> logActivity.

Operation variables

They are specified in brackets next to the relevant operation. In the case of the logActivity operation there are four variables : userId, missionId, startTime and type.

A GraphQL operation may well include variables at several nesting levels.

The GraphQL syntax allows variables to be defined inside the operation but their values to be specified outside. For example, the login operation can be written :

mutation($type: String!, $startTime: TimeStamp!, $missionId: Int!, $userId: Int) {
  activities {
    logActivity(type: $type, startTime: $startTime, missionId: $missionId, userId: $userId) {
      id
    }
  }
}

It is important to note that :

  • variables are declared just after the type of operation

  • a variable is always preceded by a $

The JSON body of the HTTP request must then contain a variables field which defines for each variable the value to be injected :

{
  "query": "mutation logActivity($type: String!, $startTime: TimeStamp!, $missionId: Int!, $userId: Int) {\n  activities {\n logActivity(\n type: $type\n startTime: $startTime\n missionId: $missionId\n userId: $userId\n ) {\n id}}\n}\n"
  "variables": { "type": "work", "startTime": 1616281275, "missionId": 500, "userId": 222408790}
}

Schema of response

This is a very powerful feature of GraphQL : the ability to customize the API response among the graph of objects.

For example, for the logActivity operation, we can only ask for the identifier of the created activity in return :

mutation {
    activities {
        logActivity(userId: 222408790, missionId: 500, type: "work", startTime: 1616281275) {
            id
        }
    }
}

The body of the response will be in JSON format, and will follow the schema of the request, as defined in the GraphQL specifications. In the previous example the JSON return will contain a data field (always present in the case of a query without errors), containing an auth field which itself contains a login field and so on :

{
  "data": {
    "activities": {
      "logActivity": {
        "id": 1608
      }
    }
  }
}

This operation makes sense for complex objects with a high level of overlap : for example, a company, to which users are attached, who carry out missions, which themselves group together several activities. Depending on its needs, the caller is free to retrieve a graph of objects of varying depth.

Last updated