Skip to content

Instantly share code, notes, and snippets.

@JogoShugh
Last active November 14, 2019 19:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • 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