Skip to content

Commit 910540f

Browse files
committed
Improve OpenAPI documentation for GET /api/v1/summary endpoint
1 parent 0fc539c commit 910540f

File tree

2 files changed

+119
-25
lines changed

2 files changed

+119
-25
lines changed

src/controllers/summary.rs

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,41 @@ use crate::schema::{
55
};
66
use crate::util::errors::AppResult;
77
use crate::views::{EncodableCategory, EncodableCrate, EncodableKeyword};
8-
use axum_extra::json;
9-
use axum_extra::response::ErasedJson;
8+
use axum::Json;
109
use diesel::prelude::*;
1110
use diesel_async::{AsyncPgConnection, RunQueryDsl};
1211
use futures_util::FutureExt;
1312
use std::future::Future;
1413

14+
#[derive(Debug, Serialize, utoipa::ToSchema)]
15+
pub struct SummaryResponse {
16+
/// The total number of downloads across all crates.
17+
#[schema(example = 123_456_789)]
18+
num_downloads: i64,
19+
20+
/// The total number of crates on crates.io.
21+
#[schema(example = 123_456)]
22+
num_crates: i64,
23+
24+
/// The 10 most recently created crates.
25+
new_crates: Vec<EncodableCrate>,
26+
27+
/// The 10 crates with the highest total number of downloads.
28+
most_downloaded: Vec<EncodableCrate>,
29+
30+
/// The 10 crates with the highest number of downloads within the last 90 days.
31+
most_recently_downloaded: Vec<EncodableCrate>,
32+
33+
/// The 10 most recently updated crates.
34+
just_updated: Vec<EncodableCrate>,
35+
36+
/// The 10 most popular keywords.
37+
popular_keywords: Vec<EncodableKeyword>,
38+
39+
/// The 10 most popular categories.
40+
popular_categories: Vec<EncodableCategory>,
41+
}
42+
1543
/// Get front page data.
1644
///
1745
/// This endpoint returns a summary of the most important data for the front
@@ -20,9 +48,9 @@ use std::future::Future;
2048
get,
2149
path = "/api/v1/summary",
2250
tag = "other",
23-
responses((status = 200, description = "Successful Response")),
51+
responses((status = 200, description = "Successful Response", body = inline(SummaryResponse))),
2452
)]
25-
pub async fn get_summary(state: AppState) -> AppResult<ErasedJson> {
53+
pub async fn get_summary(state: AppState) -> AppResult<Json<SummaryResponse>> {
2654
let mut conn = state.db_read().await?;
2755

2856
let config = &state.config;
@@ -37,10 +65,10 @@ pub async fn get_summary(state: AppState) -> AppResult<ErasedJson> {
3765
popular_categories,
3866
popular_keywords,
3967
) = tokio::try_join!(
40-
crates::table.count().get_result::<i64>(&mut conn).boxed(),
68+
crates::table.count().get_result(&mut conn).boxed(),
4169
metadata::table
4270
.select(metadata::total_downloads)
43-
.get_result::<i64>(&mut conn)
71+
.get_result(&mut conn)
4472
.boxed(),
4573
crates::table
4674
.inner_join(crate_downloads::table)
@@ -100,25 +128,18 @@ pub async fn get_summary(state: AppState) -> AppResult<ErasedJson> {
100128
encode_crates(&mut conn, just_updated),
101129
)?;
102130

103-
let popular_categories = popular_categories
104-
.into_iter()
105-
.map(Category::into)
106-
.collect::<Vec<EncodableCategory>>();
107-
108-
let popular_keywords = popular_keywords
109-
.into_iter()
110-
.map(Keyword::into)
111-
.collect::<Vec<EncodableKeyword>>();
112-
113-
Ok(json!({
114-
"num_downloads": num_downloads,
115-
"num_crates": num_crates,
116-
"new_crates": new_crates,
117-
"most_downloaded": most_downloaded,
118-
"most_recently_downloaded": most_recently_downloaded,
119-
"just_updated": just_updated,
120-
"popular_keywords": popular_keywords,
121-
"popular_categories": popular_categories,
131+
let popular_categories = popular_categories.into_iter().map(Category::into).collect();
132+
let popular_keywords = popular_keywords.into_iter().map(Keyword::into).collect();
133+
134+
Ok(Json(SummaryResponse {
135+
num_downloads,
136+
num_crates,
137+
new_crates,
138+
most_downloaded,
139+
most_recently_downloaded,
140+
just_updated,
141+
popular_keywords,
142+
popular_categories,
122143
}))
123144
}
124145

src/snapshots/crates_io__openapi__tests__openapi_snapshot.snap

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3704,6 +3704,79 @@ expression: response.json()
37043704
"operationId": "get_summary",
37053705
"responses": {
37063706
"200": {
3707+
"content": {
3708+
"application/json": {
3709+
"schema": {
3710+
"properties": {
3711+
"just_updated": {
3712+
"description": "The 10 most recently updated crates.",
3713+
"items": {
3714+
"$ref": "#/components/schemas/Crate"
3715+
},
3716+
"type": "array"
3717+
},
3718+
"most_downloaded": {
3719+
"description": "The 10 crates with the highest total number of downloads.",
3720+
"items": {
3721+
"$ref": "#/components/schemas/Crate"
3722+
},
3723+
"type": "array"
3724+
},
3725+
"most_recently_downloaded": {
3726+
"description": "The 10 crates with the highest number of downloads within the last 90 days.",
3727+
"items": {
3728+
"$ref": "#/components/schemas/Crate"
3729+
},
3730+
"type": "array"
3731+
},
3732+
"new_crates": {
3733+
"description": "The 10 most recently created crates.",
3734+
"items": {
3735+
"$ref": "#/components/schemas/Crate"
3736+
},
3737+
"type": "array"
3738+
},
3739+
"num_crates": {
3740+
"description": "The total number of crates on crates.io.",
3741+
"example": 123456,
3742+
"format": "int64",
3743+
"type": "integer"
3744+
},
3745+
"num_downloads": {
3746+
"description": "The total number of downloads across all crates.",
3747+
"example": 123456789,
3748+
"format": "int64",
3749+
"type": "integer"
3750+
},
3751+
"popular_categories": {
3752+
"description": "The 10 most popular categories.",
3753+
"items": {
3754+
"$ref": "#/components/schemas/Category"
3755+
},
3756+
"type": "array"
3757+
},
3758+
"popular_keywords": {
3759+
"description": "The 10 most popular keywords.",
3760+
"items": {
3761+
"$ref": "#/components/schemas/Keyword"
3762+
},
3763+
"type": "array"
3764+
}
3765+
},
3766+
"required": [
3767+
"num_downloads",
3768+
"num_crates",
3769+
"new_crates",
3770+
"most_downloaded",
3771+
"most_recently_downloaded",
3772+
"just_updated",
3773+
"popular_keywords",
3774+
"popular_categories"
3775+
],
3776+
"type": "object"
3777+
}
3778+
}
3779+
},
37073780
"description": "Successful Response"
37083781
}
37093782
},

0 commit comments

Comments
 (0)