Skip to content

Commit

Permalink
feat(api): make pagination configurable
Browse files Browse the repository at this point in the history
This adds the possiblity to configure the pagination via environment
variables and query params:

- Add possibility to let the client configure the page size via the
  `page_size` query param
- Add env var `PAGINATION_ENABLED` to completely disable pagination
- Add env var `PAGINATION_DEFAULT_PAGE_SIZE` to configure the default
  page size
- Add env var `PAGINATION_MAX_PAGE_SIZE` to configure the max value of
  the `page_size` query param
  • Loading branch information
anehx committed Oct 4, 2022
1 parent 0c08b5a commit dd6615f
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 2 deletions.
5 changes: 5 additions & 0 deletions CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,8 @@ supporting Open ID Connect. If not available, you might consider using
* `CORS_ORIGIN_REGEX_WHITELIST`: List of [whitelist regexes](https://github.com/ottoyiu/django-cors-headers#cors_origin_regex_whitelist) defaults to "^(https?://)?127\.0\.0\.1:\d{4}$"

Users of nginx/apache must ensure to have matching CORS configurations.

## Pagination
* `PAGINATION_ENABLED`: whether the pagination is enabled (default: `True`)
* `PAGINATION_DEFAULT_PAGE_SIZE`: the default page size if no query param (`page_size`) is given (default: `100`)
* `PAGINATION_MAX_PAGE_SIZE`: the max value of the page size query param (`page_size`) (default: `1000`)
7 changes: 7 additions & 0 deletions document_merge_service/api/pagination.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.conf import settings
from rest_framework.pagination import PageNumberPagination


class APIPagination(PageNumberPagination):
page_size_query_param = "page_size"
max_page_size = settings.PAGINATION_MAX_PAGE_SIZE
26 changes: 26 additions & 0 deletions document_merge_service/api/tests/test_pagination.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import pytest
from django.urls import reverse
from rest_framework import status


@pytest.mark.parametrize(
"query_params,expected",
[
({"page_size": 10}, 10),
({"page_size": 120}, 110), # max page size reached
({}, 100), # default page size
],
)
def test_pagination(db, client, template_factory, query_params, expected, mocker):
mocker.patch(
"document_merge_service.api.pagination.APIPagination.max_page_size", 110
)

template_factory.create_batch(120)

response = client.get(reverse("template-list"), data=query_params)

assert response.status_code == status.HTTP_200_OK
result = response.json()
assert result["count"] == 120
assert len(result["results"]) == expected
14 changes: 12 additions & 2 deletions document_merge_service/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,6 @@ def parse_admins(admins):
# https://www.django-rest-framework.org/api-guide/settings/

REST_FRAMEWORK = {
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
"PAGE_SIZE": 100,
"DEFAULT_PERMISSION_CLASSES": [
"document_merge_service.api.permissions.AsConfigured"
],
Expand All @@ -216,6 +214,18 @@ def parse_admins(admins):
"TEST_REQUEST_DEFAULT_FORMAT": "json",
}

PAGINATION_ENABLED = env.bool("PAGINATION_ENABLED", True)
PAGINATION_DEFAULT_PAGE_SIZE = env.int("PAGINATION_DEFAULT_PAGE_SIZE", 100)
PAGINATION_MAX_PAGE_SIZE = env.int("PAGINATION_MAX_PAGE_SIZE", 1000)

if PAGINATION_ENABLED:
REST_FRAMEWORK.update(
{
"DEFAULT_PAGINATION_CLASS": "document_merge_service.api.pagination.APIPagination",
"PAGE_SIZE": PAGINATION_DEFAULT_PAGE_SIZE,
}
)

# Logging
LOGGING = {
"version": 1,
Expand Down

0 comments on commit dd6615f

Please sign in to comment.