I'm using utoipa
in order to document my REST API but I have to duplicate my code with same error messages (401 and 403) like this example
#[utoipa::path(
context_path = "/user",
tag = "user",
responses(
(status = 200, description = "Endpoint to get all data from a user.",
body = Value,
example = json!({
"id": 12,
"user_id": "TestUser42",
"class": "8a",
"created_at": "07-04-2004",
"user_data": {
"traffic": [],
"modules": []
}
})
),
(status = 401, description = "Access token is missing or invalid",
body = HttpError,
example = json!({
"time": "07-05-2024 08:17:33",
"status_code": "401",
"error_type": "Unauthorized",
"reason": "Access token is missing or invalid"
})
),
(status = 404, description = "ID not found", body = HttpError,
example = json!({
"time": "07-05-2024 08:17:33",
"status_code": "404",
"error_type": "NotFound",
"reason": "ID not found"
})
),
(status = 403, description = "Not allowed to call this endpoint with the current permission", body = HttpError,
example = json!({
"time": "07-05-2024 08:17:33",
"status_code": "403",
"error_type": "AccessForbidden",
"reason": "Wrong or missing permissions"
})
)
),
security(
("bearerAuth" = [])
)
)]
#[get("/get")]
#[protect(any("STUDENT", "ADMIN"), error = "access_denied")]
pub async fn get_user(
claims: Option<web::ReqData<Claims>>
) -> impl Responder {
if let Some(claims) = claims {
match user_service::get_user(claims.sub.parse::<i32>().unwrap()).await {
Ok(u) => HttpResponse::Ok().json(u),
Err(_) => HttpError::not_found("User does not exist").error_response()
}
} else {
HttpError::bad_gateway("Unable to get user").error_response()
}
}
How is it possible to use IntoResponses
or reading the responses from a JSON file? IntoResponses
works but it isn't possible to create examples like I want it similar to my code. There is no function that allows me to create an example (i.e. example(json!({}))
which does not exists). There is an ExampleBuilder::new()
but I can't use it or doesn't know where.
impl IntoResponses for HttpError {
fn responses() -> BTreeMap<String, RefOr<Response>> {
ResponsesBuilder::new()
.response("401", ResponseBuilder::new()
.description("JWT invalid or missing")
.content("application/json",
Content::new(HttpError {
time: "07-05-2024 08:17:33".to_string(),
status_code: "401".to_string(),
error_type: ErrorResponse::Unauthorized,
reason: Some("JWT missing or invalid".to_string()),
}))
)
.response("403", ResponseBuilder::new()
.description("Not allowed to call this endpoint with the current permission")
.content("application/json",
Content::new(HttpError {
time: "07-05-2024 08:17:33".to_string(),
status_code: "403".to_string(),
error_type: ErrorResponse::Forbidden,
reason: Some("Access Forbidden".to_string()),
}))
)
.build()
.into()
}
}