Claude Code Plugins

Community-maintained marketplace

Feedback

vespera-api-development

@dev-five-git/vespera
9
0

Guide for developing fully automated OpenAPI/Axum APIs using the Vespera framework.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name vespera-api-development
description Guide for developing fully automated OpenAPI/Axum APIs using the Vespera framework.

Vespera API Development

Vespera is a fully automated OpenAPI engine for Axum with zero-config route and schema discovery. It allows you to write Axum APIs and automatically generate OpenAPI 3.1 specifications.

Instructions

1. Project Setup

Add vespera to your dependencies:

[dependencies]
vespera = "0.1.0"
axum = "0.8"
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }

2. Main Application

Use the vespera! macro in main.rs to initialize the app. This macro automatically scans your routes.

use vespera::vespera;

#[tokio::main]
async fn main() {
    // Basic initialization
    let app = vespera!(
        openapi = "openapi.json", // Optional: Generate OpenAPI spec
        title = "My API",         // Optional: API Title
        version = "1.0.0",        // Optional: API Version
        docs_url = "/docs"        // Optional: Serve Swagger UI
    );

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

3. Route Handlers

Define routes in modules (e.g., src/routes/). Use the #[vespera::route] attribute.

use axum::{Json, Path, State};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
pub struct User {
    pub id: u32,
    pub name: String,
}

// GET /users/{id}
#[vespera::route(path = "/{id}")] // Defaults to GET if not specified
pub async fn get_user(Path(id): Path<u32>) -> Json<User> {
    Json(User { id, name: "Alice".into() })
}

// POST /users
#[vespera::route(post)]
pub async fn create_user(Json(user): Json<User>) -> Json<User> {
    Json(user)
}

4. Tags and Description

Add tags to group routes and descriptions for OpenAPI documentation.

Tags: Use the tags parameter to group routes.

#[vespera::route(get, tags = ["users"])]
pub async fn list_users() -> Json<Vec<User>> { ... }

#[vespera::route(post, tags = ["users", "admin"])]
pub async fn create_user(Json(user): Json<User>) -> Json<User> { ... }

Description: Two ways to add descriptions:

  1. Doc comments (recommended): Automatically extracted from /// comments.
/// Get all users from the database
#[vespera::route(get)]
pub async fn list_users() -> Json<Vec<User>> { ... }
  1. Explicit description parameter: Takes priority over doc comments.
#[vespera::route(get, description = "Custom description")]
pub async fn list_users() -> Json<Vec<User>> { ... }

Combined example:

/// Get user by ID
#[vespera::route(get, path = "/{id}", tags = ["users"])]
pub async fn get_user(Path(id): Path<u32>) -> Json<User> { ... }

5. Error Handling

Vespera supports Result<T, E> return types. It automatically documents both the success capability (200 OK) and the error responses in the OpenAPI spec.

use axum::http::StatusCode;

#[derive(Serialize, Deserialize, Schema)]
pub struct ErrorResponse {
    pub message: String,
}

// Result<Json<Success>, Json<Error>>
#[vespera::route(get, path = "/may-fail")]
pub async fn may_fail() -> Result<Json<User>, Json<ErrorResponse>> {
    Err(Json(ErrorResponse { message: "Something went wrong".to_string() }))
}

// Result<Json<Success>, (StatusCode, Json<Error>)>
#[vespera::route(get, path = "/not-found")]
pub async fn not_found_example() -> Result<Json<User>, (StatusCode, Json<ErrorResponse>)> {
    Err((
        StatusCode::NOT_FOUND,
        Json(ErrorResponse { message: "User not found".to_string() })
    ))
}

4. File Structure

The file structure in src/routes maps to URL paths:

  • src/routes/users.rs -> /users
  • src/routes/admin/stats.rs -> /admin/stats

Guidelines

  • Always use vespera! macro instead of manually building Router::new().
  • Use #[vespera::route] for all handlers to ensure they are picked up by the OpenAPI generator.
  • dir parameter in vespera! defaults to "routes".
  • Handlers and schemas are automatically imported.