pub struct OperationBuilder<H = Missing, R = Missing, S = (), A = AuthNotSet, L = LicenseNotSet>{ /* private fields */ }Expand description
Type-safe operation builder with compile-time guarantees.
Generic parameters:
H: Handler state (Missing | Present)R: Response state (Missing | Present)S: Router state type (what you put intoRouter::with_state(S)).A: Auth state (AuthNotSet|AuthSet)L: License requirement state (LicenseNotSet|LicenseSet)
Implementations§
Source§impl<S> OperationBuilder<Missing, Missing, S, AuthNotSet>
impl<S> OperationBuilder<Missing, Missing, S, AuthNotSet>
Source§impl<H, R, S, A, L> OperationBuilder<H, R, S, A, L>
impl<H, R, S, A, L> OperationBuilder<H, R, S, A, L>
Sourcepub fn spec(&self) -> &OperationSpec
pub fn spec(&self) -> &OperationSpec
Inspect the spec (primarily for tests)
Sourcepub fn operation_id(self, id: impl Into<String>) -> Self
pub fn operation_id(self, id: impl Into<String>) -> Self
Set the operation ID
Sourcepub fn require_rate_limit(
&mut self,
rps: u32,
burst: u32,
in_flight: u32,
) -> &mut Self
pub fn require_rate_limit( &mut self, rps: u32, burst: u32, in_flight: u32, ) -> &mut Self
Require per-route rate and concurrency limits. Stores metadata for the gateway to enforce.
Sourcepub fn description(self, text: impl Into<String>) -> Self
pub fn description(self, text: impl Into<String>) -> Self
Set the operation description
Sourcepub fn path_param(
self,
name: impl Into<String>,
description: impl Into<String>,
) -> Self
pub fn path_param( self, name: impl Into<String>, description: impl Into<String>, ) -> Self
Add a path parameter with type inference (defaults to string)
Sourcepub fn query_param(
self,
name: impl Into<String>,
required: bool,
description: impl Into<String>,
) -> Self
pub fn query_param( self, name: impl Into<String>, required: bool, description: impl Into<String>, ) -> Self
Add a query parameter (defaults to string)
Sourcepub fn query_param_typed(
self,
name: impl Into<String>,
required: bool,
description: impl Into<String>,
param_type: impl Into<String>,
) -> Self
pub fn query_param_typed( self, name: impl Into<String>, required: bool, description: impl Into<String>, param_type: impl Into<String>, ) -> Self
Add a typed query parameter with explicit OpenAPI type
Sourcepub fn query_params_from<T: QueryParams>(self) -> Self
pub fn query_params_from<T: QueryParams>(self) -> Self
Register every query parameter declared by a
#[derive(toolkit_contract::QueryParams)] struct.
The generated REST routes use this so the spec and the wire format come
from one declaration. Fields render as scalars or, for Vec fields, as
style: form, explode: true arrays.
Sourcepub fn query_param_array(
self,
name: impl Into<String>,
required: bool,
description: impl Into<String>,
item_type: impl Into<String>,
) -> Self
pub fn query_param_array( self, name: impl Into<String>, required: bool, description: impl Into<String>, item_type: impl Into<String>, ) -> Self
Add a repeating query parameter — ?tag=a&tag=b.
item_type is the OpenAPI type of one element; the parameter renders
as an array with style: form, explode: true, which is the encoding the
generated REST client and its server extractor agree on for a Vec<T>
field.
Sourcepub fn json_request_schema(
self,
schema_name: impl Into<String>,
desc: impl Into<String>,
) -> Self
pub fn json_request_schema( self, schema_name: impl Into<String>, desc: impl Into<String>, ) -> Self
Attach a JSON request body by schema name that you’ve already registered.
This variant sets a description (Some(desc)) and marks the body as required.
Sourcepub fn json_request_schema_no_desc(self, schema_name: impl Into<String>) -> Self
pub fn json_request_schema_no_desc(self, schema_name: impl Into<String>) -> Self
Attach a JSON request body by schema name with no description (None).
Marks the body as required.
Sourcepub fn json_request<T>(
self,
registry: &dyn OpenApiRegistry,
desc: impl Into<String>,
) -> Selfwhere
T: ToSchema + PartialSchema + RequestApiDto + 'static,
pub fn json_request<T>(
self,
registry: &dyn OpenApiRegistry,
desc: impl Into<String>,
) -> Selfwhere
T: ToSchema + PartialSchema + RequestApiDto + 'static,
Attach a JSON request body and auto-register its schema using utoipa.
This variant sets a description (Some(desc)) and marks the body as required.
Sourcepub fn json_request_no_desc<T>(self, registry: &dyn OpenApiRegistry) -> Selfwhere
T: ToSchema + PartialSchema + RequestApiDto + 'static,
pub fn json_request_no_desc<T>(self, registry: &dyn OpenApiRegistry) -> Selfwhere
T: ToSchema + PartialSchema + RequestApiDto + 'static,
Attach a JSON request body (auto-register schema) with no description (None).
Marks the body as required.
Sourcepub fn request_optional(self) -> Self
pub fn request_optional(self) -> Self
Make the previously attached request body optional (if any).
Sourcepub fn multipart_file_request(
self,
field_name: &str,
description: Option<&str>,
) -> Self
pub fn multipart_file_request( self, field_name: &str, description: Option<&str>, ) -> Self
Configure a multipart/form-data file upload request.
This is a convenience helper for file upload endpoints that:
- Sets the request body content type to “multipart/form-data”
- Sets a description for the request body
- Configures an inline object schema with a binary file field
- Restricts allowed Content-Type to only “multipart/form-data”
The file field will be documented in OpenAPI as a binary string with the
given field name. This generates the correct OpenAPI schema for UI tools
like Stoplight to display a file upload control.
§Arguments
field_name- Name of the multipart form field (e.g., “file”)description- Optional description for the request body
§Example
let router = OperationBuilder::post("/files/v1/upload")
.operation_id("upload_file")
.summary("Upload a file")
.multipart_file_request("file", Some("File to upload"))
.anonymous()
.handler(upload_handler)
.json_response(StatusCode::OK, "Upload successful")
.register(router, ®istry);Sourcepub fn octet_stream_request(self, description: Option<&str>) -> Self
pub fn octet_stream_request(self, description: Option<&str>) -> Self
Configure the request body as raw binary (application/octet-stream).
This is intended for endpoints that accept the entire request body as a file or arbitrary bytes, without multipart form encoding.
The OpenAPI schema will be:
requestBody:
required: true
content:
application/octet-stream:
schema:
type: string
format: binaryTools like Stoplight will render this as a single file upload control for the entire body.
§Arguments
description- Optional description for the request body
§Example
let router = OperationBuilder::post("/files/v1/upload")
.operation_id("upload_file")
.summary("Upload a file")
.octet_stream_request(Some("Raw file bytes to parse"))
.anonymous()
.handler(upload_handler)
.json_response(StatusCode::OK, "Upload successful")
.register(router, ®istry);Sourcepub fn allow_content_types(self, types: &[&'static str]) -> Self
pub fn allow_content_types(self, types: &[&'static str]) -> Self
Configure allowed request MIME types for this operation.
This attaches a whitelist of allowed Content-Type values (without parameters), which will be enforced by gateway middleware. If a request arrives with a Content-Type that is not in this list, gateway will return HTTP 415.
This is independent of the request body schema - it only configures gateway
validation and does not affect OpenAPI request body specifications.
§Example
let router = OperationBuilder::post("/files/v1/upload")
.operation_id("upload_file")
.allow_content_types(&["multipart/form-data", "application/pdf"])
.anonymous()
.handler(upload_handler)
.json_response(StatusCode::OK, "Upload successful")
.register(router, ®istry);Sourcepub fn exposed(self) -> Self
pub fn exposed(self) -> Self
Mark this route as publicly visible — registered in the gateway for external access (the visibility axis).
This is independent of authentication (.authenticated() /
.anonymous()): an exposed route may still require a JWT. Routes are
internal by default (not registered in the gateway). Available at any
stage of the builder.
Source§impl<H, R, S> OperationBuilder<H, R, S, AuthSet, LicenseNotSet>where
H: HandlerSlot<S>,
License requirement setting — transitions LicenseNotSet -> LicenseSet
impl<H, R, S> OperationBuilder<H, R, S, AuthSet, LicenseNotSet>where
H: HandlerSlot<S>,
License requirement setting — transitions LicenseNotSet -> LicenseSet
Sourcepub fn require_license_features<F>(
self,
licenses: impl IntoIterator<Item = F>,
) -> OperationBuilder<H, R, S, AuthSet, LicenseSet>where
F: LicenseFeature,
pub fn require_license_features<F>(
self,
licenses: impl IntoIterator<Item = F>,
) -> OperationBuilder<H, R, S, AuthSet, LicenseSet>where
F: LicenseFeature,
Set (or explicitly clear) the license feature requirement for this operation.
This method is only available after the auth requirement has been decided
(i.e. after calling authenticated()).
Mandatory for authenticated endpoints: operations configured with authenticated()
must call require_license_features(...) before register(), because register() is only
available once the license requirement state has transitioned to LicenseSet.
Not available for public endpoints: public routes cannot (and do not need to) call this method.
Pass an empty iterator (e.g. []) to explicitly declare that no license feature is required.
Sourcepub fn no_license_required(
self,
) -> OperationBuilder<H, R, S, AuthSet, LicenseSet>
pub fn no_license_required( self, ) -> OperationBuilder<H, R, S, AuthSet, LicenseSet>
Explicitly declare that this operation does not require any license.
Use this for system/infrastructure endpoints that need authentication but are not gated behind application-level license features.
This transitions from LicenseNotSet to LicenseSet without
attaching any license requirement.
Source§impl<H, R, S, L> OperationBuilder<H, R, S, AuthNotSet, L>where
H: HandlerSlot<S>,
L: LicenseState,
impl<H, R, S, L> OperationBuilder<H, R, S, AuthNotSet, L>where
H: HandlerSlot<S>,
L: LicenseState,
Sourcepub fn authenticated(self) -> OperationBuilder<H, R, S, AuthSet, L>
pub fn authenticated(self) -> OperationBuilder<H, R, S, AuthSet, L>
Mark this route as requiring authentication.
This is a binary marker — the route requires a valid bearer token. Scope enforcement (which scopes are needed) is configured at the gateway level, not per-route.
This method transitions from AuthNotSet to AuthSet state.
§Example
enum License {
Base,
}
impl AsRef<str> for License {
fn as_ref(&self) -> &str {
match self {
License::Base => CORE_GLOBAL_BASE_LICENSE_FEATURE,
}
}
}
impl LicenseFeature for License {}
let router = OperationBuilder::get("/users-info/v1/users")
.authenticated()
.require_license_features::<License>([])
.handler(list_users_handler)
.json_response(axum::http::StatusCode::OK, "List of users")
.register(router, api);
Sourcepub fn anonymous(self) -> OperationBuilder<H, R, S, AuthSet, LicenseSet>
pub fn anonymous(self) -> OperationBuilder<H, R, S, AuthSet, LicenseSet>
Mark this route as anonymous — no authentication required (the auth axis).
A missing Authorization: Bearer header is allowed; a present bearer is
still always re-validated. This explicitly opts out of the
require_auth_by_default setting and maps to the AnonymousRoute marker
in the OoP per-gear middleware. It is independent of visibility — use
exposed to also register the route in the gateway.
This method transitions from AuthNotSet to AuthSet state.
§Example
let router = OperationBuilder::get("/users-info/v1/health")
.anonymous()
.handler(health_check)
.json_response(StatusCode::OK, "OK")
.register(router, ®istry);Sourcepub fn public(self) -> OperationBuilder<H, R, S, AuthSet, LicenseSet>
👎Deprecated since 0.6.21: .public() split into two axes; use .anonymous().exposed() (this alias forwards to exactly that)
pub fn public(self) -> OperationBuilder<H, R, S, AuthSet, LicenseSet>
.public() split into two axes; use .anonymous().exposed() (this alias forwards to exactly that)
Deprecated alias for the old single-axis .public().
The old .public() meant both anonymous (no auth) and edge
visible. Those are now separate axes: anonymous
(auth) and exposed (visibility). This shim maps to
.anonymous().exposed() so out-of-tree gears keep compiling for one
release; a bare .anonymous() (the naive mechanical replacement) would
silently drop the route from the edge, which this warning surfaces at
compile time instead.
Source§impl<R, S, A, L> OperationBuilder<Missing, R, S, A, L>
impl<R, S, A, L> OperationBuilder<Missing, R, S, A, L>
Sourcepub fn handler<F, T>(self, h: F) -> OperationBuilder<Present, R, S, A, L>
pub fn handler<F, T>(self, h: F) -> OperationBuilder<Present, R, S, A, L>
Set the handler for this operation (function handlers are recommended).
This transitions the builder from Missing to Present handler state.
Sourcepub fn method_router(
self,
mr: MethodRouter<S>,
) -> OperationBuilder<Present, R, S, A, L>
pub fn method_router( self, mr: MethodRouter<S>, ) -> OperationBuilder<Present, R, S, A, L>
Alternative path: provide a pre-composed MethodRouter<S> yourself
(useful to attach per-route middleware/layers).
Source§impl<H, S, A, L> OperationBuilder<H, Missing, S, A, L>
impl<H, S, A, L> OperationBuilder<H, Missing, S, A, L>
Sourcepub fn response(
self,
resp: ResponseSpec,
) -> OperationBuilder<H, Present, S, A, L>
pub fn response( self, resp: ResponseSpec, ) -> OperationBuilder<H, Present, S, A, L>
Add a raw response spec (transitions from Missing to Present).
Sourcepub fn json_response(
self,
status: StatusCode,
description: impl Into<String>,
) -> OperationBuilder<H, Present, S, A, L>
pub fn json_response( self, status: StatusCode, description: impl Into<String>, ) -> OperationBuilder<H, Present, S, A, L>
Add a JSON response (transitions from Missing to Present).
Sourcepub fn no_content_response(
self,
status: StatusCode,
description: impl Into<String>,
) -> OperationBuilder<H, Present, S, A, L>
pub fn no_content_response( self, status: StatusCode, description: impl Into<String>, ) -> OperationBuilder<H, Present, S, A, L>
Add a body-less response (e.g. 204 No Content) — transitions from
Missing to Present.
OpenAPI consumers and code-generators treat a 204 response with a
content block as advertising a body, which is incorrect. Use this
helper for any handler that intentionally returns no payload (typical
for DELETE / PUT semantics).
Sourcepub fn json_response_with_schema<T>(
self,
registry: &dyn OpenApiRegistry,
status: StatusCode,
description: impl Into<String>,
) -> OperationBuilder<H, Present, S, A, L>where
T: ToSchema + PartialSchema + ResponseApiDto + 'static,
pub fn json_response_with_schema<T>(
self,
registry: &dyn OpenApiRegistry,
status: StatusCode,
description: impl Into<String>,
) -> OperationBuilder<H, Present, S, A, L>where
T: ToSchema + PartialSchema + ResponseApiDto + 'static,
Add a JSON response with a registered schema (transitions from Missing to Present).
Sourcepub fn json_array_response_with_schema<T>(
self,
registry: &dyn OpenApiRegistry,
status: StatusCode,
description: impl Into<String>,
) -> OperationBuilder<H, Present, S, A, L>where
T: ToSchema + PartialSchema + ResponseApiDto + 'static,
pub fn json_array_response_with_schema<T>(
self,
registry: &dyn OpenApiRegistry,
status: StatusCode,
description: impl Into<String>,
) -> OperationBuilder<H, Present, S, A, L>where
T: ToSchema + PartialSchema + ResponseApiDto + 'static,
Add a JSON response whose body is a top-level array of T
(transitions from Missing to Present).
T is the item type — pass GearDto, not Vec<GearDto>. Registers
T as a named component and emits an inline
{type: array, items: {$ref: T}} schema for the response body.
Never pass Vec<T> to Self::json_response_with_schema: utoipa’s
default ToSchema::name() strips generic arguments, so every Vec<_>
registers under the single component name Vec and two such responses
collide fatally in OpenApiRegistryImpl::ensure_schema_raw.
Sourcepub fn text_response(
self,
status: StatusCode,
description: impl Into<String>,
content_type: &'static str,
) -> OperationBuilder<H, Present, S, A, L>
pub fn text_response( self, status: StatusCode, description: impl Into<String>, content_type: &'static str, ) -> OperationBuilder<H, Present, S, A, L>
Add a text response with a custom content type (transitions from Missing to Present).
§Arguments
status- HTTP status codedescription- Description of the responsecontent_type- Pure media type without parameters (e.g.,"text/plain","text/markdown")
§Important
The content_type must be a pure media type without parameters like ; charset=utf-8.
OpenAPI media type keys cannot include parameters. Use "text/markdown" instead of
"text/markdown; charset=utf-8". Actual HTTP response headers in handlers should still
include the charset parameter.
Sourcepub fn html_response(
self,
status: StatusCode,
description: impl Into<String>,
) -> OperationBuilder<H, Present, S, A, L>
pub fn html_response( self, status: StatusCode, description: impl Into<String>, ) -> OperationBuilder<H, Present, S, A, L>
Add an HTML response (transitions from Missing to Present).
Sourcepub fn problem_response(
self,
registry: &dyn OpenApiRegistry,
status: StatusCode,
description: impl Into<String>,
) -> OperationBuilder<H, Present, S, A, L>
pub fn problem_response( self, registry: &dyn OpenApiRegistry, status: StatusCode, description: impl Into<String>, ) -> OperationBuilder<H, Present, S, A, L>
Add an RFC 9457 application/problem+json response (transitions from Missing to Present).
Sourcepub fn sse_json<T>(
self,
openapi: &dyn OpenApiRegistry,
description: impl Into<String>,
) -> OperationBuilder<H, Present, S, A, L>where
T: ToSchema + PartialSchema + ResponseApiDto + 'static,
pub fn sse_json<T>(
self,
openapi: &dyn OpenApiRegistry,
description: impl Into<String>,
) -> OperationBuilder<H, Present, S, A, L>where
T: ToSchema + PartialSchema + ResponseApiDto + 'static,
First response: SSE stream of JSON events (text/event-stream).
Sourcepub fn multipart_json<T>(
self,
openapi: &dyn OpenApiRegistry,
description: impl Into<String>,
) -> OperationBuilder<H, Present, S, A, L>where
T: ToSchema + PartialSchema + ResponseApiDto + 'static,
pub fn multipart_json<T>(
self,
openapi: &dyn OpenApiRegistry,
description: impl Into<String>,
) -> OperationBuilder<H, Present, S, A, L>where
T: ToSchema + PartialSchema + ResponseApiDto + 'static,
First response: multipart/mixed stream of JSON items, one item per
body part — the server-to-server counterpart to Self::sse_json.
T is the item type, exactly as for SSE: the media-type key in the
spec is the bare multipart/mixed, with no boundary= parameter,
because the boundary is generated per response at runtime by
crate::http::multipart::MultipartJsonStream and is not a property of
the operation.
Source§impl<H, S, A, L> OperationBuilder<H, Present, S, A, L>
impl<H, S, A, L> OperationBuilder<H, Present, S, A, L>
Sourcepub fn response_header(self, header: ResponseHeaderSpec) -> Self
pub fn response_header(self, header: ResponseHeaderSpec) -> Self
Declare a header on the most recently declared response.
Call this immediately after the response declaration it describes. Consecutive calls attach multiple headers to that same response.
§Panics
Panics when the response status already has a header with the same case-insensitive name.
Sourcepub fn json_response(
self,
status: StatusCode,
description: impl Into<String>,
) -> Self
pub fn json_response( self, status: StatusCode, description: impl Into<String>, ) -> Self
Add a JSON response (additional).
Sourcepub fn no_content_response(
self,
status: StatusCode,
description: impl Into<String>,
) -> Self
pub fn no_content_response( self, status: StatusCode, description: impl Into<String>, ) -> Self
Add a body-less response (e.g. 204 No Content) — additional variant.
Sourcepub fn json_response_with_schema<T>(
self,
registry: &dyn OpenApiRegistry,
status: StatusCode,
description: impl Into<String>,
) -> Selfwhere
T: ToSchema + PartialSchema + ResponseApiDto + 'static,
pub fn json_response_with_schema<T>(
self,
registry: &dyn OpenApiRegistry,
status: StatusCode,
description: impl Into<String>,
) -> Selfwhere
T: ToSchema + PartialSchema + ResponseApiDto + 'static,
Add a JSON response with a registered schema (additional).
Sourcepub fn json_array_response_with_schema<T>(
self,
registry: &dyn OpenApiRegistry,
status: StatusCode,
description: impl Into<String>,
) -> Selfwhere
T: ToSchema + PartialSchema + ResponseApiDto + 'static,
pub fn json_array_response_with_schema<T>(
self,
registry: &dyn OpenApiRegistry,
status: StatusCode,
description: impl Into<String>,
) -> Selfwhere
T: ToSchema + PartialSchema + ResponseApiDto + 'static,
Add a JSON response whose body is a top-level array of T (additional).
T is the item type — pass GearDto, not Vec<GearDto>. See
OperationBuilder::json_array_response_with_schema on the
Missing-response builder for why arrays are emitted inline.
Sourcepub fn text_response(
self,
status: StatusCode,
description: impl Into<String>,
content_type: &'static str,
) -> Self
pub fn text_response( self, status: StatusCode, description: impl Into<String>, content_type: &'static str, ) -> Self
Add a text response with a custom content type (additional).
§Arguments
status- HTTP status codedescription- Description of the responsecontent_type- Pure media type without parameters (e.g.,"text/plain","text/markdown")
§Important
The content_type must be a pure media type without parameters like ; charset=utf-8.
OpenAPI media type keys cannot include parameters. Use "text/markdown" instead of
"text/markdown; charset=utf-8". Actual HTTP response headers in handlers should still
include the charset parameter.
Sourcepub fn html_response(
self,
status: StatusCode,
description: impl Into<String>,
) -> Self
pub fn html_response( self, status: StatusCode, description: impl Into<String>, ) -> Self
Add an HTML response (additional).
Sourcepub fn problem_response(
self,
registry: &dyn OpenApiRegistry,
status: StatusCode,
description: impl Into<String>,
) -> Self
pub fn problem_response( self, registry: &dyn OpenApiRegistry, status: StatusCode, description: impl Into<String>, ) -> Self
Add an additional RFC 9457 application/problem+json response.
Sourcepub fn sse_json<T>(
self,
openapi: &dyn OpenApiRegistry,
description: impl Into<String>,
) -> Selfwhere
T: ToSchema + PartialSchema + ResponseApiDto + 'static,
pub fn sse_json<T>(
self,
openapi: &dyn OpenApiRegistry,
description: impl Into<String>,
) -> Selfwhere
T: ToSchema + PartialSchema + ResponseApiDto + 'static,
Additional SSE response (if the operation already has a response).
Sourcepub fn multipart_json<T>(
self,
openapi: &dyn OpenApiRegistry,
description: impl Into<String>,
) -> Selfwhere
T: ToSchema + PartialSchema + ResponseApiDto + 'static,
pub fn multipart_json<T>(
self,
openapi: &dyn OpenApiRegistry,
description: impl Into<String>,
) -> Selfwhere
T: ToSchema + PartialSchema + ResponseApiDto + 'static,
Additional multipart/mixed response (if the operation already has
one). See OperationBuilder::multipart_json on the first-response
builder for what T and the media-type key mean.
Sourcepub fn standard_errors(self, registry: &dyn OpenApiRegistry) -> Self
pub fn standard_errors(self, registry: &dyn OpenApiRegistry) -> Self
Add standard error responses (400, 401, 403, 404, 409, 422, 429, 500).
All responses reference the shared Problem schema (RFC 9457) for consistent error handling across your API. This is the recommended way to declare common error responses without repeating boilerplate.
§Example
let op = OperationBuilder::get("/user-info/v1/users")
.anonymous()
.handler(list_users)
.json_response(StatusCode::OK, "List of users")
.standard_errors(®istry);
let router = op.register(router, ®istry);This adds the following error responses:
- 400 Bad Request
- 401 Unauthorized
- 403 Forbidden
- 404 Not Found
- 409 Conflict
- 429 Too Many Requests
- 500 Internal Server Error
413/415/422 are intentionally absent here: canonical InvalidArgument
maps to 400 per docs/arch/errors/DESIGN.md §1.2, so no
canonical-handler path alone produces those statuses. An operation
whose handler takes toolkit::api::rest::extract::Json<T> can produce
all three (oversized body, wrong Content-Type, schema violation) -
add Self::error_413/Self::error_415/Self::error_422
individually for such an operation.
Sourcepub fn with_400_validation_error(self, registry: &dyn OpenApiRegistry) -> Self
pub fn with_400_validation_error(self, registry: &dyn OpenApiRegistry) -> Self
Add 400 validation error response using the canonical Problem schema.
Field-level violations surface under context.field_violations[]
(canonical InvalidArgument category, HTTP 400 per
docs/arch/errors/DESIGN.md §1.2 / §3.5).
§Example
#[toolkit_macros::api_dto(request)]
struct CreateUserRequest {
email: String,
}
let op = OperationBuilder::post("/users-info/v1/users")
.anonymous()
.handler(create_user)
.json_request::<CreateUserRequest>(®istry, "User data")
.json_response(StatusCode::CREATED, "User created")
.with_400_validation_error(®istry);
let router = op.register(router, ®istry);Sourcepub fn error_400(self, registry: &dyn OpenApiRegistry) -> Self
pub fn error_400(self, registry: &dyn OpenApiRegistry) -> Self
Add a 400 Bad Request error response.
This is a convenience wrapper around problem_response.
Sourcepub fn error_401(self, registry: &dyn OpenApiRegistry) -> Self
pub fn error_401(self, registry: &dyn OpenApiRegistry) -> Self
Add a 401 Unauthorized error response.
This is a convenience wrapper around problem_response.
Sourcepub fn error_403(self, registry: &dyn OpenApiRegistry) -> Self
pub fn error_403(self, registry: &dyn OpenApiRegistry) -> Self
Add a 403 Forbidden error response.
This is a convenience wrapper around problem_response.
Sourcepub fn error_404(self, registry: &dyn OpenApiRegistry) -> Self
pub fn error_404(self, registry: &dyn OpenApiRegistry) -> Self
Add a 404 Not Found error response.
This is a convenience wrapper around problem_response.
Sourcepub fn error_409(self, registry: &dyn OpenApiRegistry) -> Self
pub fn error_409(self, registry: &dyn OpenApiRegistry) -> Self
Add a 409 Conflict error response.
This is a convenience wrapper around problem_response.
Sourcepub fn error_413(self, registry: &dyn OpenApiRegistry) -> Self
pub fn error_413(self, registry: &dyn OpenApiRegistry) -> Self
Add a 413 Payload Too Large error response.
This is a convenience wrapper around problem_response. Relevant to
any operation whose handler takes
toolkit::api::rest::extract::Json<T>
as a parameter - an oversized request body produces this status.
Sourcepub fn error_415(self, registry: &dyn OpenApiRegistry) -> Self
pub fn error_415(self, registry: &dyn OpenApiRegistry) -> Self
Add a 415 Unsupported Media Type error response.
This is a convenience wrapper around problem_response.
Sourcepub fn error_422(self, registry: &dyn OpenApiRegistry) -> Self
pub fn error_422(self, registry: &dyn OpenApiRegistry) -> Self
Add a 422 Unprocessable Entity error response.
This is a convenience wrapper around problem_response.
Sourcepub fn error_429(self, registry: &dyn OpenApiRegistry) -> Self
pub fn error_429(self, registry: &dyn OpenApiRegistry) -> Self
Add a 429 Too Many Requests error response.
This is a convenience wrapper around problem_response.
Sourcepub fn error_500(self, registry: &dyn OpenApiRegistry) -> Self
pub fn error_500(self, registry: &dyn OpenApiRegistry) -> Self
Add a 500 Internal Server Error response.
This is a convenience wrapper around problem_response.
Sourcepub fn error_502(self, registry: &dyn OpenApiRegistry) -> Self
pub fn error_502(self, registry: &dyn OpenApiRegistry) -> Self
Add a 502 Bad Gateway error response.
This is a convenience wrapper around problem_response.
Sourcepub fn error_503(self, registry: &dyn OpenApiRegistry) -> Self
pub fn error_503(self, registry: &dyn OpenApiRegistry) -> Self
Add a 503 Service Unavailable error response.
This is a convenience wrapper around problem_response.
Sourcepub fn error_504(self, registry: &dyn OpenApiRegistry) -> Self
pub fn error_504(self, registry: &dyn OpenApiRegistry) -> Self
Add a 504 Gateway Timeout error response.
This is a convenience wrapper around problem_response.
Source§impl<S> OperationBuilder<Present, Present, S, AuthSet, LicenseSet>
impl<S> OperationBuilder<Present, Present, S, AuthSet, LicenseSet>
Sourcepub fn register(
self,
router: Router<S>,
openapi: &dyn OpenApiRegistry,
) -> Router<S>
pub fn register( self, router: Router<S>, openapi: &dyn OpenApiRegistry, ) -> Router<S>
Register the operation with the router and OpenAPI registry.
This method is only available when:
- Handler is present
- Response is present
- Auth requirement is set (either
authenticatedorpublic)
All conditions are enforced at compile time by the type system.
Trait Implementations§
Source§impl<S, H, R, A, L> OperationBuilderODataExt<S, H, R> for OperationBuilder<H, R, S, A, L>
impl<S, H, R, A, L> OperationBuilderODataExt<S, H, R> for OperationBuilder<H, R, S, A, L>
Source§fn with_odata_filter<T>(self) -> Selfwhere
T: FilterField,
fn with_odata_filter<T>(self) -> Selfwhere
T: FilterField,
$filter query parameter to OpenAPI.Source§fn with_odata_select(self) -> Self
fn with_odata_select(self) -> Self
$select query parameter to OpenAPI.Source§fn with_odata_orderby<T>(self) -> Selfwhere
T: FilterField,
fn with_odata_orderby<T>(self) -> Selfwhere
T: FilterField,
$orderby query parameter to OpenAPI.Auto Trait Implementations§
impl<H, R, S, A, L> Freeze for OperationBuilder<H, R, S, A, L>where
<H as HandlerSlot<S>>::Slot: Freeze,
PhantomData<H>: Freeze,
PhantomData<R>: Freeze,
PhantomData<fn() -> S>: Freeze,
PhantomData<A>: Freeze,
PhantomData<L>: Freeze,
impl<H, R, S, A, L> RefUnwindSafe for OperationBuilder<H, R, S, A, L>where
<H as HandlerSlot<S>>::Slot: RefUnwindSafe,
PhantomData<H>: RefUnwindSafe,
PhantomData<R>: RefUnwindSafe,
PhantomData<fn() -> S>: RefUnwindSafe,
PhantomData<A>: RefUnwindSafe,
PhantomData<L>: RefUnwindSafe,
impl<H, R, S, A, L> Send for OperationBuilder<H, R, S, A, L>where
<H as HandlerSlot<S>>::Slot: Send,
PhantomData<H>: Send,
PhantomData<R>: Send,
PhantomData<fn() -> S>: Send,
PhantomData<A>: Send,
PhantomData<L>: Send,
impl<H, R, S, A, L> Sync for OperationBuilder<H, R, S, A, L>where
<H as HandlerSlot<S>>::Slot: Sync,
PhantomData<H>: Sync,
PhantomData<R>: Sync,
PhantomData<fn() -> S>: Sync,
PhantomData<A>: Sync,
PhantomData<L>: Sync,
impl<H, R, S, A, L> Unpin for OperationBuilder<H, R, S, A, L>where
<H as HandlerSlot<S>>::Slot: Unpin,
PhantomData<H>: Unpin,
PhantomData<R>: Unpin,
PhantomData<fn() -> S>: Unpin,
PhantomData<A>: Unpin,
PhantomData<L>: Unpin,
impl<H, R, S, A, L> UnsafeUnpin for OperationBuilder<H, R, S, A, L>where
<H as HandlerSlot<S>>::Slot: UnsafeUnpin,
PhantomData<H>: UnsafeUnpin,
PhantomData<R>: UnsafeUnpin,
PhantomData<fn() -> S>: UnsafeUnpin,
PhantomData<A>: UnsafeUnpin,
PhantomData<L>: UnsafeUnpin,
impl<H, R, S, A, L> UnwindSafe for OperationBuilder<H, R, S, A, L>where
<H as HandlerSlot<S>>::Slot: UnwindSafe,
PhantomData<H>: UnwindSafe,
PhantomData<R>: UnwindSafe,
PhantomData<fn() -> S>: UnwindSafe,
PhantomData<A>: UnwindSafe,
PhantomData<L>: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
Source§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::RequestSource§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T> ServiceExt for T
impl<T> ServiceExt for T
Source§fn map_response_body<F>(self, f: F) -> MapResponseBody<Self, F>where
Self: Sized,
fn map_response_body<F>(self, f: F) -> MapResponseBody<Self, F>where
Self: Sized,
Source§fn decompression(self) -> Decompression<Self>where
Self: Sized,
fn decompression(self) -> Decompression<Self>where
Self: Sized,
Source§fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>where
Self: Sized,
fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>where
Self: Sized,
Source§fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>where
Self: Sized,
fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>where
Self: Sized,
Source§fn follow_redirects(self) -> FollowRedirect<Self>where
Self: Sized,
fn follow_redirects(self) -> FollowRedirect<Self>where
Self: Sized,
Source§fn set_request_id<M>(
self,
header_name: HeaderName,
make_request_id: M,
) -> SetRequestId<Self, M>where
Self: Sized,
M: MakeRequestId,
fn set_request_id<M>(
self,
header_name: HeaderName,
make_request_id: M,
) -> SetRequestId<Self, M>where
Self: Sized,
M: MakeRequestId,
Source§fn set_x_request_id<M>(self, make_request_id: M) -> SetRequestId<Self, M>where
Self: Sized,
M: MakeRequestId,
fn set_x_request_id<M>(self, make_request_id: M) -> SetRequestId<Self, M>where
Self: Sized,
M: MakeRequestId,
x-request-id as the header name. Read moreSource§fn propagate_request_id(
self,
header_name: HeaderName,
) -> PropagateRequestId<Self>where
Self: Sized,
fn propagate_request_id(
self,
header_name: HeaderName,
) -> PropagateRequestId<Self>where
Self: Sized,
Source§fn propagate_x_request_id(self) -> PropagateRequestId<Self>where
Self: Sized,
fn propagate_x_request_id(self) -> PropagateRequestId<Self>where
Self: Sized,
x-request-id as the header name. Read moreSource§fn catch_panic(self) -> CatchPanic<Self, DefaultResponseForPanic>where
Self: Sized,
fn catch_panic(self) -> CatchPanic<Self, DefaultResponseForPanic>where
Self: Sized,
500 Internal Server responses. Read moreSource§fn request_body_limit(self, limit: usize) -> RequestBodyLimit<Self>where
Self: Sized,
fn request_body_limit(self, limit: usize) -> RequestBodyLimit<Self>where
Self: Sized,
413 Payload Too Large responses. Read moreSource§impl<T> WithSecurityContext for T
impl<T> WithSecurityContext for T
Source§fn security_ctx<'a>(&'a self, ctx: &'a SecurityContext) -> Secured<'a, T>where
T: Sized,
fn security_ctx<'a>(&'a self, ctx: &'a SecurityContext) -> Secured<'a, T>where
T: Sized,
Secured wrapper. Read more