Attribute Macro utoipa::path

source · []
#[path]
Expand description

Path attribute macro

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 addtional 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.

Path Attributes

  • operation Must be first parameter! Accepted values are known http operations suchs as get, post, put, delete, head, options, connect, patch, trace.
  • path = "..." Must be OpenAPI format compatible str with arguments withing curly braces. E.g {id}
  • operation_id = "..." Unique operation id for the enpoint. By default this is mapped to function name.
  • context_path = "..." Can add optional scope for path. The context_path will be prepended to begining 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 groupped together. By default this is derived from the handler that is given to OpenApi. If derive results empty str then default value crate is used instead.
  • 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 of SecurityRequirements local to the path operation.

Request Body Attributes

  • content = ... Can be used to define the content object. Should be an identifier, slice or option E.g. Pet or [Pet] or Option<Pet>.
  • description = "..." Define the description for the request body object as str.
  • content_type = "..." Can be used to override the default behaviour of auto resolving the content type from the content attribute. If defined the value should be valid content type such as application/json. By default the content type is text/plain for primitive Rust types and application/json for struct and complex enum types.

Request body supports following formats:

request_body(content = String, description = "Xml as string request", content_type = "text/xml"),
request_body = Pet,
request_body = Option<[Pet]>,
  1. First is the long representation of the request body definition.
  2. Second is the quick format which only defines the content object type.
  3. Last one is same quick format but only with optional request body.

Responses Attributes

  • status = ... Is valid http status code. E.g. 200
  • 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. Should be an identifier or slice. E.g Pet or [Pet]
  • content_type = "..." | content_type = [...] Can be used to override the default behaviour of auto resolving the content type from the body attribute. If defined the value should be valid content type such as application/json. By default the content type is text/plain for primitive Rust types and application/json for 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 both json and xml formats.
  • headers(...) Slice of response headers that are returned back to a caller.
  • example = ... Can be either json!(...) or literal str that can be parsed to json. json! should be something that serde_json::json! can parse as a serde_json::Value. 1

Minimal response format:

(status = 200, description = "success response")

Response with all possible values:

(status = 200, description = "Success response", body = Pet, content_type = "application/json",
    headers(...),
    example = json!({"id": 1, "name": "bob the cat"})
)

Response with multiple response content types:

(status = 200, description = "Success response", body = Pet, content_type = ["application/json", "text/xml"])

Response Header Attributes

  • name Name of the header. E.g. x-csrf-token
  • type Addtional type of the header value. Type is defined after name with equals sign before the type. Type should be identifer or slice of identifiers. E.g. String or [String]
  • description = "..." Can be used to define optional description for the response header as str.

Header supported formats:

("x-csfr-token"),
("x-csrf-token" = String, description = "New csfr token"),

Params Attributes

  • name Must be the first argument. Define the name for parameter.
  • parameter_type Define possible type for the parameter. Type should be an identifer, slice or option. E.g. String or [String] or Option<String>. Parameter type is placed after name with equals sign E.g. "id" = String
  • in Must be placed after name or parameter_type. Define the place of the parameter. E.g. path, query, header, cookie
  • deprecated Define whether the parameter is deprecated or not.
  • description = "..." Define possible description for the parameter as str.
  • style = ... Defines how parameters are serialized by ParameterStyle. Default values are based on in attribute.
  • explode Defines whether new parameter=value is created for each parameter withing object or array.
  • allow_reserved Defines whether reserved charachers :/?#[]@!$&'()*+,;= is allowed within value.
  • example = ... Can be literal value, method reference or json!(...). 1. Given example will override any example in underlying parameter type.

Params supports following representation formats:

("id" = String, path, deprecated, description = "Pet database id"),
("id", path, deprecated, description = "Pet database id"),
("value" = Option<[String]>, query, description = "Value description", style = Form, allow_reserved, deprecated, explode, example = json!(["Value"]))

Security Requirement Attributes

  • name Define the name for security requirement. This must match to name of existing SecuritySchema.
  • scopes = [...] Define the list of scopes needed. These must be scopes defined already in existing SecuritySchema.

Security Requirement supported formats:

(),
("name" = []),
("name" = ["scope1", "scope2"]),

Leaving empty () creates an empty SecurityRequirement this is useful when security requirement is optional for operation.

actix_extras support for actix-web

actix_extras featue gives utoipa ability to parse path operation information from actix-web types and macros.

  1. Ability to parse path from actix-web path attribute macros e.g. #[get(...)].
  2. Ability to parse std::primitive or String or tuple typed path parameters from actix-web web::Path<...>.
  3. Ability to parse path and query parameters form actix-web web::Path<...>, web::Query<...> types with IntoParams 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 parmater types 2.

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 parmas if you do not want to specify any description for them. Params are resolved from path and the argument types of handler. 2

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 support for rocket

rocket_extras feature gives utoipa ability to use rocket path operation macros such as #[get(...)] to resolve path for #[utoipa::path]. Also it is able to parse the path and query parameters from path operation macro combined with function arguments of the operation. Allowing you leave out types from parameters in params(...) section or even leave out the section if description is not needed for parameters. Utoipa is only able to parse parameter types for primitive types, String, Vec, Option or std::path::PathBuf type. Other function arguments are simply ignored.

See the rocket_extras in action in examples rocket-todo.

Examples

Example with all possible arguments.

#[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 refect 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()) }))
}

  1. json feature need to be enabled for json!(...) type to work. 

  2. actix_extras feature need to be enabled and actix-web framework must be declared in your Cargo.toml