**Request Validation**
use validator::Validate;
#[derive(Debug, Deserialize, Validate, ToSchema)]
pub struct CreateUserRequest {
#[validate(email)]
#[schema(example = "user@example.com")]
pub email: String,
#[validate(length(min = 8, max = 64))]
pub password: String,
#[validate(length(min = 1, max = 100))]
#[schema(example = "Jane Doe")]
pub name: String,
}
pub async fn create_user(
State(state): State<AppState>,
Json(req): Json<CreateUserRequest>,
) -> Result<Json<UserResponse>, AppError> {
req.validate()?;
// ...
}
**OpenAPI with utoipa**
#[utoipa::path(
post,
path = "/users",
tag = "users",
request_body = CreateUserRequest,
responses(
(status = 201, description = "User created", body = UserResponse),
(status = 400, description = "Validation error")
)
)]
pub async fn create_user(/* ... */) { }
#[derive(OpenApi)]
#[openapi(
info(title = "My API", version = "1.0.0"),
tags((name = "users", description = "User management"))
)]
struct ApiDoc;
pub fn create_router(state: AppState) -> Router {
let (router, api) = OpenApiRouter::with_openapi(ApiDoc::openapi())
.routes(routes!(create_user))
.split_for_parts();
router
.merge(SwaggerUi::new("/swagger-ui").url("/api-docs/openapi.json", api))
.with_state(state)
}