use axum::{
extract::Extension,
routing::{get, post},
Json, Router,
};
use reqkey::{
axum::ReqKeyLayer,
middleware::{KeyLocation, Middleware, MiddlewareConfig},
Client, VerificationResult,
};
use serde_json::{json, Value};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::from_env()?;
let config = MiddlewareConfig::builder("api_payments")
.key_location(KeyLocation::header("X-StartupName-Key"))
.exclude_path("/health")
.credit_cost_resolver(|request| Ok(if request.path == "/payments" { 2 } else { 1 }))
.capture_query_params(true)
.build()?;
let protected = Router::new()
.route("/payments", post(create_payment))
.layer(ReqKeyLayer::new(Middleware::new(client, config)));
let app = Router::new()
.route("/health", get(|| async { "ok" }))
.merge(protected);
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await?;
axum::serve(listener, app).await?;
Ok(())
}
async fn create_payment(Extension(decision): Extension<VerificationResult>) -> Json<Value> {
Json(json!({
"created": true,
"credits_remaining": decision.credits_remaining,
}))
}