
Utoipa
- 9 installs
- Updated May 4, 2026
- melonask/utoipa-skills
Helps with ai & agent building tasks.
About
utoipa is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- utoipa
- AI & Agent Building
- AI-coding skill
Utoipa by the numbers
- 9 all-time installs (skills.sh)
- Ranked #12,152 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/melonask/utoipa-skills --skill utoipaAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 9 |
|---|---|
| Last updated | May 4, 2026 |
| Repository | melonask/utoipa-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
Utoipa v5.4 — OpenAPI 3.1 Generator for Rust
utoipa generates OpenAPI 3.1 specifications at compile time using Rust macros. It integrates perfectly with Axum, turning documented Rust structs and functions into fully compliant OpenAPI JSON.
Dependency Setup
[dependencies]
utoipa = { version = "5.4", features = ["axum_extras", "openapi_extensions"] }
moka = { version = "0.12", features = ["future"] }
serde_json = "1"Core Patterns at a Glance
1. Documenting Types (ToSchema)
Use #[derive(ToSchema)] on structs and enums. Include examples for better developer experience.
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
#[derive(Serialize, Deserialize, ToSchema, Clone)]
pub struct TaskResult {
/// The unique task ID (ULID)
#[schema(example = "01HT7M5A20X8V2Z1N7G3P4Y9BQ")]
pub tid: String,
/// Execution status
#[schema(example = "done")]
pub status: String,
}2. Documenting Routes (#[utoipa::path])
Annotate Axum handlers with #[utoipa::path]. Specify parameters, request bodies, and responses.
use axum::{extract::Path, Json, http::StatusCode};
#[utoipa::path(
get,
path = "/v1/tasks/{kind}/{tid}",
responses(
(status = 200, description = "Task found", body = TaskResult),
(status = 404, description = "Task not found")
),
params(
("kind" = String, Path, description = "Task kind slug"),
("tid" = String, Path, description = "Task ULID")
),
security(
("AltchaAuth" = [])
)
)]
pub async fn get_task(
Path((_kind, _tid)): Path<(String, String)>
) -> Result<Json<TaskResult>, StatusCode> {
Ok(Json(TaskResult { tid: "01HT...".into(), status: "done".into() }))
}3. Assembling and Caching the Spec (Axum + Moka)
In high-performance orchestrators, the OpenAPI JSON should be generated once, cached in memory using moka, and served via Axum.
use axum::{routing::get, Router, Json, extract::State};
use moka::future::Cache;
use std::time::Duration;
use utoipa::OpenApi;
use serde_json::Value;
#[derive(OpenApi)]
#[openapi(
paths(get_task),
components(schemas(TaskResult)),
info(title = "Platform API", version = "1.0.0"),
tags((name = "tasks", description = "Task execution API"))
)]
struct ApiDoc;
#[derive(Clone)]
struct AppState {
// Cache the JSON Value, not the string, so Axum sets Content-Type correctly
openapi_cache: Cache<String, Value>,
}
pub fn router() -> Router {
let cache = Cache::builder()
.time_to_live(Duration::from_secs(3600)) // 1 hour TTL
.build();
Router::new()
.route("/v1/openapi.json", get(serve_openapi))
.with_state(AppState { openapi_cache: cache })
}
async fn serve_openapi(State(state): State<AppState>) -> Json<Value> {
let spec = state.openapi_cache.get_with("openapi", async {
// Generate the spec on cache miss
let doc = ApiDoc::openapi();
serde_json::to_value(&doc).unwrap()
}).await;
Json(spec)
}Known Issues — Utoipa Skill
Issues discovered through practical compilation testing against actual crate versions (utoipa 5.4.0, moka 0.12.15, axum 0.8.9).
1. Code Typos in SKILL.md (DOCUMENTATION)
The skill's SKILL.md contains several typographical errors in code snippets:
// Line 65: Result<<JsonJson<<TaskTaskResult>, StatusCode>
// SHOULD BE: Result<Json<TaskResult>, StatusCode>
// Line 93: Cache<<StringString, Value>
// SHOULD BE: Cache<String, Value>
// Line 103: State<<AppStateAppState>
// SHOULD BE: State<AppState>
// Line 106: Json<<ValueValue>
// SHOULD BE: Json<Value>These appear to be HTML/rendering artifacts (double-bracketed type parameters).
2. moka::future::Cache::get_with Requires Owned Key
The async get_with method requires the key type to be an owned String, not &str:
// WRONG (skill's code):
cache.get_with("openapi", async { ... })
// CORRECT:
cache.get_with("openapi".to_string(), async { ... })3. Missing reqwest Dependency for Runtime Tests
The SKILL.md code snippet in section 3 (serve_openapi handler with Axum) doesn't mention that reqwest is needed for runtime HTTP testing.
utoipa-skills
A comprehensive skill for building OpenAPI 3.1 documentation in Rust using the utoipa crate.
Overview
This skill teaches the LLM how to generate, serve, and efficiently cache OpenAPI 3.1 specifications. It seamlessly integrates with Axum 0.8 and uses moka for in-memory caching to prevent expensive runtime schema recalculations.
Installation
npx skills add melonask/utoipa-skillsWhat This Skill Covers
- Schema Generation: Using
#[derive(ToSchema)]for structs and enums. - Route Documentation: Using
#[utoipa::path]to document Axum handlers, path parameters, and request/response bodies. - Axum Integration: Combining
ApiDoc::openapi()with Axum 0.8 routing. - Caching: Using
mokato cache the generated JSON payload, avoiding serialization overhead on every/openapi.jsonrequest.
File Structure
utoipa/
└── SKILL.md # Main skill file (core concepts, macros, and caching)Quick Example
[dependencies]
utoipa = { version = "5.4", features = ["axum_extras", "openapi_extensions"] }License
Provided as-is for development with LLM assistants. Utoipa is dual-licensed under MIT/Apache-2.0.