#[derive(ToSchema)]
{
// Attributes available to this derive:
#[schema]
#[aliases]
}
Expand description
ToSchema derive macro.
This is #[derive]
implementation for ToSchema
trait. The macro accepts one
schema
attribute optionally which can be used to enhance generated documentation. The attribute can be placed
at item level or field level in struct and enums. Currently placing this attribute to unnamed field does
not have any effect.
You can use the Rust’s own #[deprecated]
attribute on any struct, enum or field to mark it as deprecated and it will
reflect to the generated OpenAPI spec.
#[deprecated]
attribute supports adding additional details such as a reason and or since version but this is is not supported in
OpenAPI. OpenAPI has only a boolean flag to determine deprecation. While it is totally okay to declare deprecated with reason
#[deprecated = "There is better way to do this"]
the reason would not render in OpenAPI spec.
Struct Optional Configuration Options for #[schema(...)]
example = ...
Can be eitherjson!(...)
or literal string that can be parsed to json.json!
should be something thatserde_json::json!
can parse as aserde_json::Value
. 1xml(...)
Can be used to defineXml
object properties applicable to Structs.
Enum Optional Configuration Options for #[schema(...)]
example = ...
Can be literal value, method reference orjson!(...)
. 2default = ...
Can be literal value, method reference orjson!(...)
. 2
Unnamed Field Struct Optional Configuration Options for #[schema(...)]
example = ...
Can be literal value, method reference orjson!(...)
. 2default = ...
Can be literal value, method reference orjson!(...)
. 2format = ...
May either be variant of theKnownFormat
enum, or otherwise an open value as a string. By default the format is derived from the type of the property according OpenApi spec.value_type = ...
Can be used to override default type derived from type of the field used in OpenAPI spec. This is useful in cases where the default type does not correspond to the actual type e.g. when any third-party types are used which are notToSchema
s norprimitive
types. Value can be any Rust type what normally could be used to serialize to JSON or custom type such asObject
.
Named Fields Optional Configuration Options for #[schema(...)]
example = ...
Can be literal value, method reference orjson!(...)
. 2default = ...
Can be literal value, method reference orjson!(...)
. 2format = ...
May either be variant of theKnownFormat
enum, or otherwise an open value as a string. By default the format is derived from the type of the property according OpenApi spec.write_only
Defines property is only used in write operations POST,PUT,PATCH but not in GETread_only
Defines property is only used in read operations GET but not in POST,PUT,PATCHxml(...)
Can be used to defineXml
object properties applicable to named fields.value_type = ...
Can be used to override default type derived from type of the field used in OpenAPI spec. This is useful in cases where the default type does not correspond to the actual type e.g. when any third-party types are used which are notToSchema
s norprimitive
types. Value can be any Rust type what normally could be used to serialize to JSON or custom type such asObject
.inline
If the type of this field implementsToSchema
, then the schema definition will be inlined. warning: Don’t use this for recursive data types!nullable
Defines property is nullable (note this is different to non-required).
Xml attribute Configuration Options
xml(name = "...")
Will set name for property or type.xml(namespace = "...")
Will set namespace for xml element which needs to be valid uri.xml(prefix = "...")
Will set prefix for name.xml(attribute)
Will translate property to xml attribute instead of xml element.xml(wrapped)
Will make wrapped xml element.xml(wrapped(name = "wrap_name"))
Will override the wrapper elements name.
See Xml
for more details.
Partial #[serde(...)]
attributes support
ToSchema derive has partial support for serde attributes. These supported attributes will reflect to the
generated OpenAPI doc. For example if #[serde(skip)]
is defined the attribute will not show up in the OpenAPI spec at all since it will not never
be serialized anyway. Similarly the rename
and rename_all
will reflect to the generated OpenAPI doc.
rename_all = "..."
Supported in container level.rename = "..."
Supported only in field or variant level.skip = "..."
Supported only in field or variant level.tag = "..."
Supported in container level.tag
attribute also works as a discriminator field for an enum.default
Supported in container level and field level according to serde attributes.flatten
Supported in field level.
Other serde
attributes works as is but does not have any effect on the generated OpenAPI doc.
Note! tag
attribute has some limitations like it cannot be used
with unnamed field structs and tuple types. See more at
enum representation docs.
#[derive(Serialize, ToSchema)]
struct Foo(String);
#[derive(Serialize, ToSchema)]
#[serde(rename_all = "camelCase")]
enum Bar {
UnitValue,
#[serde(rename_all = "camelCase")]
NamedFields {
#[serde(rename = "id")]
named_id: &'static str,
name_list: Option<Vec<String>>
},
UnnamedFields(Foo),
#[serde(skip)]
SkipMe,
}
Add custom tag
to change JSON representation to be internally tagged.
#[derive(Serialize, ToSchema)]
struct Foo(String);
#[derive(Serialize, ToSchema)]
#[serde(tag = "tag")]
enum Bar {
UnitValue,
NamedFields {
id: &'static str,
names: Option<Vec<String>>
},
}
Add serde default
attribute for MyValue struct. Similarly default
could be added to
individual fields as well. If default
is given the field’s affected will be treated
as optional.
#[derive(utoipa::ToSchema, serde::Deserialize, Default)]
#[serde(default)]
struct MyValue {
field: String
}
#[repr(...)]
attribute support
ToSchema derive has support for repr(u*)
and repr(i*)
attributes for fieldless enums.
This allows you to create enums from thier discriminant values.
repr feature need to be enabled.
Otherwise, string representations of the fields will be used as values.
#[derive(ToSchema, Deserialize, Serialize)]
#[repr(u8)]
enum ApiVersion {
One = 1,
Two,
Three,
}
You can use skip
and tag
attributes from serde.
#[derive(ToSchema, Deserialize, Serialize)]
#[repr(i8)]
#[serde(tag = "code")]
enum ExitCode {
Error = -1,
#[serde(skip)]
Unknown = 0,
Ok = 1,
}
As well as schema attributes
for enums.
#[derive(ToSchema, Deserialize, Serialize)]
#[repr(u8)]
#[schema(default = default_value, example = 2)]
enum Mode {
One = 1,
Two,
}
fn default_value() -> u8 {
1
}
Generic schemas with aliases
Schemas can also be generic which allows reusing types. This enables certain behaviour patters where super type delcares common code for type aliases.
In this example we have common Status
type which accepts one generic type. It is then defined
with #[aliases(...)]
that it is going to be used with std::string::String
and i32
values.
The generic argument could also be another ToSchema
as well.
#[derive(ToSchema)]
#[aliases(StatusMessage = Status<String>, StatusNumber = Status<i32>)]
struct Status<T> {
value: T
}
#[derive(OpenApi)]
#[openapi(
components(schemas(StatusMessage, StatusNumber))
)]
struct ApiDoc;
The #[aliases(...)]
is just syntatic sugar and will create Rust type aliases
behind the scenes which then can be later referenced anywhere in code.
Note! You should never register generic type itself in components(...)
so according above example Status<...>
should not be registered
because it will not render the type correctly and will cause an error in generated OpenAPI spec.
Examples
Example struct with struct level example.
#[derive(ToSchema)]
#[schema(example = json!({"name": "bob the cat", "id": 0}))]
struct Pet {
id: u64,
name: String,
age: Option<i32>,
}
The schema
attribute can also be placed at field level as follows.
#[derive(ToSchema)]
struct Pet {
#[schema(example = 1, default = 0)]
id: u64,
name: String,
age: Option<i32>,
}
You can also use method reference for attribute values.
#[derive(ToSchema)]
struct Pet {
#[schema(example = u64::default, default = u64::default)]
id: u64,
#[schema(default = default_name)]
name: String,
age: Option<i32>,
}
fn default_name() -> String {
"bob".to_string()
}
For enums and unnamed field structs you can define schema
at type level.
#[derive(ToSchema)]
#[schema(example = "Bus")]
enum VehicleType {
Rocket, Car, Bus, Submarine
}
Also you write complex enum combining all above types.
#[derive(ToSchema)]
enum ErrorResponse {
InvalidCredentials,
#[schema(default = String::default, example = "Pet not found")]
NotFound(String),
System {
#[schema(example = "Unknown system failure")]
details: String,
}
}
It is possible to specify the title of each variant to help generators create named structures.
#[derive(ToSchema)]
enum ErrorResponse {
#[schema(title = "InvalidCredentials")]
InvalidCredentials,
#[schema(title = "NotFound")]
NotFound(String),
}
Use xml
attribute to manipulate xml output.
#[derive(ToSchema)]
#[schema(xml(name = "user", prefix = "u", namespace = "https://user.xml.schema.test"))]
struct User {
#[schema(xml(attribute, prefix = "u"))]
id: i64,
#[schema(xml(name = "user_name", prefix = "u"))]
username: String,
#[schema(xml(wrapped(name = "linkList"), name = "link"))]
links: Vec<String>,
#[schema(xml(wrapped, name = "photo_url"))]
photos_urls: Vec<String>
}
Use of Rust’s own #[deprecated]
attribute will reflect to generated OpenAPI spec.
#[derive(ToSchema)]
#[deprecated]
struct User {
id: i64,
username: String,
links: Vec<String>,
#[deprecated]
photos_urls: Vec<String>
}
Enforce type being used in OpenAPI spec to String
with value_type
and set format to octet stream
with SchemaFormat::KnownFormat(KnownFormat::Binary)
.
#[derive(ToSchema)]
struct Post {
id: i32,
#[schema(value_type = String, format = Binary)]
value: Vec<u8>,
}
Enforce type being used in OpenAPI spec to String
with value_type
option.
#[derive(ToSchema)]
#[schema(value_type = String)]
struct Value(i64);
Override the Bar
reference with a custom::NewBar
reference.
#[derive(ToSchema)]
struct Value {
#[schema(value_type = custom::NewBar)]
field: Bar,
};
Use a virtual Object
type to render generic object
in OpenAPI spec.
#[derive(ToSchema)]
struct Value {
#[schema(value_type = Object)]
field: Bar,
};
More examples for value_type
in IntoParams
derive docs.