Skip to content

Instantly share code, notes, and snippets.

@JogoShugh
Last active November 14, 2019 19:52
Show Gist options
  • Save JogoShugh/260dbd5df6385fc855cffc44e219b0b3 to your computer and use it in GitHub Desktop.
Save JogoShugh/260dbd5df6385fc855cffc44e219b0b3 to your computer and use it in GitHub Desktop.
Api with next / prev links

Inspired by:

https://developer.atlassian.com/server/confluence/pagination-in-the-rest-api/ https://stackoverflow.com/questions/13872273/api-pagination-best-practices

The following command returns everything available, 47 results in this case:

Note: there's a default page size of 1000, which is why the next and prev have the same values in this case, though we might just strip the parameters out when everything is visible

$ curl "http://localhost/VersionOne.Web/api/asset/data/BaseAsset?select=AssetType" -u admin:admin
{
  "_links": {
    "next": "http://localhost/VersionOne.Web/api/asset/data/BaseAsset?select=AssetType&page=1000%2c0",
    "prev": "http://localhost/VersionOne.Web/api/asset/data/BaseAsset?select=AssetType&page=1000%2c0",
    "self": "http://localhost/VersionOne.Web/api/asset/data/BaseAsset?select=AssetType"
  },
  "queryResult": {
    "results": [
      {
        "_oid": "Scope:0",
        "AssetType": "Scope"
      },
      {
        "_oid": "Member:20",
        "AssetType": "Member"
      },
      {
        "_oid": "Topic:302",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:303",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:304",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:305",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:306",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:307",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:308",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:309",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:321",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:322",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:323",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:324",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:325",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:326",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:328",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:329",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:331",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:332",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:333",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:334",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:335",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:336",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:337",
        "AssetType": "Topic"
      },
      {
        "_oid": "Schedule:1000",
        "AssetType": "Schedule"
      },
      {
        "_oid": "Scope:1003",
        "AssetType": "Scope"
      },
      {
        "_oid": "Timebox:1004",
        "AssetType": "Timebox"
      },
      {
        "_oid": "Story:1006",
        "AssetType": "Story"
      },
      {
        "_oid": "Story:1007",
        "AssetType": "Story"
      },
      {
        "_oid": "Story:1008",
        "AssetType": "Story"
      },
      {
        "_oid": "Defect:1009",
        "AssetType": "Defect"
      },
      {
        "_oid": "Defect:1010",
        "AssetType": "Defect"
      },
      {
        "_oid": "Defect:1011",
        "AssetType": "Defect"
      },
      {
        "_oid": "Defect:1012",
        "AssetType": "Defect"
      },
      {
        "_oid": "Defect:1013",
        "AssetType": "Defect"
      },
      {
        "_oid": "Defect:1014",
        "AssetType": "Defect"
      },
      {
        "_oid": "Defect:1015",
        "AssetType": "Defect"
      },
      {
        "_oid": "Defect:1016",
        "AssetType": "Defect"
      },
      {
        "_oid": "Defect:1017",
        "AssetType": "Defect"
      },
      {
        "_oid": "Task:1018",
        "AssetType": "Task"
      },
      {
        "_oid": "Task:1019",
        "AssetType": "Task"
      },
      {
        "_oid": "Test:1020",
        "AssetType": "Test"
      },
      {
        "_oid": "Test:1021",
        "AssetType": "Test"
      },
      {
        "_oid": "Scope:1022",
        "AssetType": "Scope"
      },
      {
        "_oid": "Scope:1024",
        "AssetType": "Scope"
      },
      {
        "_oid": "Member:1025",
        "AssetType": "Member"
      }
    ],
    "count": 47
  },
  "requestId": "886e3a90-0e07-4b33-a257-07d94292252c",
  "createdDate": "2019-11-14T19:41:52.2598314Z",
  "completedDate": "2019-11-14T19:41:52.2778332Z",
  "duration": "00:00:00.0180018",
  "durationSeconds": 0.0180018,
  "complete": true,
  "processing": false
}

Now, let's give a page size of 2:

