A simple demo backend API server for testing the V-A-C sidecar. This simulates an upstream API service that the sidecar forwards requests to.
- API Key Authentication: Requires API key in
Authorization: Bearer <key>header - Demo Endpoints:
GET /health- Health check (no auth required)POST /search- Search endpoint (requires API key)POST /charge- Payment charge endpoint (requires API key)* /*path- Generic endpoint handler for any path
- Configurable: API key and port can be set via CLI args or env vars
cd demo-api
cargo runThis starts the server on http://localhost:8080 with default API key "demo-api-key".
Via CLI arguments:
cargo run -- --api-key "my-secret-key" --port 9000Via environment variables:
export DEMO_API_KEY="my-secret-key"
export DEMO_API_PORT=9000
cargo runHealth check (no auth):
curl http://localhost:8080/healthSearch endpoint (requires API key):
curl -X POST http://localhost:8080/search \
-H "Authorization: Bearer demo-api-key" \
-H "Content-Type: application/json" \
-d '{"query": "test search"}'Charge endpoint (requires API key):
curl -X POST http://localhost:8080/charge \
-H "Authorization: Bearer demo-api-key" \
-H "Content-Type: application/json" \
-d '{"amount": 5000, "currency": "usd", "description": "Test charge"}'In your config.toml for the sidecar:
[sidecar]
root_public_key = "<your-root-public-key>"
api_key = "demo-api-key" # Must match DEMO_API_KEY
upstream_url = "http://localhost:8080" # Demo API URL
control_plane_url = "http://localhost:8081"-
Start Demo API:
cd demo-api cargo run -- --api-key "demo-api-key"
-
Start V-A-C Sidecar:
cd sidecar cargo run --bin vac-sidecar -- --config-file ../config.toml -
Send request through sidecar:
curl -X POST http://localhost:3000/charge \ -H "Authorization: Bearer <Root-Biscuit-Token>" \ -H "Content-Type: application/json" \ -d '{"amount": 5000, "currency": "usd"}'
The sidecar will:
- Verify the Root Biscuit
- Check policy
- Forward to demo API at
http://localhost:8080/chargewith API key"demo-api-key" - Return response with receipt
Health check endpoint (no authentication required).
Response:
{
"success": true,
"message": "Demo API is healthy",
"data": null
}Search endpoint (requires API key).
Request:
{
"query": "search term"
}Response:
{
"success": true,
"message": "Found 2 results",
"data": {
"results": [
{"id": "1", "title": "Result for: search term", "score": 0.95},
{"id": "2", "title": "Another result for: search term", "score": 0.87}
],
"count": 2,
"query": "search term"
}
}Payment charge endpoint (requires API key).
Request:
{
"amount": 5000,
"currency": "usd",
"description": "Optional description"
}Response:
{
"success": true,
"message": "Charge processed successfully",
"data": {
"id": "ch_abc123...",
"amount": 5000,
"currency": "usd",
"status": "succeeded",
"description": "Optional description"
}
}Generic endpoint handler for any other path.
Response:
{
"success": true,
"message": "Received GET request to /custom/path",
"data": {
"method": "GET",
"path": "/custom/path",
"timestamp": "2024-01-01T12:00:00Z"
}
}Returned when API key is missing or invalid.
{
"success": false,
"message": "Unauthorized",
"data": null
}Edit src/main.rs and add new route handlers:
async fn my_endpoint(
State(state): State<Arc<AppState>>,
headers: HeaderMap,
Json(payload): Json<MyRequest>,
) -> Result<Json<ApiResponse>, StatusCode> {
verify_api_key(&headers, &state.api_key)?;
// Your logic here
Ok(Json(ApiResponse { ... }))
}
// Add to router:
.route("/my-endpoint", post(my_endpoint))Use this API with the VAC sidecar for end-to-end testing. Same endpoints the sidecar expects; tweak responses in code if needed.