#[derive(ToResponse)]
{
// Attributes available to this derive:
#[salvo]
}
Expand description
Generate reusable OpenApi response.
This is #[derive] implementation for ToResponse trait.
#[salvo(response(...))] attribute can be used to alter and add response attributes.
#[salvo(content(...))] attributes is used to make enum variant a content of a specific type for the
response.
#[salvo(schema(...))] attribute is used to inline a schema for a response in unnamed structs or
enum variants with #[content] attribute. Note! ToSchema need to be implemented for
the field or variant type.
Type derived with ToResponse uses provided doc comment as a description for the response. It
can alternatively be overridden with description = ... attribute.
ToResponse can be used in four different ways to generate OpenAPI response component.
-
By decorating
structorenumwithToResponsederive macro. This will create a response with inlined schema resolved from the fields of thestructorvariantsof the enum.#[derive(ToResponse)] #[salvo(response(description = "Person response returns single Person entity"))] struct Person { name: String, } -
By decorating unnamed field
structwithToResponsederive macro. Unnamed field struct allows users to use new type pattern to define one inner field which is used as a schema for the generated response. This allows users to defineVecandOptionresponse types. Additionally these types can also be used with#[salvo(schema(...))]attribute to inline the field’s type schema if it implementsToSchemaderive macro./// Person list response #[derive(salvo_oapi::ToResponse)] struct PersonList(Vec<Person>); -
By decorating unit struct with
ToResponsederive macro. Unit structs will produce a response without body./// Success response which does not have body. #[derive(salvo_oapi::ToResponse)] struct SuccessResponse; -
By decorating
enumwith variants having#[salvo(content(...))]attribute. This allows users to define multiple response content schemas to single response according to OpenAPI spec. Note: Enum withcontentattribute in variants cannot have enum levelexampleorexamplesdefined. Instead examples need to be defined per variant basis. Additionally these variants can also be used with#[salvo(schema(...))]attribute to inline the variant’s type schema if it implementsToSchemaderive macro.#[derive(salvo_oapi::ToSchema)] struct Admin { name: String, } #[derive(salvo_oapi::ToSchema)] struct Admin2 { name: String, id: i32, } #[derive(salvo_oapi::ToResponse)] enum Person { #[salvo( response(examples( ("Person1" = (value = json!({"name": "name1"}))), ("Person2" = (value = json!({"name": "name2"}))) )) )] Admin(#[salvo(content("application/vnd-custom-v1+json"))] Admin), #[salvo(response(example = json!({"name": "name3", "id": 1})))] Admin2(#[salvo(content("application/vnd-custom-v2+json"))] #[salvo(schema(inline))] Admin2), }
§ToResponse #[salvo(response(...))] attributes
-
description = "..."Define description for the response as str. This can be used to override the default description resolved from doc comments if present. -
content_type = "..." | content_type = [...]Can be used to override the default behavior of auto resolving the content type from thebodyattribute. If defined the value should be valid content type such asapplication/json. By default the content type istext/plainfor primitive Rust types,application/octet-streamfor[u8]andapplication/jsonfor struct and complex enum types. Content type can also be slice of content_type values if the endpoint support returning multiple response content types. E.g["application/json", "text/xml"]would indicate that endpoint can return bothjsonandxmlformats. The order of the content types define the default example show first in the Swagger UI. Swagger UI will use the firstcontent_typevalue as a default example. -
headers(...)Slice of response headers that are returned back to a caller. -
example = ...Can bejson!(...).json!(...)should be something thatserde_json::json!can parse as aserde_json::Value. -
examples(...)Define multiple examples for single response. This attribute is mutually exclusive to theexampleattribute and if both are defined this will override theexample.name = ...This is first attribute and value must be literal string.summary = ...Short description of example. Value must be literal string.description = ...Long description of example. Attribute supports markdown for rich text representation. Value must be literal string.value = ...Example value. It must bejson!(...).json!(...)should be something thatserde_json::json!can parse as aserde_json::Value.external_value = ...Define URI to literal example value. This is mutually exclusive to thevalueattribute. Value must be literal string.
Example of example definition.
("John" = (summary = "This is John", value = json!({"name": "John"})))
§Examples
Use reusable response in operation handler.
use salvo_core::http::{header::CONTENT_TYPE, HeaderValue};
use salvo_core::prelude::*;
use salvo_oapi::{ToSchema, ToResponse, endpoint};
#[derive(ToResponse, ToSchema)]
struct PersonResponse {
value: String
}
impl Scribe for PersonResponse {
fn render(self, res: &mut Response) {
res.headers_mut()
.insert(CONTENT_TYPE, HeaderValue::from_static("text/plain; charset=utf-8"));
let _ = res.write_body(self.value);
}
}
#[endpoint(
responses(
(status_code = 200, response = PersonResponse)
)
)]
fn get_person() -> PersonResponse {
PersonResponse { value: "person".to_string() }
}Create a response from named struct.
use salvo_oapi::{ToSchema, ToResponse};
/// This is description
///
/// It will also be used in `ToSchema` if present
#[derive(ToSchema, ToResponse)]
#[salvo(
response(
description = "Override description for response",
content_type = "text/xml"
)
)]
#[salvo(
response(
example = json!({"name": "the name"}),
headers(
("csrf-token", description = "response csrf token"),
("random-id" = i32)
)
)
)]
struct Person {
name: String,
}Create inlined person list response.
/// Person list response
#[derive(salvo_oapi::ToResponse)]
struct PersonList(#[salvo(schema(inline))] Vec<Person>);Create enum response from variants.
#[derive(salvo_oapi::ToResponse)]
enum PersonType {
Value(String),
Foobar,
}