# Proactive Feedback

GraphQL servers usually do not offer good contextual information when running queries, because the GraphQL spec does not force them (or even suggest) to do so. This is evident concerning deprecations, where deprecation data is shown only through introspection, by querying fields isDeprecated and deprecationReason on the Field and Enum types:

{
  __type(name: "Account") {
    name
    fields {
      name
      isDeprecated
      deprecationReason
    }
  }
}

The response will be:

{
  "data": {
    "__type": {
      "name": "Account",
      "fields": [
        {
          "name": "id",
          "isDeprecated": false,
          "deprecationReason": null
        },
        {
          "name": "surname",
          "isDeprecated": true,
          "deprecationReason": "Use `personSurname`"
        },
        {
          "name": "personSurname",
          "isDeprecated": false,
          "deprecationReason": null
        }
      ]
    }
  }
}

However, when running a query involving a deprecated field, like this one:

query GetSurname {
  account(id: 1) {
    surname
  }
}

...the deprecation information will not appear in the response:

{
  "data": {
    "account": {
      "surname": "Owens"
    }
  }
}

This means that the developer executing the query must actively execute introspection queries to find out if the schema was upgraded and any field deprecated. That may happen maybe once in a long while? Quite possibly never?

# Providing proactive feedback

GraphQL by PoP addresses this deficiency by making usie of the wildcard top-level entry extensions, which allows to extend the protocol as needed. Under this entry, when running any query, GraphQL by PoP may send data through the following feedback entries:

  • deprecations
  • warnings
  • logs

Because they are sent on the response to the query itself, and not just during introspection, this data is valuable to developers of the API-consuming application to understand how to better interact with the API.

Let's explore these entries.

# Deprecations

Deprecations are returned in the same query involving deprecated fields, and not only when doing introspection.

For instance, running this query:

query {
  posts {
    title
    isPublished
  }
}

...produces response:

{
  "extensions": {
    "deprecations": [
      {
        "message": "Use 'isStatus(status:published)' instead of 'isPublished'",
        "extensions": {
          ...
        }
      }
    ]
  },
  "data": {
    "posts": [
      ...
    ]
  }
}
View PQL query
/?query=
  posts.
    title|
    isPublished

[View query results]

# Warnings

Warning are issues which can be considered non-blocking, i.e. they enhance the query but do not break it. While in standard GraphQL they would be considered errors, GraphQL by PoP takes a more lenient approach towards them, by ignoring their execution only, and not the whole query.

For instance, passing parameter limit with the wrong type will not stop execution of the query, it will just ignore this parameter (hence, the response will bring more results that are needed, but that's not a breaking issue) and provide an appropriate warning message.

Executing this query:

query {
  posts(limit:3.5) {
    title
  }
}

...produces this response:

{
  "extensions": {
    "warnings": [
      {
        "message": "For field 'posts', casting value '3.5' for argument 'limit' to type 'int' failed, so it has been ignored",
        "extensions": {
          ...
        }
      }
    ]
  },
  "data": {
    "posts": [
      ...
    ]
  }
}
View PQL query
/?query=
  posts(limit:3.5).
    title

[View query results]

# Logs

Any resolver (for fields and directives) can log any piece of information, as to provide the developer with useful information to debug the application.

Showing logs in the response

Logs are retrieved by passing parameter actions[]=show-logs to the GraphQL endpoint /api/graphql/.

In this query, directive @traceExecutionTime informs the execution time of resolving the field through the log:

query {
  post(id:1) {
    title @traceExecutionTime
  }
}

Showing logs in the response

This query calls the GraphiQL client with parameter show_logs=true, and then GraphiQL sets actions[]=show-logs on the endpoint.

View PQL query
/?
actions[]=show-logs&
postId=1&
query=
  post(id:$postId).
    title<traceExecutionTime>

[View query results]

Last Updated: 4/20/2020, 1:48:55 PM