26

I'm trying to figure out how to document two of my query parameters in OpenAPI.

Filtering

My filtering follows the recommendations of JSON:API, which takes the form of, for example:

  • ?filter[post]=1,2,3
  • ?filter[post]=1,2,3&filter[author]=5

The filter key is an associative array that can contain a set list of resource names in my API. The value assigned to each filter key is either a single id or list of comma separated ids.

Sorting

For sorting also follows the JSON:API recommendation, so something like these:

  • ?sort=age
  • ?sort=age,-height

The sort query parameter is assigned the value of one sort field or list of comma separated sort fields. Note that the minus sign that prefixes the height field indicates a descending sort.

Question

How do I represent the my filtering and sorting in OpenAPI?

For example, I'm not sure it's possible for me to specify that the filter key is an associative array, or that it accepts a comma separated list of ids. Almost the same issue for sort: how to represent a comma separated list of sort fields?

StackOverflowNewbie
  • 39,403
  • 111
  • 277
  • 441
  • Does this answer your question? [How do I express JSON-API sparse fieldsets with OpenAPI-3.0](https://stackoverflow.com/q/57808396/113116) – Helen Sep 14 '20 at 10:09
  • I'm not sure. You're only referring to filtering, right? I'll study that link more. As for the sort, I feel that I need to have `anyOf` along with some `enum` (e.g. [age, -age], [height, -height]) it's clear that sorting can be done by age ASC or age DESC, and/or height ASC or height DESC, etc. – StackOverflowNewbie Sep 15 '20 at 11:51

3 Answers3

4

The below approach should help

parameters:
  - in: query
    name: fields
    style: deepObject
    allowReserved: true
    schema:
      type: object
      properties:
        post:
          type: string
        author:
          type: string
  - in: query
    name: sort
    schema:
      type: array
      items:
        type: string
        enum:
          - age
          - height

A part of it is similar to the question that @Helen shared. It'll enable you to use it as in the below image

image1

And the respective cURL command

curl -X GET "https://editor.swagger.io/user?filter[post]=1,2&filter[author]=3,4&sort=age&sort=height" -H  "accept: */*"

You can also define the filter parameter in below way

parameters:
  - in: query
    name: filter
    style: deepObject
    allowReserved: true
    schema:
      type: object
      properties:
        post:
          type: array
          items:
            type: string
        author:
          type: array
          items:
            type: string

This will result in the UI being more comprehensive as below

image2

Then the cURL request looks as below

curl -X GET "https://editor.swagger.io/user?filter[post]=1&filter[post]=2&filter[author]=3&filter[author]=4&sort=age&sort=height" -H  "accept: */*"

And you should probably not need anyOf as it's related to inheritance for situations when a method may return an object of the base class or any of its sub-class.

Refer oneof-anyof-allof-not - OpenAPI Specification for more info on it.

Debargha Roy
  • 2,320
  • 1
  • 15
  • 34
  • 1
    Neither filter nor sort comply with the JSON:API specs. Compare the cURL request to the examples I provided. For sort, I feel that I need to express: "anyOf" [name,-name], [age,-age]. – StackOverflowNewbie Sep 24 '20 at 15:12
  • What about the first part of the answer? The one with `curl -X GET "https://editor.swagger.io/user?filter[post]=1,2&filter[author]=3,4&sort=age&sort=height" -H "accept: */*"` ? Does this also not comply with the JSON:API specs? – Debargha Roy Sep 24 '20 at 15:29
  • Filter looks right in the cURL example (not sure anymore why I said that was wrong earlier). Sort is definitely wrong. Is it possible to express: "anyOf" [name,-name], [age,-age]? – StackOverflowNewbie Sep 25 '20 at 16:10
  • If you read the specification, it clearly states the purpose of `anyOf`. It's supposed to be used with Inheritance concepts – Debargha Roy Sep 26 '20 at 09:45
  • Where does `filter[post]=1,2&filter[author]=3,4` come from in the first example's cURL command? I am trying to convert a filter value of `{ "post": [1,2], "author": [3,4] }` into this with no success. Whatever I try it gets split into `filter[post]=1&filter[post]=2&filter[author]=3&filter[author]=4`. – wedi Jan 29 '21 at 01:10
  • Compare the specification that I shared with the ones that you have. If you're using some library to generate the specification (the code-first approach), you might as well need to check and how you can get it done with the library. – Debargha Roy Jan 29 '21 at 08:22
4

This may be a bit old but I'm currently documenting an API whose sort, filter and dynamic relationship includes adheres to the JSON API spec and I just figured out how to properly document the filter query parameter. The below is written in JSON but I hope you'd be able to adapt it to fit your needs if you're writing YAML

{
    "schema": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "id": {
          "description": "Id of the user",
          "type": "string"
        },
        "referrer_id": {
          "description": "The id of the user that referred the user",
          "type": "string"
        },
        "email_verified": {
          "description": "Whether the user has verified their email address",
          "type": "boolean"
        },
        "trashed": {
          "description": "Whether the user has been soft deleted",
          "type": "string",
          "enum": [
            "with",
            "only"
          ]
        }
      }
    },
    "in": "query",
    "name": "filter",
    "description": "Really long description.........",
    "style": "deepObject",
    "explode": true,
    "allowReserved": true
  }

To document sorting, you can follow the example included here which is also written below

parameters:
  - in: query
    name: ids
    description: One or more IDs
    required: true
    schema:
      type: array
      items:
        type: integer
    style: form
    explode: false
    examples:
      oneId:
        summary: Example of a single ID
        value: [5]   # ?ids=5
      multipleIds:
        summary: Example of multiple IDs
        value: [1, 5, 7]   # ?ids=1,5,7
firstdorsal
  • 401
  • 5
  • 17
0

For sort its straight forward approach you can find syntax on official guide Open API Guide

For sorting: JSON format

"parameters": [{
    "in": "query",
    "name": "sort",
    "schema": {
        "type": "array",
        "items": {
            "type": "string"
        }
    }
}

]

YAML format

  parameters:
  - in: query
    name: "sort"
    schema:
    type: array,
    items:
      type: string