Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
restful
Request and response helpers for Rust. Ordering and pagination metadata are always available; the other modules are feature-gated.
Features
| Feature | What it enables |
|---|---|
response (default) |
JSON API envelopes, metadata, errors, and Axum IntoResponse |
axum |
Validated JSON, form, and query extractors; also enables response |
projection |
Field-selection parsing and validation |
macros |
Macro exports in ordering, pagination, and, when enabled, projection |
field-delta |
Re-exports field_delta::Delta as restful::Delta |
pgkit |
Sort-direction conversion; column selections with projection |
utoipa |
Schema support for runtime types and an enabled field-delta dependency |
full |
All features above |
Use default-features = false for ordering and pagination metadata alone.
The response feature includes Axum even without the extractor feature.
Macro-generated code may need direct Serde, Valid8r, Utoipa, or Pgkit
dependencies; enabling a feature does not add imports to your application.
Responses and pagination
Add serde_json = "1" to run this example. It uses the default features:
use OffsetPaginationMetadata;
use ;
let pagination = new;
let meta = paginated;
let response = ok.unwrap;
assert_eq!;
assert_eq!;
let error = from;
assert_eq!;
Success envelopes contain data and optional meta; failures contain
error with type, message, and optional details. created uses 201,
accepted uses 202, and no_content produces an empty 204 response.
Offset metadata clamps page size to at least one and the page to the available
range. Cursor metadata sets has_more from whether next_cursor is present.
Add custom metadata with .set(key, serde_json::Value). Custom fields appear
directly inside meta, alongside pagination. Start with ResponseMetadata::default()
for a response without pagination:
use ;
use json;
let mut meta = default;
meta.set.unwrap;
meta.set.unwrap;
let response = ok.unwrap;
let json = to_value.unwrap;
assert_eq!;
assert_eq!;
assert!;
Repeated custom keys replace their previous values. The "pagination" key is
reserved; .set() returns ReservedKeyError for it. Convert typed metadata with
serde_json::to_value(value)? before adding it. With utoipa, custom fields are
represented by an open object schema rather than individual typed properties.
Validated requests
Enable axum and add direct serde (with derive) and valid8r = "0.2.2"
dependencies. This handler accepts only JSON values that pass validation:
use ValidatedJson;
use ApiResponse;
use ;
use Validate;
async
ValidatedForm validates form data; ValidatedQuery validates URL queries.
They all require DeserializeOwned + valid8r::Validate.
Validation failures use 422. JSON data errors with a field path also use 422; root JSON data errors, malformed input, and form/query deserialization errors use 400. Body limits use 413; rejected body content types use 415.
Validation error keys follow a camelCase policy. Use
#[serde(rename_all = "camelCase")] and avoid conflicting field renames when
keys must match the request. Nested list errors retain their indices as object
keys, such as "items": {"1": {...}}.
Built-in deserialization messages are sanitized, but error paths can include
client-sent keys. Keep input out of custom deserializer messages. Validation
errors retain Valid8r parameters; use #[validate(sensitive)] on sensitive
fields and keep secrets out of custom messages and parameters.
Field selection and PATCH
With projection, Projection<T>::from(String) stores parsing errors rather
than returning a Result. Check is_valid() or call validate() before using
its fields. Deserializing alone does not run validation.
With projection and macros, the ProjectionField and PartialResponse
derives support parsing field names and building partial response types.
They do not apply a projection to an existing response. See Projection's API
documentation for selection syntax and ProjectionField's for Pgkit column mapping.
End to end, the application checks the parsed fields and fills the partial:
use ;
// From ?fields=id,note
let fields = from;
assert!;
let mut partial = default;
if fields.fields.contains
if fields.fields.contains
assert_eq!;
With field-delta, restful::Delta<T> represents unchanged, clear, and set
PATCH values. Use #[serde(default)] on a Delta field to treat omitted input
as unchanged.