$ curl "http://localhost/VersionOne.Web/api/asset/data/BaseAsset?select=AssetType&page=2" -u admin:admin
{
  "_links": {
    "next": "http://localhost/VersionOne.Web/api/asset/data/BaseAsset?select=AssetType&page=2%2c2",
    "prev": "http://localhost/VersionOne.Web/api/asset/data/BaseAsset?select=AssetType&page=2%2c0",
    "self": "http://localhost/VersionOne.Web/api/asset/data/BaseAsset?select=AssetType&page=2"
  },
  "queryResult": {
    "results": [
      {
        "_oid": "Scope:0",
        "AssetType": "Scope"
      },
      {
        "_oid": "Member:20",
        "AssetType": "Member"
      }
    ],
    "count": 2
  },
  "requestId": "c8b97e25-eeec-4778-96d6-e7514653eb7d",
  "createdDate": "2019-11-14T19:42:39.1190906Z",
  "completedDate": "2019-11-14T19:42:39.1231245Z",
  "duration": "00:00:00.0040339",
  "durationSeconds": 0.0040339,
  "complete": true,
  "processing": false
}

Notice the kind of ugly URLs in the _links property, but it's valid as input, like this:

$ curl "http://localhost/VersionOne.Web/api/asset/data/BaseAsset?select=AssetType&page=2%2c2" -u admin:admin
{
  "_links": {
    "next": "http://localhost/VersionOne.Web/api/asset/data/BaseAsset?select=AssetType&page=2%2c4",
    "prev": "http://localhost/VersionOne.Web/api/asset/data/BaseAsset?select=AssetType&page=2%2c0",
    "self": "http://localhost/VersionOne.Web/api/asset/data/BaseAsset?select=AssetType&page=2%2c2"
  },
  "queryResult": {
    "results": [
      {
        "_oid": "Topic:302",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:303",
        "AssetType": "Topic"
      }
    ],
    "count": 2
  },
  "requestId": "c752095c-f44f-4500-9deb-f9d075a75ac0",
  "createdDate": "2019-11-14T19:43:13.7780393Z",
  "completedDate": "2019-11-14T19:43:13.8010709Z",
  "duration": "00:00:00.0230316",
  "durationSeconds": 0.0230316,
  "complete": true,
  "processing": false
}

And, we go to 2,4:

$ curl "http://localhost/VersionOne.Web/api/asset/data/BaseAsset?select=AssetType&page=2,4" -u admin:admin
{
  "_links": {
    "next": "http://localhost/VersionOne.Web/api/asset/data/BaseAsset?select=AssetType&page=2%2c6",
    "prev": "http://localhost/VersionOne.Web/api/asset/data/BaseAsset?select=AssetType&page=2%2c2",
    "self": "http://localhost/VersionOne.Web/api/asset/data/BaseAsset?select=AssetType&page=2%2c4"
  },
  "queryResult": {
    "results": [
      {
        "_oid": "Topic:304",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:305",
        "AssetType": "Topic"
      }
    ],
    "count": 2
  },
  "requestId": "74ceb747-71f7-4dda-b672-f72ca1b58e85",
  "createdDate": "2019-11-14T19:43:57.8357649Z",
  "completedDate": "2019-11-14T19:43:57.8617682Z",
  "duration": "00:00:00.0260033",
  "durationSeconds": 0.0260033,
  "complete": true,
  "processing": false
}

If you compare each set of results to the original, you'll see it should be stepping properly:

First 6:

[
      {
        "_oid": "Scope:0",
        "AssetType": "Scope"
      },
      {
        "_oid": "Member:20",
        "AssetType": "Member"
      },
      {
        "_oid": "Topic:302",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:303",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:304",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:305",
        "AssetType": "Topic"
      }
 ]

First 2:

[
      {
        "_oid": "Scope:0",
        "AssetType": "Scope"
      },
      {
        "_oid": "Member:20",
        "AssetType": "Member"
      }
]

Second page of 2:

[
      {
        "_oid": "Topic:302",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:303",
        "AssetType": "Topic"
      }
]

Third page of 2:

[
      {
        "_oid": "Topic:304",
        "AssetType": "Topic"
      },
      {
        "_oid": "Topic:305",
        "AssetType": "Topic"
      }
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment