1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
//! Shared response types for Axum JSON APIs.
//!
//! Provides building blocks that every Axum CRUD service needs but always
//! re-defines from scratch:
//!
//! - [`ApiError`] - a machine-readable JSON error body with `code`, `message`, and optional
//! `details`, plus factory helpers that return `(StatusCode, Json<ApiError>)` tuples ready
//! for use with Axum's [`IntoResponse`](axum::response::IntoResponse). Supports `From`
//! conversions for common error types. With the optional `validator` feature enabled,
//! also supports converting `validator::ValidationErrors` into structured field errors.
//! With the optional `sqlx` feature enabled, also supports converting `sqlx::Error` into
//! semantically correct HTTP status codes (404, 409, 422, 503, 500).
//! - [`ListResponse<T>`] - a generic offset/limit paginated collection response with `data`,
//! `total`, `limit`, and `offset` fields.
//! - [`CursorResponse<T>`] - a generic cursor-based paginated collection response for large
//! datasets or feeds, with `data`, `next_cursor`, and `has_more` fields.
//! - [`HealthResponse`] - a health-check response with `status` field supporting `ok`,
//! `degraded`, and `unhealthy` states.
//!
//! With optional feature flags enabled, the kit also provides request extractors that
//! reject with an [`ApiError`] body on failure:
//!
//! - `ValidatedJson<T>` (feature `validator`) - deserializes a JSON body and runs
//! `validator` validation before the handler runs.
//! - `Pagination` and `CursorPagination` (feature `extract`) - parse `limit`/`offset` and
//! `cursor`/`limit` query parameters into typed values, with `list_response` /
//! `cursor_response` helpers that build the matching response type.
//!
//! It also ships observability middleware:
//!
//! - `propagate_request_id` and `trace_requests` (feature `trace`) - assign an
//! `x-request-id` correlation id (extractable via `RequestId`) and emit a structured
//! `tracing` event with method, path, status, and latency for each request.
//!
//! And service-wiring helpers:
//!
//! - `health_routes` and `liveness` (feature `router`) - a `Router` exposing `/healthz` and
//! `/readyz` probes backed by `HealthResponse`.
//! - `cors_allowing` and `permissive_cors` (feature `cors`) - build a `tower_http`
//! `CorsLayer` with sensible defaults.
//!
//! With the `openapi` feature, all four response types derive `utoipa::ToSchema` so they
//! can be referenced from a `utoipa` `OpenApi` document and appear in generated specs.
//!
//! # Quick Start
//!
//! ```rust,no_run
//! use axum::{Json, http::StatusCode, response::IntoResponse};
//! use axum_api_kit::{ApiError, ListResponse, CursorResponse, HealthResponse};
//! use serde::Serialize;
//!
//! #[derive(Serialize)]
//! struct Item { id: String }
//!
//! async fn list_items() -> impl IntoResponse {
//! let items = vec![Item { id: "1".into() }];
//! Json(ListResponse { data: items, total: 1, limit: 50, offset: 0 })
//! }
//!
//! async fn feed_items(cursor: Option<String>) -> impl IntoResponse {
//! let items = vec![Item { id: "1".into() }];
//! CursorResponse { data: items, next_cursor: Some("abc".into()), has_more: true }
//! }
//!
//! async fn get_item() -> impl IntoResponse {
//! ApiError::not_found("item not found")
//! }
//!
//! async fn health() -> impl IntoResponse {
//! HealthResponse::ok()
//! }
//! ```
pub use ;
pub use CursorResponse;
pub use ApiError;
pub use HealthResponse;
pub use ListResponse;
pub use ;
pub use ;
pub use ;
pub use ValidatedJson;