axum-api-kit
Shared response types for Axum JSON APIs.
Every Axum CRUD service defines the same ApiError, HealthResponse, and paginated list types. This crate provides one canonical implementation.
Installation
= "0.6"
Optional validator integration:
= { = "0.6", = ["validator"] }
Types
ApiError
A machine-readable JSON error body with code, message, and optional details.
use IntoResponse;
use ApiError;
// Factory helpers return (StatusCode, Json<ApiError>) which implement IntoResponse
async
// Use too_many_requests directly
async
// Or build manually for fully custom status codes
async
// ApiError implements Display and std::error::Error
async
// Chain error sources with with_source()
async
// Use ? operator in handlers with From<std::io::Error> and From<serde_json::Error>
async
Available factory methods:
| Method | Status |
|---|---|
ApiError::bad_request(code, msg) |
400 |
ApiError::unauthorized(msg) |
401 |
ApiError::forbidden(msg) |
403 |
ApiError::not_found(msg) |
404 |
ApiError::conflict(msg) |
409 |
ApiError::unprocessable(msg) |
422 |
ApiError::too_many_requests(msg) |
429 |
ApiError::internal(msg) |
500 |
ApiError::not_implemented(msg) |
501 |
ApiError::db_error() |
500 |
ApiError::service_unavailable(msg) |
503 |
ListResponse<T>
Generic paginated collection response.
use IntoResponse;
use ListResponse;
use Serialize;
async
HealthResponse
| Constructor | status |
HTTP |
|---|---|---|
HealthResponse::ok() |
"ok" |
200 |
HealthResponse::degraded() |
"degraded" |
200 |
HealthResponse::unhealthy() |
"unhealthy" |
503 |
use IntoResponse;
use HealthResponse;
async
CursorResponse<T>
Cursor-based paginated response for large datasets or feeds. Use instead of ListResponse when:
- Total count is expensive to compute
- Data is streamed or unbounded
- You're building a feed (social media, notifications, etc.)
- You need bidirectional navigation via opaque tokens
| Field | Type | Meaning |
|---|---|---|
data |
Vec<T> |
Items in this page |
next_cursor |
Option<String> |
Token for next page; None = last page |
has_more |
bool |
Convenience flag: true if more data exists |
use IntoResponse;
use CursorResponse;
use Serialize;
async
Error Propagation with From Implementations
Convert common Rust errors directly to ApiError (HTTP 500 Internal Error):
use io;
use ApiError;
async
Supported conversions:
std::io::Error- file I/O failuresserde_json::Error- JSON parsing errors
Optional Integrations
Validator Integration (validator feature)
Enable the feature to convert validator::ValidationErrors directly into ApiError.
use IntoResponse;
use ApiError;
async
The resulting ApiError uses this shape:
sqlx Integration (sqlx feature)
Enable the feature to convert sqlx::Error into semantically correct ApiError responses.
= { = "0.6", = ["sqlx"] }
use IntoResponse;
use ApiError;
async
sqlx::Error variant |
code |
HTTP |
|---|---|---|
RowNotFound |
NOT_FOUND |
404 |
Database (unique or FK violation) |
CONFLICT |
409 |
Database (check violation) |
VALIDATION_ERROR |
422 |
Database (other) |
DB_ERROR |
500 |
PoolTimedOut / PoolClosed / WorkerCrashed |
SERVICE_UNAVAILABLE |
503 |
| everything else | DB_ERROR |
500 |
License
MIT