Expand description
§Axum helpers for jacquard XRPC server implementations
§Usage
use axum::{Router, routing::get, http::StatusCode, response::IntoResponse, Json};
use jacquard_axum::{ ExtractXrpc, IntoRouter };
use std::collections::BTreeMap;
use miette::{IntoDiagnostic, Result};
use jacquard::api::com_atproto::identity::resolve_handle::{ResolveHandle, ResolveHandleRequest, ResolveHandleOutput};
use jacquard_common::types::string::Did;
async fn handle_resolve(
ExtractXrpc(req): ExtractXrpc<ResolveHandleRequest>
) -> Result<Json<ResolveHandleOutput<'static>>, StatusCode> {
// req is ResolveHandle<'static>, ready to use
let handle = req.handle;
// ... resolve logic
Ok(Json(output))
}
#[tokio::main]
async fn main() -> Result<()> {
let app = Router::new()
.route("/", axum::routing::get(|| async { "hello world!" }))
.merge(ResolveHandleRequest::into_router(handle_resolve));
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
.await
.into_diagnostic()?;
axum::serve(listener, app).await.unwrap();
Ok(())
}The extractor uses the XrpcEndpoint trait to determine request type:
- Query: Deserializes from query string parameters
- Procedure: Deserializes from request body (supports custom encodings via
decode_body)
Deserialization errors return a 400 Bad Request with a JSON error body matching the XRPC error format.
The extractor deserializes to borrowed types first, then converts to 'static via
IntoStatic, avoiding the DeserializeOwned requirement of the Json axum extractor and similar.
Modules§
- did_web
- Helper for serving did:web DID documents
- service_
auth - Service authentication extractor and middleware
Structs§
- Extract
Xrpc - Axum extractor for XRPC requests
- Xrpc
Error Response - Axum-compatible Xrpc error wrapper
Traits§
- Into
Router - Conversion trait to turn an XrpcEndpoint and a handler into an axum Router