Skip to content

Commit a1f4f3a

Browse files
authored
Add OpenAPI documentation for GET /api/v1/users/{user} endpoint (#10698)
1 parent d0afff8 commit a1f4f3a

File tree

3 files changed

+85
-6
lines changed

3 files changed

+85
-6
lines changed

src/controllers/user/other.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use axum::Json;
12
use axum::extract::Path;
23
use axum_extra::json;
34
use axum_extra::response::ErasedJson;
@@ -12,6 +13,11 @@ use crate::util::errors::AppResult;
1213
use crate::views::EncodablePublicUser;
1314
use crates_io_diesel_helpers::lower;
1415

16+
#[derive(Debug, Serialize, utoipa::ToSchema)]
17+
pub struct GetResponse {
18+
pub user: EncodablePublicUser,
19+
}
20+
1521
/// Find user by login.
1622
#[utoipa::path(
1723
get,
@@ -20,9 +26,12 @@ use crates_io_diesel_helpers::lower;
2026
("user" = String, Path, description = "Login name of the user"),
2127
),
2228
tag = "users",
23-
responses((status = 200, description = "Successful Response")),
29+
responses((status = 200, description = "Successful Response", body = inline(GetResponse))),
2430
)]
25-
pub async fn find_user(state: AppState, Path(user_name): Path<String>) -> AppResult<ErasedJson> {
31+
pub async fn find_user(
32+
state: AppState,
33+
Path(user_name): Path<String>,
34+
) -> AppResult<Json<GetResponse>> {
2635
let mut conn = state.db_read_prefer_primary().await?;
2736

2837
use crate::schema::users::dsl::{gh_login, id, users};
@@ -34,7 +43,7 @@ pub async fn find_user(state: AppState, Path(user_name): Path<String>) -> AppRes
3443
.first(&mut conn)
3544
.await?;
3645

37-
Ok(json!({ "user": EncodablePublicUser::from(user) }))
46+
Ok(Json(GetResponse { user: user.into() }))
3847
}
3948

4049
/// Get user stats.

src/snapshots/crates_io__openapi__tests__openapi_snapshot.snap

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,48 @@ expression: response.json()
129129
"description"
130130
],
131131
"type": "object"
132+
},
133+
"User": {
134+
"properties": {
135+
"avatar": {
136+
"description": "The user's avatar URL, if set.",
137+
"example": "https://avatars2.githubusercontent.com/u/1234567?v=4",
138+
"type": [
139+
"string",
140+
"null"
141+
]
142+
},
143+
"id": {
144+
"description": "An opaque identifier for the user.",
145+
"example": 42,
146+
"format": "int32",
147+
"type": "integer"
148+
},
149+
"login": {
150+
"description": "The user's login name.",
151+
"example": "ghost",
152+
"type": "string"
153+
},
154+
"name": {
155+
"description": "The user's display name, if set.",
156+
"example": "Kate Morgan",
157+
"type": [
158+
"string",
159+
"null"
160+
]
161+
},
162+
"url": {
163+
"description": "The user's GitHub profile URL.",
164+
"example": "https://github.com/ghost",
165+
"type": "string"
166+
}
167+
},
168+
"required": [
169+
"id",
170+
"login",
171+
"url"
172+
],
173+
"type": "object"
132174
}
133175
},
134176
"securitySchemes": {
@@ -2004,6 +2046,21 @@ expression: response.json()
20042046
],
20052047
"responses": {
20062048
"200": {
2049+
"content": {
2050+
"application/json": {
2051+
"schema": {
2052+
"properties": {
2053+
"user": {
2054+
"$ref": "#/components/schemas/User"
2055+
}
2056+
},
2057+
"required": [
2058+
"user"
2059+
],
2060+
"type": "object"
2061+
}
2062+
}
2063+
},
20072064
"description": "Successful Response"
20082065
}
20092066
},

src/views.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -522,14 +522,27 @@ impl EncodablePrivateUser {
522522
}
523523
}
524524

525-
/// The serialization format for the `User` model.
526-
/// Same as private user, except no email field
527-
#[derive(Deserialize, Serialize, Debug, PartialEq, Eq)]
525+
#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, utoipa::ToSchema)]
526+
#[schema(as = User)]
528527
pub struct EncodablePublicUser {
528+
/// An opaque identifier for the user.
529+
#[schema(example = 42)]
529530
pub id: i32,
531+
532+
/// The user's login name.
533+
#[schema(example = "ghost")]
530534
pub login: String,
535+
536+
/// The user's display name, if set.
537+
#[schema(example = "Kate Morgan")]
531538
pub name: Option<String>,
539+
540+
/// The user's avatar URL, if set.
541+
#[schema(example = "https://avatars2.githubusercontent.com/u/1234567?v=4")]
532542
pub avatar: Option<String>,
543+
544+
/// The user's GitHub profile URL.
545+
#[schema(example = "https://github.com/ghost")]
533546
pub url: String,
534547
}
535548

0 commit comments

Comments
 (0)