OpenAPI ist eine offene Spezifikation zur Beschreibung von RESTful-API-Schnittstellen. Im JSON- oder YAML-Format definiert es die Struktur von Anfragen und Antworten, Parameter, Rückgabetypen, Fehlercodes und andere Details, wodurch die Kommunikation zwischen Client und Server klarer und standardisierter wird.
Ursprünglich war OpenAPI die Open-Source-Version der Swagger-Spezifikation, hat sich jedoch zu einem eigenständigen Projekt entwickelt, das von vielen großen Unternehmen und Entwicklern unterstützt wird. Die Verwendung der OpenAPI-Spezifikation verbessert die Zusammenarbeit in Entwicklungsteams, reduziert Kommunikationskosten und steigert die Effizienz. Zudem bietet OpenAPI Tools zur automatischen Generierung von API-Dokumentation, Mock-Daten und Testfällen, was die Entwicklungs- und Testarbeit erleichtert.
Salvo bietet eine Integration von OpenAPI (modifiziert von utoipa). Salvo holt sich elegant die relevanten OpenAPI-Datentypinformationen automatisch vom Handler
. Zudem integriert Salvo beliebte OpenAPI-Oberflächen wie SwaggerUI, scalar, rapidoc und redoc.
Da Rust-Typnamen oft lang und für OpenAPI ungeeignet sind, bietet salvo-oapi
den Typ Namer
, mit dem Sie Regeln anpassen können, um Typnamen in OpenAPI zu ändern.
Beispielcode
Geben Sie im Browser http://localhost:5800/swagger-ui
ein, um die Swagger-UI-Seite zu sehen.
Die OpenAPI-Integration in Salvo ist äußerst elegant. Im Vergleich zu einem normalen Salvo-Projekt sind für das obige Beispiel nur folgende Schritte notwendig:
oapi
-Funktion in Cargo.toml
: salvo = { workspace = true, features = ["oapi"] }
;#[handler]
durch #[endpoint]
;name: QueryParam<String, false>
, um den Wert eines Abfrageparameters zu erhalten. Beim Aufruf von http://localhost/hello?name=chris
wird der Parameter name
aus der Abfragezeichenfolge geparst. QueryParam<String, false>
bedeutet, dass der Parameter optional ist – ein Aufruf von http://localhost/hello
ohne Parameter führt nicht zu einem Fehler. Bei QueryParam<String, true>
ist der Parameter dagegen erforderlich, andernfalls wird ein Fehler zurückgegeben.OpenAPI
-Objekt und den entsprechenden Router
. OpenApi::new("test api", "0.0.1").merge_router(&router)
bedeutet, dass das OpenAPI
-Objekt durch die Analyse eines Routers und seiner Unterrouten die notwendigen Dokumentationsinformationen erhält. Handler, die keine Dokumentationsinformationen liefern (z.B. solche mit #[handler]
statt #[endpoint]
), werden ignoriert. In realen Projekten können Sie also wählen, ob Sie OpenAPI-Dokumentation generieren möchten oder nicht, oder nur teilweise. Später können Sie schrittweise mehr OpenAPI-Endpoints hinzufügen, indem Sie einfach #[handler]
in #[endpoint]
ändern und die Funktionssignatur anpassen.Durch use salvo::oapi::extract::*;
können Sie vordefinierte, häufig verwendete Datenextraktoren importieren. Diese Extraktoren liefern Salvo die notwendigen Informationen zur Generierung der OpenAPI-Dokumentation.
QueryParam<T, const REQUIRED: bool>
: Extrahiert Daten aus der Abfragezeichenfolge. QueryParam<T, false>
bedeutet, dass der Parameter optional ist, QueryParam<T, true>
, dass er erforderlich ist.HeaderParam<T, const REQUIRED: bool>
: Extrahiert Daten aus den Header-Informationen der Anfrage.CookieParam<T, const REQUIRED: bool>
: Extrahiert Daten aus den Cookies der Anfrage.PathParam<T>
: Extrahiert Pfadparameter aus der Anfrage-URL. Fehlt dieser Parameter, schlägt das Routing fehl.FormBody<T>
: Extrahiert Informationen aus Formulardaten.JsonBody<T>
: Extrahiert Informationen aus JSON-Nutzlasten.#[endpoint]
Für die OpenAPI-Dokumentationsgenerierung muss das #[endpoint]
-Makro anstelle des üblichen #[handler]
-Makros verwendet werden. Es handelt sich um eine erweiterte Version von #[handler]
.
#[endpoint]
-Makro hinzugefügt werden. Diese überschreiben ggf. die aus der Signatur abgeleiteten Informationen.Mit dem Rust-Attribut #[deprecated]
können Sie Handler als veraltet markieren. OpenAPI unterstützt zwar keine detaillierten Deprecation-Informationen, aber der Status wird übernommen.
Dokumentationskommentare im Code werden automatisch für die OpenAPI-Generierung verwendet: Die erste Zeile wird als summary
verwendet, der gesamte Kommentar als description
.
Verwenden Sie #[derive(ToSchema)]
, um Datenstrukturen zu definieren:
Mit #[salvo(schema(...))]
können optionale Einstellungen definiert werden:
example = ...
kann json!(...)
sein. json!(...)
wird von serde_json::json!
in serde_json::Value
geparst.
xml(...)
definiert XML-Objekteigenschaften:
Generiert Pfadparameter aus Strukturfeldern.
Dies ist eine #[derive]
-Implementierung des ToParameters
-Traits.
Normalerweise müssen Pfadparameter im endpoint
unter #[salvo_oapi::endpoint(...parameters(...))]
definiert werden. Bei Verwendung einer struct
kann dieser Schritt entfallen. Für Basistypen oder Tupel-Parameter ist die Definition in parameters(...)
jedoch weiterhin notwendig, insbesondere wenn Beschreibungen oder Konfigurationen angepasst werden sollen.
Mit dem Rust-Attribut #[deprecated]
können Felder als veraltet markiert werden, was sich in der OpenAPI-Spezifikation widerspiegelt. Zusätzliche Deprecation-Informationen werden ignoriert.
Dokumentationskommentare über Feldern werden als Parameterbeschreibungen in der OpenAPI-Spezifikation übernommen.
#[salvo(parameters(...))]
Folgende Attribute können für Strukturen verwendet werden, die von ToParameters
abgeleitet sind:
names(...)
definiert Namen für unbenannte Felder (nur bei unbenannten Strukturen).style = ...
definiert das Serialisierungsformat aller Parameter (standardmäßig abhängig von parameter_in
).default_parameter_in = ...
legt die Standardposition der Parameter fest (Standard: query
).rename_all = ...
bietet ähnliche Funktionen wie serde
's rename_all
.Beispiel für names
:
#[salvo(parameter(...))]
Folgende Feldattribute sind verfügbar:
style
, parameter_in
, explode
, allow_reserved
, example
, value_type
, inline
, default
, format
, write_only
, read_only
, nullable
, required
, rename
, multiple_of
, maximum
, minimum
, exclusive_maximum
, exclusive_minimum
, max_length
, min_length
, pattern
, max_items
, min_items
, with_schema
, additional_properties
.Bestimmte Regeln für Nullability und Pflichtfelder gelten analog zu ToSchema
. Siehe Regeln.
#[serde(...)]
-AttributeToParameters
unterstützt ausgewählte Serde-Attribute, die sich auf die OpenAPI-Dokumentation auswirken:
rename_all
, rename
, default
, skip_serializing_if
, with
, skip_serializing
, skip_deserializing
, skip
.Andere Serde-Attribute beeinflussen nur die Serialisierung, nicht die OpenAPI-Dokumentation.
Demonstration der Verwendung von #[salvo(parameters(...))]
mit ToParameters
für Pfadparameter und Inline-Abfragefelder:
Fehlerbehandlung
Für OpenAPI muss der globale Fehlertyp (AppError
) EndpointOutRegister
implementieren:
Mit status_codes
können spezifische Fehlertypen gefiltert werden: