Task 07 — Add Pagination to an Existing API
Difficulty: Intermediate
Goal: Extend an existing list endpoint (e.g. the users list) to support cursor-based or offset-based pagination.
What you'll learn
- How to handle
page/limitquery parameters in a Flask-RESTX route - How to write a Cosmos DB query with
OFFSET … LIMITor a continuation token - How to return pagination metadata alongside data
Endpoint spec
Extend your task-03 endpoint (or build a new one) to accept:
| Param | Type | Default | Description |
|---|---|---|---|
page | int | 1 | Page number (1-indexed) |
limit | int | 20 | Items per page (max 100) |
Response shape:
{
"status": "success",
"status_code": 200,
"data": {
"items": [ ... ],
"page": 1,
"limit": 20,
"total": 142,
"totalPages": 8
}
}
Implementation notes
Query with OFFSET / LIMIT in Cosmos DB
Cosmos DB SQL supports OFFSET … LIMIT natively. ORDER BY must always be included — without it the page order is non-deterministic.
The existing get_all_users_of_industry(industry_id) returns id, username, type, active. Add a paginated variant alongside it:
@staticmethod
@validate_values()
def get_users_paginated(industry_id, offset, limit):
return (
f'SELECT c.id, c.username, c.type, c.active FROM c '
f'WHERE c.industryId = "{industry_id}" '
f'ORDER BY c._ts DESC OFFSET {offset} LIMIT {limit}'
)
Count query
@staticmethod
@validate_values()
def count_users_by_industry(industry_id):
return f'SELECT VALUE COUNT(1) FROM c WHERE c.industryId = "{industry_id}"'
User types
Users have a type field — DEFAULT, OTP, SSO, or microsoft. The existing service counts users by summing OTP + SSO counts via separate queries. For pagination you can query all types together with a single industryId filter.
Route changes
page = int(request.args.get('page', 1))
limit = min(int(request.args.get('limit', 20)), 100) # cap at 100
offset = (page - 1) * limit
Edge cases to handle
page=0or negative → return400with a clear messagelimit > 100→ clamp to 100 (don't error, just cap)- Page beyond total → return empty
itemslist, not an error
Done when
-
?page=1&limit=5returns the first 5 items -
?page=2&limit=5returns items 6–10 -
totalPagesis calculated correctly - Invalid
page=0returns a400response