Skip to content

Commit 15ba0f4

Browse files
authored
utoipa: Add pagination query params to list_crates() documentation (#10233)
1 parent b83cc4c commit 15ba0f4

File tree

3 files changed

+67
-10
lines changed

3 files changed

+67
-10
lines changed

src/controllers/helpers/pagination.rs

+25-8
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,30 @@ impl PaginationOptions {
5555
}
5656
}
5757

58+
#[derive(Debug, Deserialize, utoipa::IntoParams)]
59+
#[into_params(parameter_in = Query)]
60+
pub struct PaginationQueryParams {
61+
/// The page number to request.
62+
///
63+
/// This parameter is mutually exclusive with `seek` and not supported for
64+
/// all requests.
65+
#[param(value_type = Option<u32>, minimum = 1)]
66+
page: Option<NonZeroU32>,
67+
68+
/// The number of items to request per page.
69+
#[param(value_type = Option<u32>, minimum = 1)]
70+
per_page: Option<NonZeroU32>,
71+
72+
/// The seek key to request.
73+
///
74+
/// This parameter is mutually exclusive with `page` and not supported for
75+
/// all requests.
76+
///
77+
/// The seek key can usually be found in the `meta.next_page` field of
78+
/// paginated responses.
79+
seek: Option<String>,
80+
}
81+
5882
pub(crate) struct PaginationOptionsBuilder {
5983
limit_page_numbers: bool,
6084
enable_pages: bool,
@@ -80,14 +104,7 @@ impl PaginationOptionsBuilder {
80104
pub(crate) fn gather(self, parts: &Parts) -> AppResult<PaginationOptions> {
81105
use axum::extract::Query;
82106

83-
#[derive(Debug, Deserialize)]
84-
struct QueryParams {
85-
page: Option<NonZeroU32>,
86-
per_page: Option<NonZeroU32>,
87-
seek: Option<String>,
88-
}
89-
90-
let Query(params) = Query::<QueryParams>::try_from_uri(&parts.uri)
107+
let Query(params) = Query::<PaginationQueryParams>::try_from_uri(&parts.uri)
91108
.map_err(|err| bad_request(err.body_text()))?;
92109

93110
if params.seek.is_some() && params.page.is_some() {

src/controllers/krate/search.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::schema::*;
2222
use crate::util::errors::{bad_request, AppResult};
2323
use crate::views::EncodableCrate;
2424

25-
use crate::controllers::helpers::pagination::{Page, PaginationOptions};
25+
use crate::controllers::helpers::pagination::{Page, PaginationOptions, PaginationQueryParams};
2626
use crate::models::krate::ALL_COLUMNS;
2727
use crate::sql::{array_agg, canon_crate_name, lower};
2828
use crate::util::string_excl_null::StringExclNull;
@@ -37,7 +37,7 @@ use crate::util::RequestUtils;
3737
#[utoipa::path(
3838
get,
3939
path = "/api/v1/crates",
40-
params(ListQueryParams),
40+
params(ListQueryParams, PaginationQueryParams),
4141
tag = "crates",
4242
responses((status = 200, description = "Successful Response")),
4343
)]

src/snapshots/crates_io__openapi__tests__openapi_snapshot.snap

+40
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,46 @@ snapshot_kind: text
322322
},
323323
"type": "array"
324324
}
325+
},
326+
{
327+
"description": "The page number to request.\n\nThis parameter is mutually exclusive with `seek` and not supported for\nall requests.",
328+
"in": "query",
329+
"name": "page",
330+
"required": false,
331+
"schema": {
332+
"format": "int32",
333+
"minimum": 1,
334+
"type": [
335+
"integer",
336+
"null"
337+
]
338+
}
339+
},
340+
{
341+
"description": "The number of items to request per page.",
342+
"in": "query",
343+
"name": "per_page",
344+
"required": false,
345+
"schema": {
346+
"format": "int32",
347+
"minimum": 1,
348+
"type": [
349+
"integer",
350+
"null"
351+
]
352+
}
353+
},
354+
{
355+
"description": "The seek key to request.\n\nThis parameter is mutually exclusive with `page` and not supported for\nall requests.\n\nThe seek key can usually be found in the `meta.next_page` field of\npaginated responses.",
356+
"in": "query",
357+
"name": "seek",
358+
"required": false,
359+
"schema": {
360+
"type": [
361+
"string",
362+
"null"
363+
]
364+
}
325365
}
326366
],
327367
"responses": {

0 commit comments

Comments
 (0)