Rust के लिए Swagger/OpenAPI जनरेशन: Utoipa और Aide
आधुनिक Rust वेब डेवलपमेंट में, एक दस्तावेजीकृत API बनाना कोई विलासिता नहीं, बल्कि एक आवश्यकता है। Swagger (OpenAPI) आपको स्वचालित रूप से इंटरैक्टिव दस्तावेज़ीकरण, क्लाइंट SDK और टेस्ट कंसोल उत्पन्न करने की अनुमति देता है। Rust इकोसिस्टम में, दो उपकरण अग्रणी स्थान रखते हैं: Utoipa (मैक्रोज़ पर आधारित) और Aide (टाइपिंग और मैन्युअल नियंत्रण पर जोर देने वाला)। आइए इन्हें विस्तार से देखें।
Utoipa — OpenAPI 3.0 के लिए मैक्रोज़
Utoipa एक लाइब्रेरी है जो OpenAPI विनिर्देश को स्वचालित रूप से उत्पन्न करने के लिए एट्रीब्यूट-मैक्रोज़ (#[utoipa::path]) का उपयोग करती है। यह लोकप्रिय फ्रेमवर्क: Actix-web, Axum, Rocket, Warp के साथ घनिष्ठ रूप से एकीकृत होती है।
विशेषताएँ:
- OpenAPI 3.0 का पूर्ण समर्थन (paths, components, security schemes)।
- Rust स्ट्रक्चर से स्वचालित रूप से प्रकार निकालना (
#[derive(ToSchema)]के साथ)। - Swagger UI के लिए JSON/YAML फ़ाइल जनरेशन।
- बॉक्स से बाहर
actix-webके लिए समर्थन (utoipa-swagger-uiके माध्यम से)। - कम प्रवेश सीमा — बस मैक्रोज़ जोड़ने की आवश्यकता है।
Actix-web के साथ उदाहरण:
use actix_web::{get, web, App, HttpResponse, HttpServer, Responder};use serde::{Deserialize, Serialize};use utoipa::{OpenApi, ToSchema};use utoipa_swagger_ui::SwaggerUi;
#[derive(Serialize, Deserialize, ToSchema)]struct User { id: u32, name: String,}
#[utoipa::path( get, path = "/users/{id}", responses( (status = 200, description = "User found", body = User), (status = 404, description = "User not found") ), params( ("id" = u32, Path, description = "User ID") ))]#[get("/users/{id}")]async fn get_user(id: web::Path<u32>) -> impl Responder { HttpResponse::Ok().json(User { id: id.into_inner(), name: "Alice".into(), })}
#[derive(OpenApi)]#[openapi(paths(get_user), components(schemas(User)))]struct ApiDoc;
#[actix_web::main]async fn main() -> std::io::Result<()> { HttpServer::new(|| { App::new() .service(get_user) .service( SwaggerUi::new("/swagger-ui/{_:.*}") .url("/api-doc/openapi.json", ApiDoc::openapi()), ) }) .bind("127.0.0.1:8080")? .run() .await}Aide — नियंत्रण और टाइपिंग
Aide (पूर्व में paperclip) एक अलग दृष्टिकोण प्रस्तुत करता है: आप मैक्रोज़ के बजाय स्ट्रक्चर और फ़ंक्शन के माध्यम से स्पष्ट रूप से विनिर्देश का वर्णन करते हैं। यह अधिक नियंत्रण देता है, लेकिन अधिक कोड की आवश्यकता होती है। लाइब्रेरी Axum और Actix-web का समर्थन करती है।
विशेषताएँ:
- शुद्ध टाइपिंग — सभी विवरण enum और struct के माध्यम से दिए गए हैं।
- जनरेशन के दौरान अंतर्निहित स्कीमा सत्यापन।
- नेस्टेड मॉडल और कंपोज़िशन (allOf, oneOf) के लिए समर्थन।
- लचीलापन: आप विनिर्देश के किसी भी पहलू को ओवरराइड कर सकते हैं।
Axum के साथ उदाहरण:
use aide::{axum::ApiRouter, openapi::OpenApi};use axum::{routing::get, Json, Router};use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]struct Pet { id: u32, name: String,}
async fn list_pets() -> Json<Vec<Pet>> { Json(vec![Pet { id: 1, name: "Rex".into(), }])}
async fn api_docs() -> Json<OpenApi> { let mut api = OpenApi::default(); api.info.title = "Pet Store API".into(); api.info.version = "1.0.0".into(); Json(api)}
#[tokio::main]async fn main() { let app = ApiRouter::new() .route("/pets", get(list_pets)) .route("/api-doc", get(api_docs));
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap()) .serve(app.into_make_service()) .await .unwrap();}