OpenAPI-Dokumentationsgenerierung
OpenAPI ist eine Open-Source-Spezifikation zur Beschreibung von RESTful-API-Schnittstellendesigns. Sie definiert API-Anfrage- und Antwortstrukturen, Parameter, Rückgabetypen, Fehlercodes und andere Details im JSON- oder YAML-Format, wodurch die Kommunikation zwischen Client und Server expliziter und standardisierter wird.
OpenAPI war ursprünglich die Open-Source-Version der Swagger-Spezifikation und ist heute ein eigenständiges Projekt, das von vielen großen Unternehmen und Entwicklern unterstützt wird. Die Verwendung der OpenAPI-Spezifikation hilft Entwicklungsteams, besser zusammenzuarbeiten, Kommunikationskosten zu senken und die Entwicklungseffizienz zu steigern. Darüber hinaus bietet OpenAPI Entwicklern Werkzeuge zur automatischen Generierung von API-Dokumentation, Mock-Daten und Testfällen, was Entwicklungs- und Testarbeiten erleichtert.
Salvo bietet OpenAPI-Integration (modifiziert von utoipa). Salvo extrahiert elegant relevante OpenAPI-Datentypinformationen automatisch aus Handler basierend auf seinen eigenen Eigenschaften. Salvo integriert auch mehrere beliebte Open-Source-OpenAPI-Schnittstellen wie SwaggerUI, Scalar, RapiDoc und ReDoc.
Da Rust-Typnamen lang sein können und nicht immer für die OpenAPI-Verwendung geeignet sind, bietet salvo-oapi den Typ Namer, der es ermöglicht, Regeln anzupassen, um Typnamen in OpenAPI nach Bedarf zu ändern.
Beispielcode
Geben Sie http://localhost:8698/swagger-ui in Ihrem Browser ein, um die Swagger-UI-Seite zu sehen.
Die OpenAPI-Integration in Salvo ist recht elegant. Für das obige Beispiel haben wir im Vergleich zu einem normalen Salvo-Projekt nur die folgenden Schritte durchgeführt:
-
Aktivieren Sie das Feature
oapiinCargo.toml:salvo = { workspace = true, features = ["oapi"] }; -
Ersetzen Sie
#[handler]durch#[endpoint]; -
Verwenden Sie
name: QueryParam<String, false>, um den Wert der Abfragezeichenkette zu erhalten. Wenn Siehttp://localhost/hello?name=chrisaufrufen, wird diename-Abfragezeichenkette geparst. DasfalseinQueryParam<String, false>bedeutet, dass dieser Parameter optional ist. Wenn Siehttp://localhost/helloaufrufen, wird kein Fehler gemeldet. Im Gegensatz dazu bedeutetQueryParam<String, true>, dass dieser Parameter zwingend bereitgestellt werden muss, andernfalls wird ein Fehler zurückgegeben. -
Erstellen Sie
OpenAPIund den entsprechendenRouter. Dasmerge_routerinOpenApi::new("test api", "0.0.1").merge_router(&router)bedeutet, dass diesesOpenAPIdie notwendigen Dokumentinformationen durch Parsen einer bestimmten Route und ihrer Unterrouten erhält. EinigeHandlervon Routen liefern möglicherweise keine Informationen zur Dokumentgenerierung, und diese Routen werden ignoriert, wie z.B.Handler, die mit dem#[handler]-Makro anstelle des#[endpoint]-Makros definiert wurden. Das heißt, in realen Projekten können Sie aus Gründen wie dem Entwicklungsfortschritt wählen, keine OpenAPI-Dokumente zu generieren oder nur teilweise OpenAPI-Dokumente zu generieren. Anschließend können Sie schrittweise die Anzahl der generierten OpenAPI-Schnittstellen erhöhen, und alles, was Sie tun müssen, ist,#[handler]in#[endpoint]zu ändern und die Funktionssignatur anzupassen.
Datenextraktoren
Sie können vordefinierte gängige Datenextraktoren über use salvo::oapi::extract::*; importieren. Der Extraktor liefert Salvo einige notwendige Informationen, damit Salvo OpenAPI-Dokumente generieren kann.
-
QueryParam<T, const REQUIRED: bool>: Ein Extraktor zum Extrahieren von Daten aus Abfragezeichenketten.QueryParam<T, false>bedeutet, dass dieser Parameter nicht erforderlich ist und weggelassen werden kann.QueryParam<T, true>bedeutet, dass dieser Parameter erforderlich ist und nicht weggelassen werden darf. Wenn er nicht bereitgestellt wird, wird ein Fehler zurückgegeben; -
HeaderParam<T, const REQUIRED: bool>: Ein Extraktor zum Extrahieren von Daten aus dem Anfrageheader.HeaderParam<T, false>bedeutet, dass dieser Parameter nicht erforderlich ist und weggelassen werden kann.HeaderParam<T, true>bedeutet, dass dieser Parameter erforderlich ist und nicht weggelassen werden darf. Wenn er nicht bereitgestellt wird, wird ein Fehler zurückgegeben; -
CookieParam<T, const REQUIRED: bool>: Ein Extraktor zum Extrahieren von Daten aus dem Anfrage-Cookie.CookieParam<T, false>bedeutet, dass dieser Parameter nicht erforderlich ist und weggelassen werden kann.CookieParam<T, true>bedeutet, dass dieser Parameter erforderlich ist und nicht weggelassen werden darf. Wenn er nicht bereitgestellt wird, wird ein Fehler zurückgegeben; -
PathParam<T>: Ein Extraktor zum Extrahieren von Pfadparametern aus der Anfrage-URL. Wenn dieser Parameter nicht existiert, wird das Routen-Matching nicht erfolgreich sein, daher gibt es keinen Fall, in dem er weggelassen werden kann; -
FormBody<T>: Extrahiert Informationen aus dem übermittelten Formular der Anfrage; -
JsonBody<T>: Extrahiert Informationen aus der JSON-formatierten Nutzlast, die von der Anfrage übermittelt wird;
#[endpoint]
Bei der Generierung von OpenAPI-Dokumenten müssen Sie das #[endpoint]-Makro anstelle des regulären #[handler]-Makros verwenden. Es handelt sich tatsächlich um eine erweiterte Version des #[handler]-Makros.
-
Es kann die für die OpenAPI-Generierung notwendigen Informationen über die Funktionssignatur erhalten;
-
Für Informationen, die nicht bequem über die Signatur bereitgestellt werden können, können Sie diese direkt durch Hinzufügen von Attributen im
#[endpoint]-Makro bereitstellen. Die auf diese Weise bereitgestellten Informationen werden mit den über die Funktionssignatur erhaltenen Informationen zusammengeführt. Bei Konflikten überschreiben sie die von der Funktionssignatur bereitgestellten Informationen.
Sie können das in Rust integrierte #[deprecated]-Attribut verwenden, um einen Handler als veraltet zu markieren. Obwohl das #[deprecated]-Attribut das Hinzufügen von Informationen wie dem Grund für die Veraltung und der Version unterstützt, unterstützt OpenAPI dies nicht, daher werden diese Informationen bei der OpenAPI-Generierung ignoriert.
Der Dokumentationskommentarteil im Code wird automatisch extrahiert, um OpenAPI zu generieren. Die erste Zeile wird zur Generierung von summary verwendet, und der gesamte Kommentarteil wird zur Generierung von description verwendet.
ToSchema
Sie können #[derive(ToSchema)] verwenden, um Datenstrukturen zu definieren:
Sie können #[salvo(schema(...))] verwenden, um optionale Einstellungen zu definieren:
-
example = ...kannjson!(...)sein.json!(...)wird vonserde_json::json!alsserde_json::Valuegeparst. -
xml(...)kann verwendet werden, um Xml-Objekteigenschaften zu definieren:
ToParameters
Generiert [Pfadparameter][path_parameters] aus den Feldern der Struktur.
Dies ist die #[derive]-Implementierung des [ToParameters][to_parameters]-Traits.
Normalerweise müssen Pfadparameter in [#[salvo_oapi::endpoint(...parameters(...))]][path_parameters] des Endpoints definiert werden. Bei Verwendung einer [struct][struct] zur Parameterdefinition können diese Schritte jedoch weggelassen werden. Dennoch, wenn Sie eine Beschreibung angeben oder die Standardkonfiguration ändern müssen, dann müssen [primitive Typen][primitive] und [String][std_string]-Pfadparameter oder [Tupel]-stil Pfadparameter weiterhin in parameters(...) definiert werden.
Sie können das in Rust integrierte #[deprecated]-Attribut verwenden, um Felder als veraltet zu markieren, was sich in der generierten OpenAPI-Spezifikation widerspiegelt.
Das #[deprecated]-Attribut unterstützt das Hinzufügen zusätzlicher Informationen wie dem Grund für die Veraltung oder der Version, ab der es veraltet ist, aber OpenAPI unterstützt dies nicht. OpenAPI unterstützt nur einen booleschen Wert, um zu bestimmen, ob etwas veraltet ist. Obwohl es durchaus möglich ist, eine Veraltung mit einem Grund zu deklarieren, wie #[deprecated = "There is better way to do this"], wird dieser Grund nicht in der OpenAPI-Spezifikation dargestellt.
Der Kommentardokumentation auf dem Strukturfeld wird als Parameterbeschreibung in der generierten OpenAPI-Spezifikation verwendet.
ToParameters Container-Attribute für #[salvo(parameters(...))]
Die folgenden Attribute können im Container-Attribut #[salvo(parameters(…))] der von ToParameters abgeleiteten Struktur verwendet werden:
names(...)Definiert eine kommagetrennte Liste von Namen für die unbenannten Felder der als Pfadparameter verwendeten Struktur. Nur bei unbenannten Strukturen unterstützt.style = ...Definiert die Serialisierungsmethode für alle Parameter, angegeben durch [ParameterStyle][style]. Der Standardwert basiert auf demparameter_in-Attribut.default_parameter_in = ...Definiert die Standardposition, die von den Parametern dieses Felds verwendet wird. Der Wert dieser Position stammt aus [parameter::ParameterIn][in_enum]. Wenn dieses Attribut nicht bereitgestellt wird, ist der Standardwertquery.rename_all = ...Kann als Alternative zuserdesrename_allverwendet werden. Es bietet tatsächlich die gleiche Funktionalität.
Verwenden Sie names, um einen Namen für einen einzelnen unbenannten Parameter zu definieren.
Verwenden Sie names, um Namen für mehrere unbenannte Parameter zu definieren.
ToParameters Feld-Attribute für #[salvo(parameter(...))]
Die folgenden Attribute können auf Strukturfeldern #[salvo(parameter(...))] verwendet werden:
-
style = ...Definiert, wie Parameter durch [ParameterStyle][style] serialisiert werden. Der Standardwert basiert auf demparameter_in-Attribut. -
parameter_in = ...Verwenden Sie den Wert aus [parameter::ParameterIn][in_enum], um zu definieren, wo sich dieser Feldparameter befindet. Wenn dieser Wert nicht bereitgestellt wird, ist der Standardwertquery. -
explodeDefiniert, ob für jeden Parameter inobjectoderarrayein neuesparameter=value-Paar erstellt werden soll. -
allow_reservedDefiniert, ob reservierte Zeichen:/?#[]@!$&'()*+,;=im Parameterwert erlaubt sind. -
example = ...Kann eine Methodenreferenz oderjson!(...)sein. Das gegebene Beispiel überschreibt alle Beispiele des zugrundeliegenden Parametertyps. -
value_type = ...Kann verwendet werden, um den Standardtyp, der von Feldern in der OpenAPI-Spezifikation verwendet wird, zu überschreiben. Dies ist nützlich, wenn der Standardtyp nicht dem tatsächlichen Typ entspricht, z.B. bei Verwendung von Drittanbietertypen, die nicht in [ToSchema][to_schema] oder [primitiveTypen][primitive] definiert sind. Der Wert kann jeder Rust-Typ sein, der unter normalen Umständen zu JSON serialisiert werden kann, oder ein benutzerdefinierter Typ wieObject.Object, der als generisches OpenAPI-Objekt gerendert wird. -
inlineWenn aktiviert, muss die Definition dieses Feldtyps aus [ToSchema][to_schema] stammen, und diese Definition wird inline gesetzt. -
default = ...Kann eine Methodenreferenz oderjson!(...)sein. -
format = ...Kann eine Variante der [KnownFormat][known_format]-Enum oder ein offener Wert in Stringform sein. Standardmäßig wird das Format aus dem Typ des Attributs gemäß der OpenApi-Spezifikation abgeleitet. -
write_onlyDefiniert, dass das Attribut nur für Schreiboperationen POST,PUT,PATCH und nicht für GET verwendet wird. -
read_onlyDefiniert, dass das Attribut nur für Leseoperationen GET und nicht für POST,PUT,PATCH verwendet wird. -
nullableDefiniert, ob das Attributnullsein kann (beachten Sie, dass dies sich von nicht erforderlich unterscheidet). -
required = ...Wird verwendet, um zu erzwingen, dass der Parameter erforderlich ist. Siehe Regeln. -
rename = ...Kann als Alternative zuserdesrenameverwendet werden. Es bietet tatsächlich die gleiche Funktionalität. -
multiple_of = ...Wird verwendet, um ein Vielfaches des Werts zu definieren. Der Parameterwert gilt nur dann als gültig, wenn der Parameterwert durch den Wert dieses Schlüsselworts geteilt wird und das Ergebnis eine ganze Zahl ist. Der Vielfachwert muss strikt größer als0sein. -
maximum = ...Wird verwendet, um die Obergrenze des Werts zu definieren, einschließlich des aktuellen Werts. -
minimum = ...Wird verwendet, um die Untergrenze des Werts zu definieren, einschließlich des aktuellen Werts. -
exclusive_maximum = ...Wird verwendet, um die Obergrenze des Werts zu definieren, ausschließlich des aktuellen Werts. -
exclusive_minimum = ...Wird verwendet, um die Untergrenze des Werts zu definieren, ausschließlich des aktuellen Werts. -
max_length = ...Wird verwendet, um die maximale Länge einesstring-Typwerts zu definieren. -
min_length = ...Wird verwendet, um die minimale Länge einesstring-Typwerts zu definieren. -
pattern = ...Wird verwendet, um einen gültigen regulären Ausdruck zu definieren, dem der Feldwert entsprechen muss. Der reguläre Ausdruck verwendet die ECMA-262-Version. -
max_items = ...Kann verwendet werden, um die maximale Anzahl von Elementen zu definieren, die in einemarray-Typfeld erlaubt sind. Der Wert muss eine nicht-negative Ganzzahl sein. -
min_items = ...Kann verwendet werden, um die minimale Anzahl von Elementen zu definieren, die in einemarray-Typfeld erlaubt sind. Der Wert muss eine nicht-negative Ganzzahl sein. -
with_schema = ...Verwendet eine Funktionsreferenz, um einschemaanstelle des Standard-schemazu erstellen. Die Funktion muss der Definitionfn() -> Into<RefOr<Schema>>genügen. Sie erhält keine Parameter und muss einen beliebigen Wert zurückgeben, der inRefOr<Schema>konvertiert werden kann. -
additional_properties = ...Wird verwendet, um freiform-Typen fürmapzu definieren, wie z.B.