GraphQL documentation authoring best practices

Here we have provided best-practice guidelines on how to write API documentation. While these recommendations are mostly aimed at Totara developers writing core APIs, following these guidelines will make any third-party services consistent with the rest of the platform.

For more technical information on how to actually implement the documentation in code, see Extending API documentation.

Style

For Totara developers, use a writing style that is consistent with Totara's internal style guide.

Write schema documentation for the intended audience of a third-party developer integrating with a Totara instance, not the Totara administrator.

When the in-product term for a feature or object is different from its name in source code, use the in-product term. For example, "audience" not "cohort".

Document all aspects of the API schema

Provide complete documentation on all parts of the schema including:

  • Queries and their arguments
  • Mutations and their arguments
  • Input and object types
  • Each individual field within an object, including their arguments
  • Enums and their values
  • Scalars
  • Interfaces
  • Unions

Reference type descriptions

Use of reference types is encouraged to provide flexibility to the API user. When defining reference types, keep the following in mind.

The description should describe which combination of fields are required to uniquely identify an object of that type. For example:

You must provide either an id or both instancetype and instanceid to uniquely identify a single record.

It should also also describe any additional filtering that might be applied when identifying the object. For example, the core_user_user_reference type excludes deleted users and users from other tenants if the requesting user is a tenant member. This is important information that will impact the behaviour of the reference type, so should be called out in the type description.

Default values

In some cases you might specify the default value for an input property in the schema, but in other cases it is preferable to make the input property optional without specifying a schema default (for example, if the default value is not fixed but dependent on business logic defined within the application).

In these cases, specify in the description what the default value will be (and, if necessary, how it will be determined). For example, the city property of the core_user_create_user_input type says:

City where the user is located. If not provided the system will use the admin setting 'defaultcity' if set.

Impact of configuration settings on behaviour

In some cases, the system's behaviour can be different depending on factors that can vary on a case-by-case basis, such as site configuration, the data in the database, the server environment, or the viewing user. Where possible, include information about how these factors can impact API behaviour in the documentation.

For example, the timezone property of the core_user type says:

Timezone of the user, as a string, for example 'Pacific/Auckland'.

Note that if the admin setting 'forcetimezone' is configured, its value will be used here instead.

Provide examples of valid data for input types

It can be very helpful to provide examples of one or more valid values, in order to make it clearer how to structure a request. This can be helpful to include in the documentation for queries and mutations, even if more details are provided in an input or result type.

For example, the lang property of the core_user type says:

Language of the user, for example 'en_us'. Valid options depend on the site's installed language packs.

Deprecate APIs when appropriate

See Changes to the GraphQL APIs for information on when we use deprecation and GraphQL API deprecation process for details on how to do it.

Provide specific and useful comments

Try to avoid giving superfluous comments that simply mirror the name of the item itself, e.g.:

 """ Widget type """
type widget {
  """ widget id """
  id: core_id!
  """ widget name """
  name: String!
}

Instead, imagine yourself in the shoes of someone coming across the type out of context and wanting to understand the purpose of that particular type. Explain anything that isn't obvious that might be useful for that person. A better description might be:

 """ Widgets are objects which represent something that the customer needs to track. """
type widget {
  """ Unique internal database identifier for a single widget """
  id: core_id!
   """ User-provided name used to identify the widget in the interface. Max 255 characters and must be unique. """
  name: String! 
}

Common patterns

There are some things we repeat often in documentation, so where possible, reuse the styles here for consistency:

When describing an admin setting, use the syntax "admin setting '<settingname>'", for example:

will use the admin setting 'forcetimezone' if enabled

When describing a description field that can accept HTML or other formatted content, call it a 'Rich-text description field', for example:

Rich-text description of the framework.

When describing a descriptionformat field (the integer we use to identify the format of a rich-text field), describe it as 'Format of the <name> field, as stored in the database.', for example:

Format of the description field, as stored in the database.

When describing an id field, describe it as 'Internal database id of the <type>.', for example:

Internal database id of the position.

When describing an idnumber field, describe it as 'Unique reference used to represent the <type> across multiple systems.', for example:

Unique reference used to represent the position across multiple systems.

Additional recommendations

The following are some additional recommendations about how to format schema documentation. While these style points are recommended, they are not blockers, so we need to be careful not to prioritise easy-to-notice but non-critical fixes over review feedback that will make a significant difference to documentation users.

  • We recommend full stops at the end of sentences.
  • Comments can use single- or multi-line comment syntax (separate lines for triple quotes, or all on one line).
  • Capitalise acronyms, e.g. 'SCORM' not 'scorm'.
  • We use 'id' rather than 'ID'.
  • In general, try to use full English with prepositions, joining words, etc.
  • Include comments for input types, even when the type itself has its own comment. Focus on the overall purpose of the argument in this comment and leave detail for within the input type.
  • Be consistent with tenses: use the present tense describing something currently happening.

See the /wiki/spaces/TEAM/pages/116686875 (internal documentation) for more information.