View on GitHub

stdn-api-guidelines

API guidelines STDN

SHOULD use cursor-based pagination [60]

When making an API request, you don’t always receive all of the results of that request in a single response. This is because some responses could contain thousands of objects, those responses should use pagination.

Cursor-based pagination is the most efficient method of paging and should be used. Cursor-based pagination works by returning a pointer to a specific item in the dataset. On subsequent requests, the server returns results after the given pointer. This method addresses the drawbacks of using offset pagination, but does so by making certain trade offs:

How to implement: As publisher of the API, use the following schema as response object (Below sample has a limit of 1):

{
    "links": {
        "next_cursor": "dXNlcnM6WCUyNzAxMDAwMTAwMDAwMDAzMDAwMDAwMzBBQ0E3MkQzMTFENTU0Rjk5RTAxQUMzNThGMkREMTdDQkNCQjYwNzQxM0JGQjQzODMwRUMxMkQ3NzE4QkJGMUE4RTI3QjhFMEExRDkzNDA5MTk4QTg5REUwMUQ4QkJCMDFFNEQxM0JFOUEyRDkwNTREQTk2QjcyMTVBNTcyRUJDOTU3MDAwMDAwNDQ1MzcwNzQwQTAwMDEwMDAwMDEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMTczMTJFMzIyRTM4MzQzMDJFMzEzMTMzMzUzNTM2MkUzMTJFMzQyRTMyMzMzMzMxMDYwMDAwMDAwMDAwMDE0QTk4NUY1NTdCQzA2ODQwQTIxRjZGODE5NjZERjgxNjAxMjQwMDAwMDAwMTAwMDAwMDAwNDcwMDAwMDAwNTAwMDAwMDAwMDAwMDJBNjE2RDM1NzI2NzcyMzE2MTY0NzIzMzM3MzQyRTY3NzI2RTMwMzAzMTJFNkQ3MzZGNzA3MjY0MkU2RDczNjY3NDJFNkU2NTc0M0EzMzMwMzAzMDMwMDEyNDAwMDAwMDAxMDAwMDAwMDAwMDAxMDAwMDAwMDAxMTAwMDAwMDAwMDAwMDAwMDAlMjc="
    },
    "data": [
        {
            "id": "3cc51257-31e4-4461-a1e4-c1bb2fd989b1",
            "firstName": "John",
            "lastName": "de Vries",
            "displayName": "John de Vries",
            "email": "john@partner.com",
            "requesterId": "12345",
            "userType": "partner",
            "companyName": "Test aannemer"
        }
    ]
}

Cursor-paginating supports the following parameters:

limit : This is the maximum number of objects that may be returned. A query may return fewer than the value of limit due to filtering. Do not depend on the number of results being fewer than the limit value to indicate that your query reached the end of the list of data, use the absence of next instead as described below. For example, if you set limit to 10 and 9 results are returned, there may be more data available, but one item was removed due to privacy filtering. Some apis may also have a maximum on the limit value for performance reasons. In all cases, the API returns the correct pagination links.

next_cursor : The endpoint that will return the next page of data. Do not decode the value of next_cursor. This value can be given directly to the API for the next page. Use for this the cursor querystring parameter. If next_cursor is an empty string, you’ve reached the last page. The value of next_cursor is a base64 string with a reference to the last record given in the result set. In the above example the id “3cc51257-31e4-4461-a1e4-c1bb2fd989b1”

Additional paramters for filtering can be added to the parameters. For example sort or fields See also ## MUST stick to conventional query parameters [89]

Example OpenAPI specification

 /:
    get:
      summary: Get electricity stations
      operationId: get-electricity-stations
      description: Returns a list of electricity stations
      parameters:
      - name: limit
        description: | 
            You can indicate the number of instances to return in each page using the limit. Limit is an integer and must be greater than 0, but smaller than 100. If no limit parameter is provided, 100 is used.
        in: query
        schema:
          type: number
          example: 20
        required: false
      - name: cursor
        description: |
            The query parameter cursor is a reference to the next page of items. The value of next_cursor in the previous response can be used. If no cursor parameter is provided means that the client is requesting the first page of items.
        in: query
        schema:
          type: string
          example: swrefVrecordVdatasetZkabelsVcollectionZe_ls_leveringspunt_priVkeysZ194722107
        required: false

MAY use offset-based pagination [90]

Offset-based pagination is a technique wherein the client requests parameters with a specific limit (the number of results) and offset (the number of records that need to be skipped). Offset-based pagination is easy to use and is preferred for static data. Only use this if the backend does not support cursor.

Offset-paginated supports the following parameters:

offset: This offsets the start of each page by the number specified.

limit: This is the maximum number of objects that may be returned. A query may return fewer than the value of limit due to filtering. Do not depend on the number of results being fewer than the limit value to indicate that your query reached the end of the list of data, use the absence of next instead as described below. For example, if you set limit to 10 and 9 results are returned, there may be more data available, but one item was removed due to privacy filtering. Some APIs also have a maximum on the limit value for performance reasons. In all cases, the API returns the correct pagination links.

next: The API will return the next page of data. If not included, this is the last page of data. Due to how pagination works with visibility and privacy, it is possible that a page may be empty but contain a next paging link. Stop paging when the next link no longer appears.

previous: The API will return the previous page of data. If not included, this is the first page of data. Note that if new objects are added to the list of items being paged, the contents of each offset-based page will change.

example openAPI spec:

  /:
    get:
      tags:
        - Pricing profile
      summary: Endpoint to get pricing profiles
      description: |-
        The pricing profiles for charging stations (determined on stedin-side) of electric vehicles are based on
        net congestion predictions in specific time range (request date from midnight 00:00 am to 48 hours ahead)
      parameters:
        - name: offset
          in: query
          required: false
          schema:
            type: integer
            minimum: 0
            default: 0
          description: The number of transformer ID's to skip before returning the results on the page.
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
           description: The number of transformer ID's (and predictions for those transformers) to return per result page.

example json response:

[
  {
    "links": {
      "next": "https://api.stedin.net/connections/v1?limit=10&offset=20",
      "previous": "https://api.stedin.net/connections/v1?limit=10&offset=0",
    },
    "data": [
      {
        "id": "964350945273"
      }
    ]
  }
]