#[path]
Expand description
Path attribute macro implements OpenAPI path for the decorated function.
This is a #[derive]
implementation for Path
trait. Macro accepts set of attributes that can
be used to configure and override default values what are resolved automatically.
You can use the Rust’s own #[deprecated]
attribute on functions to mark it as deprecated and it will
reflect to the generated OpenAPI spec. Only parameters has a special deprecated attribute to define them as deprecated.
#[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.
Doc comment at decorated function will be used for description
and summary
of the path.
First line of the doc comment will be used as the summary
while the remaining lines will be
used as description
.
/// This is a summary of the operation
///
/// The rest of the doc comment will be included to operation description.
#[utoipa::path(get, path = "/operation")]
fn operation() {}
§Path Attributes
-
operation
Must be first parameter! Accepted values are known HTTP operations such asget, post, put, delete, head, options, patch, trace
. -
method(get, head, ...)
Http methods for the operation. This allows defining multiple HTTP methods at once for single operation. Eitheroperation
ormethod(...)
must be provided. -
path = "..."
Must be OpenAPI format compatible str with arguments within curly braces. E.g{id}
-
impl_for = ...
Optional type to implement thePath
trait. By default a new type is used for the implementation. -
operation_id = ...
Unique operation id for the endpoint. By default this is mapped to function name. The operation_id can be any valid expression (e.g. string literals, macro invocations, variables) so long as its result can be converted to aString
usingString::from
. -
context_path = "..."
Can add optional scope for path. The context_path will be prepended to beginning of path. This is particularly useful when path does not contain the full path to the endpoint. For example if web framework allows operation to be defined under some context path or scope which does not reflect to the resolved path then this context_path can become handy to alter the path. -
tag = "..."
Can be used to group operations. Operations with same tag are grouped together. By default this is derived from the module path of the handler that is given toOpenApi
. -
tags = ["tag1", ...]
Can be used to group operations. Operations with same tag are grouped together. Tags attribute can be used to add additional tags for the operation. If bothtag
andtags
are provided then they will be combined to a singletags
array. -
request_body = ... | request_body(...)
Defining request body indicates that the request is expecting request body within the performed request. -
responses(...)
Slice of responses the endpoint is going to possibly return to the caller. -
params(...)
Slice of params that the endpoint accepts. -
security(...)
List ofSecurityRequirement
s local to the path operation.
§Request Body Attributes
§Simple format definition by request_body = ...
request_body = Type
,request_body = inline(Type)
orrequest_body = ref("...")
. The givenType
can be any Rust type that is JSON parseable. It can be Option, Vec or Map etc. Withinline(...)
the schema will be inlined instead of a referenced which is the default forToSchema
types.ref("./external.json")
can be used to reference external json file for body schema. Note! Utoipa does not guarantee that free formref
is accessible via OpenAPI doc or Swagger UI, users are responsible for making these guarantees.
§Advanced format definition by request_body(...)
With advanced format the request body supports defining either one or multiple request bodies by content
attribute.
§Common request body attributes
-
description = "..."
Define the description for the request body object as str. -
example = ...
Can bejson!(...)
.json!(...)
should be something thatserde_json::json!
can parse as aserde_json::Value
. -
examples(...)
Define multiple examples for single request body. This attribute is mutually exclusive to theexample
attribute and if both are defined this will override theexample
. This has same syntax asexamples(...)
in Response Attributes examples(…)
§Single request body content
-
content = ...
Can becontent = Type
,content = inline(Type)
orcontent = ref("...")
. The givenType
can be any Rust type that is JSON parseable. It can be Option, Vec or Map etc. Withinline(...)
the schema will be inlined instead of a referenced which is the default forToSchema
types.ref("./external.json")
can be used to reference external json file for body schema. Note! Utoipa does not guarantee that free formref
is accessible via OpenAPI doc or Swagger UI, users are responsible for making these guarantees. -
content_type = "..."
Can be used to override the default behavior of auto resolving the content type from thecontent
attribute. If defined the value should be valid content type such asapplication/json
. By default the content type istext/plain
for primitive Rust types,application/octet-stream
for[u8]
andapplication/json
for struct and mixed enum types.
Example of single request body definitions.
request_body(content = String, description = "Xml as string request", content_type = "text/xml"),
request_body(content_type = "application/json"),
request_body = Pet,
request_body = Option<[Pet]>,
§Multiple request body content
-
content(...)
Can be tuple of content tuples according to format below.( schema ) ( schema = "content/type", example = ..., examples(..., ...) ) ( "content/type", ), ( "content/type", example = ..., examples(..., ...) )
First argument of content tuple is
schema
, which is optional as long as eitherschema
orcontent/type
is defined. Theschema
andcontent/type
is separated with equals (=) sign. Optionally content tuple supports definingexample
andexamples
arguments. See common request body attributes
Example of multiple request body definitions.
// guess the content type for Pet and Pet2
request_body(description = "Common description",
content(
(Pet),
(Pet2)
)
),
// define explicit content types
request_body(description = "Common description",
content(
(Pet = "application/json", examples(..., ...), example = ...),
(Pet2 = "text/xml", examples(..., ...), example = ...)
)
),
// omit schema and accept arbitrary content types
request_body(description = "Common description",
content(
("application/json"),
("text/xml", examples(..., ...), example = ...)
)
),
§Response Attributes
-
status = ...
Is either a valid http status code integer. E.g.200
or a string value representing a range such as"4XX"
or"default"
or a validhttp::status::StatusCode
.StatusCode
can either be use path to the status code or status code constant directly. -
description = "..."
Define description for the response as str. -
body = ...
Optional response body object type. When left empty response does not expect to send any response body. Can bebody = Type
,body = inline(Type)
, orbody = ref("...")
. The givenType
can be any Rust type that is JSON parseable. It can be Option, Vec or Map etc. Withinline(...)
the schema will be inlined instead of a referenced which is the default forToSchema
types.ref("./external.json")
can be used to reference external json file for body schema. Note! Utoipa does not guarantee that free formref
is accessible via OpenAPI doc or Swagger UI, users are responsible for making these guarantees. -
content_type = "..."
Can be used to override the default behavior of auto resolving the content type from thebody
attribute. If defined the value should be valid content type such asapplication/json
. By default the content type istext/plain
for primitive Rust types,application/octet-stream
for[u8]
andapplication/json
for struct and mixed enum types. -
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
. -
response = ...
Type what implementsToResponse
trait. This can alternatively be used to define response attributes.response
attribute cannot co-exist with other thanstatus
attribute. -
content((...), (...))
Can be used to define multiple return types for single response status. Supports same syntax as multiple request body content. -
examples(...)
Define multiple examples for single response. This attribute is mutually exclusive to theexample
attribute and if both are defined this will override theexample
. -
links(...)
Define a map of operations links that can be followed from the response.
§Response examples(...)
syntax
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 thevalue
attribute. Value must be literal string.
Example of example definition.
("John" = (summary = "This is John", value = json!({"name": "John"})))
§Response links(...)
syntax
-
operation_ref = ...
Define a relative or absolute URI reference to an OAS operation. This field is mutually exclusive of theoperation_id
field, and must point to an Operation Object. Value can be bestr
or an expression such asinclude_str!
or staticconst
reference. -
operation_id = ...
Define the name of an existing, resolvable OAS operation, as defined with a uniqueoperation_id
. This field is mutually exclusive of theoperation_ref
field. Value can be bestr
or an expression such asinclude_str!
or staticconst
reference. -
parameters(...)
A map representing parameters to pass to an operation as specified withoperation_id
or identified byoperation_ref
. The key is parameter name to be used and value can be any value supported by JSON or an expression e.g.$path.id
name = ...
Define name for the parameter. Value can be bestr
or an expression such asinclude_str!
or staticconst
reference.value
= Any value that can be supported by JSON or an expression.
Example of parameters syntax:
parameters( ("name" = value), ("name" = value) ),
-
request_body = ...
Define a literal value or an expression to be used as request body when operation is called -
description = ...
Define description of the link. Value supports Markdown syntax.Value can be bestr
or an expression such asinclude_str!
or staticconst
reference. -
server(...)
Define Server object to be used by the target operation. See server syntax
Links syntax example: See the full example below in examples.
responses(
(status = 200, description = "success response",
links(
("link_name" = (
operation_id = "test_links",
parameters(("key" = "value"), ("json_value" = json!(1))),
request_body = "this is body",
server(url = "http://localhost")
))
)
)
)
Minimal response format:
responses(
(status = 200, description = "success response"),
(status = 404, description = "resource missing"),
(status = "5XX", description = "server error"),
(status = StatusCode::INTERNAL_SERVER_ERROR, description = "internal server error"),
(status = IM_A_TEAPOT, description = "happy easter")
)
More complete Response:
responses(
(status = 200, description = "Success response", body = Pet, content_type = "application/json",
headers(...),
example = json!({"id": 1, "name": "bob the cat"})
)
)
Multiple response return types with content(...)
attribute:
Define multiple response return types for single response status with their own example.
responses(
(status = 200, content(
(User = "application/vnd.user.v1+json", example = json!(User {id: "id".to_string()})),
(User2 = "application/vnd.user.v2+json", example = json!(User2 {id: 2}))
)
)
)
§Using ToResponse
for reusable responses
ReusableResponse
must be a type that implements ToResponse
.
responses(
(status = 200, response = ReusableResponse)
)
ToResponse
can also be inlined to the responses map.
responses(
(status = 200, response = inline(ReusableResponse))
)
§Responses from IntoResponses
Responses for a path can be specified with one or more types that implement
IntoResponses
.
responses(MyResponse)
§Response Header Attributes
-
name
Name of the header. E.g.x-csrf-token
-
type
Additional type of the header value. Can beType
orinline(Type)
. The givenType
can be any Rust type that is JSON parseable. It can be Option, Vec or Map etc. Withinline(...)
the schema will be inlined instead of a referenced which is the default forToSchema
types. Reminder! It’s up to the user to use valid type for the response header. -
description = "..."
Can be used to define optional description for the response header as str.
Header supported formats:
("x-csrf-token"),
("x-csrf-token" = String, description = "New csrf token"),
§Params Attributes
The list of attributes inside the params(...)
attribute can take two forms: Tuples or IntoParams
Type.
§Tuples
In the tuples format, parameters are specified using the following attributes inside a list of tuples separated by commas:
-
name
Must be the first argument. Define the name for parameter. -
parameter_type
Define possible type for the parameter. Can beType
orinline(Type)
. The givenType
can be any Rust type that is JSON parseable. It can be Option, Vec or Map etc. Withinline(...)
the schema will be inlined instead of a referenced which is the default forToSchema
types. Parameter type is placed aftername
with equals sign E.g."id" = string
-
in
Must be placed after name or parameter_type. Define the place of the parameter. This must be one of the variants ofopenapi::path::ParameterIn
. E.g.Path, Query, Header, Cookie
-
deprecated
Define whether the parameter is deprecated or not. Can optionally be defined with explicitbool
value asdeprecated = bool
. -
description = "..."
Define possible description for the parameter as str. -
style = ...
Defines how parameters are serialized byParameterStyle
. Default values are based onin
attribute. -
explode
Defines whether newparameter=value
is created for each parameter withinobject
orarray
. -
allow_reserved
Defines whether reserved characters:/?#[]@!$&'()*+,;=
is allowed within value. -
example = ...
Can method reference orjson!(...)
. Given example will override any example in underlying parameter type.
§Parameter type attributes
These attributes supported when parameter_type
is present. Either by manually providing one
or otherwise resolved e.g from path macro argument when actix_extras
crate feature is
enabled.
-
format = ...
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 GET -
read_only
Defines property is only used in read operations GET but not in POST,PUT,PATCH -
xml(...)
Can be used to defineXml
object properties for the parameter type. See configuration options at xml attributes ofToSchema
-
nullable
Defines property is nullable (note this is different to non-required). -
multiple_of = ...
Can be used to define multiplier for a value. Value is considered valid division will result aninteger
. Value must be strictly above0
. -
maximum = ...
Can be used to define inclusive upper bound to anumber
value. -
minimum = ...
Can be used to define inclusive lower bound to anumber
value. -
exclusive_maximum = ...
Can be used to define exclusive upper bound to anumber
value. -
exclusive_minimum = ...
Can be used to define exclusive lower bound to anumber
value. -
max_length = ...
Can be used to define maximum length forstring
types. -
min_length = ...
Can be used to define minimum length forstring
types. -
pattern = ...
Can be used to define valid regular expression in ECMA-262 dialect the field value must match. -
max_items = ...
Can be used to define maximum items allowed forarray
fields. Value must be non-negative integer. -
min_items = ...
Can be used to define minimum items allowed forarray
fields. Value must be non-negative integer.
§Parameter Formats
("name" = ParameterType, ParameterIn, ...)
("name", ParameterIn, ...)
For example:
params(
("limit" = i32, Query),
("x-custom-header" = String, Header, description = "Custom header"),
("id" = String, Path, deprecated, description = "Pet database id"),
("name", Path, deprecated, description = "Pet name"),
(
"value" = inline(Option<[String]>),
Query,
description = "Value description",
style = Form,
allow_reserved,
deprecated,
explode,
example = json!(["Value"])),
max_length = 10,
min_items = 1
)
)
§IntoParams Type
In the IntoParams parameters format, the parameters are specified using an identifier for a type
that implements IntoParams
. See IntoParams
for an
example.
params(MyParameters)
Note! that MyParameters
can also be used in combination with the tuples
representation or other structs.
params(
MyParameters1,
MyParameters2,
("id" = String, Path, deprecated, description = "Pet database id"),
)
§Security Requirement Attributes
name
Define the name for security requirement. This must match to name of existingSecurityScheme
.scopes = [...]
Define the list of scopes needed. These must be scopes defined already in existingSecurityScheme
.
Security Requirement supported formats:
(),
("name" = []),
("name" = ["scope1", "scope2"]),
("name" = ["scope1", "scope2"], "name2" = []),
Leaving empty ()
creates an empty SecurityRequirement
this is useful when
security requirement is optional for operation.
You can define multiple security requirements within same parenthesis separated by comma. This allows you to define keys that must be simultaneously provided for the endpoint / API.
Following could be explained as: Security is optional and if provided it must either contain
api_key
or key AND key2
.
(),
("api_key" = []),
("key" = [], "key2" = []),
§actix_extras feature support for actix-web
actix_extras feature gives utoipa ability to parse path operation information from actix-web types and macros.
- Ability to parse
path
from actix-web path attribute macros e.g.#[get(...)]
or#[route(...)]
. - Ability to parse
std::primitive
orString
ortuple
typedpath
parameters from actix-webweb::Path<...>
. - Ability to parse
path
andquery
parameters form actix-webweb::Path<...>
,web::Query<...>
types withIntoParams
trait.
See the actix_extras in action in examples todo-actix.
With actix_extras feature enabled the you can leave out definitions for path, operation and parameter types.
use actix_web::{get, web, HttpResponse, Responder};
use serde_json::json;
/// Get Pet by id
#[utoipa::path(
responses(
(status = 200, description = "Pet found from database")
),
params(
("id", description = "Pet id"),
)
)]
#[get("/pet/{id}")]
async fn get_pet_by_id(id: web::Path<i32>) -> impl Responder {
HttpResponse::Ok().json(json!({ "pet": format!("{:?}", &id.into_inner()) }))
}
With actix_extras you may also not to list any params if you do not want to specify any description for them. Params are resolved from path and the argument types of handler
use actix_web::{get, web, HttpResponse, Responder};
use serde_json::json;
/// Get Pet by id
#[utoipa::path(
responses(
(status = 200, description = "Pet found from database")
)
)]
#[get("/pet/{id}")]
async fn get_pet_by_id(id: web::Path<i32>) -> impl Responder {
HttpResponse::Ok().json(json!({ "pet": format!("{:?}", &id.into_inner()) }))
}
§rocket_extras feature support for rocket
rocket_extras feature enhances path operation parameter support. It gives utoipa ability to parse path
, path parameters
and query parameters
based on arguments given to rocket proc macros such as #[get(...)]
.
- It is able to parse parameter types for primitive types,
String
,Vec
,Option
orstd::path::PathBuf
type. - It is able to determine
parameter_in
forIntoParams
trait used forFromForm
type of query parameters.
See the rocket_extras in action in examples rocket-todo.
§axum_extras feature support for axum
axum_extras feature enhances parameter support for path operation in following ways.
- It allows users to use tuple style path parameters e.g.
Path((id, name)): Path<(i32, String)>
and resolves parameter names and types from it. - It enhances
IntoParams
derive functionality by automatically resolvingparameter_in
fromPath<...>
orQuery<...>
handler function arguments.
Resole path argument types from tuple style handler arguments.
/// Get todo by id and name.
#[utoipa::path(
get,
path = "/todo/{id}",
params(
("id", description = "Todo id"),
("name", description = "Todo name")
),
responses(
(status = 200, description = "Get todo success", body = String)
)
)]
async fn get_todo(
Path((id, name)): Path<(i32, String)>
) -> String {
String::new()
}
Use IntoParams
to resolve query parameters.
#[derive(Deserialize, IntoParams)]
struct TodoSearchQuery {
/// Search by value. Search is incase sensitive.
value: String,
/// Search by `done` status.
done: bool,
}
/// Search Todos by query params.
#[utoipa::path(
get,
path = "/todo/search",
params(
TodoSearchQuery
),
responses(
(status = 200, description = "List matching todos by query", body = [String])
)
)]
async fn search_todos(
query: Query<TodoSearchQuery>,
) -> Json<Vec<String>> {
Json(vec![])
}
§Defining file uploads
File uploads can be defined in accordance to Open API specification file uploads.
Example sending jpg
and png
images as application/octet-stream
.
#[utoipa::path(
post,
request_body(
content(
("image/png"),
("image/jpg"),
),
),
path = "/test_images"
)]
async fn test_images(_body: Vec<u8>) {}
Example of sending multipart
form.
#[derive(utoipa::ToSchema)]
struct MyForm {
order_id: i32,
#[schema(content_media_type = "application/octet-stream")]
file_bytes: Vec<u8>,
}
#[utoipa::path(
post,
request_body(content = inline(MyForm), content_type = "multipart/form-data"),
path = "/test_multipart"
)]
async fn test_multipart(_body: MyForm) {}
Example of sending arbitrary binary content as application/octet-stream
.
#[utoipa::path(
post,
request_body = Vec<u8>,
path = "/test-octet-stream",
responses(
(status = 200, description = "success response")
),
)]
async fn test_octet_stream(_body: Vec<u8>) {}
Example of sending png
image as base64
encoded.
#[derive(utoipa::ToSchema)]
#[schema(content_encoding = "base64")]
struct MyPng(String);
#[utoipa::path(
post,
request_body(content = inline(MyPng), content_type = "image/png"),
path = "/test_png",
responses(
(status = 200, description = "success response")
),
)]
async fn test_png(_body: MyPng) {}
§Examples
More complete example.
#[utoipa::path(
post,
operation_id = "custom_post_pet",
path = "/pet",
tag = "pet_handlers",
request_body(content = Pet, description = "Pet to store the database", content_type = "application/json"),
responses(
(status = 200, description = "Pet stored successfully", body = Pet, content_type = "application/json",
headers(
("x-cache-len" = String, description = "Cache length")
),
example = json!({"id": 1, "name": "bob the cat"})
),
),
params(
("x-csrf-token" = String, Header, deprecated, description = "Current csrf token of user"),
),
security(
(),
("my_auth" = ["read:items", "edit:items"]),
("token_jwt" = [])
)
)]
fn post_pet(pet: Pet) -> Pet {
Pet {
id: 4,
name: "bob the cat".to_string(),
}
}
More minimal example with the defaults.
#[utoipa::path(
post,
path = "/pet",
request_body = Pet,
responses(
(status = 200, description = "Pet stored successfully", body = Pet,
headers(
("x-cache-len", description = "Cache length")
)
),
),
params(
("x-csrf-token", Header, description = "Current csrf token of user"),
)
)]
fn post_pet(pet: Pet) -> Pet {
Pet {
id: 4,
name: "bob the cat".to_string(),
}
}
Use of Rust’s own #[deprecated]
attribute will reflect to the generated OpenAPI spec and mark this operation as deprecated.
#[utoipa::path(
responses(
(status = 200, description = "Pet found from database")
),
params(
("id", description = "Pet id"),
)
)]
#[get("/pet/{id}")]
#[deprecated]
async fn get_pet_by_id(id: web::Path<i32>) -> impl Responder {
HttpResponse::Ok().json(json!({ "pet": format!("{:?}", &id.into_inner()) }))
}
Define context path for endpoint. The resolved path shown in OpenAPI doc will be /api/pet/{id}
.
#[utoipa::path(
context_path = "/api",
responses(
(status = 200, description = "Pet found from database")
)
)]
#[get("/pet/{id}")]
async fn get_pet_by_id(id: web::Path<i32>) -> impl Responder {
HttpResponse::Ok().json(json!({ "pet": format!("{:?}", &id.into_inner()) }))
}
Example with multiple return types
#[utoipa::path(
get,
path = "/user",
responses(
(status = 200, content(
(User1 = "application/vnd.user.v1+json", example = json!({"id": "id".to_string()})),
(User2 = "application/vnd.user.v2+json", example = json!({"id": 2}))
)
)
)
)]
fn get_user() -> Box<dyn User> {
Box::new(User1 {id: "id".to_string()})
}
Example with multiple examples on single response.
#[utoipa::path(
get,
path = "/user",
responses(
(status = 200, body = User,
examples(
("Demo" = (summary = "This is summary", description = "Long description",
value = json!(User{name: "Demo".to_string()}))),
("John" = (summary = "Another user", value = json!({"name": "John"})))
)
)
)
)]
fn get_user() -> User {
User {name: "John".to_string()}
}
Example of using links in response.
#[utoipa::path(
get,
path = "/test-links",
responses(
(status = 200, description = "success response",
links(
("getFoo" = (
operation_id = "test_links",
parameters(("key" = "value"), ("json_value" = json!(1))),
request_body = "this is body",
server(url = "http://localhost")
)),
("getBar" = (
operation_ref = "this is ref"
))
)
)
),
)]
async fn test_links() -> &'static str {
""
}