Generazione della Documentazione OpenAPI
OpenAPI è una specifica open source per descrivere la progettazione di interfacce API RESTful. Definisce strutture di richiesta e risposta API, parametri, tipi di ritorno, codici di errore e altri dettagli in formato JSON o YAML, rendendo la comunicazione tra client e server più esplicita e standardizzata.
OpenAPI era originariamente la versione open source della specifica Swagger ed è ora diventato un progetto indipendente supportato da molte grandi aziende e sviluppatori. Utilizzare la specifica OpenAPI aiuta i team di sviluppo a collaborare meglio, ridurre i costi di comunicazione e migliorare l'efficienza dello sviluppo. Inoltre, OpenAPI fornisce agli sviluppatori strumenti per generare automaticamente documentazione API, dati mock e casi di test, facilitando il lavoro di sviluppo e testing.
Salvo fornisce integrazione OpenAPI (modificata da utoipa). Salvo estrae elegantemente automaticamente le informazioni rilevanti sui tipi di dati OpenAPI da Handler in base alle sue caratteristiche. Salvo integra anche diverse interfacce OpenAPI open source popolari come SwaggerUI, Scalar, RapiDoc e ReDoc.
Poiché i nomi dei tipi Rust possono essere lunghi e non sempre adatti all'uso in OpenAPI, salvo-oapi fornisce il tipo Namer, che consente di personalizzare le regole per modificare i nomi dei tipi in OpenAPI secondo necessità.
Codice di Esempio
Inserisci http://localhost:8698/swagger-ui nel tuo browser per vedere la pagina Swagger UI.
L'integrazione OpenAPI in Salvo è piuttosto elegante. Per l'esempio sopra, rispetto a un normale progetto Salvo, abbiamo semplicemente eseguito i seguenti passaggi:
-
Abilita la feature
oapiinCargo.toml:salvo = { workspace = true, features = ["oapi"] }; -
Sostituisci
#[handler]con#[endpoint]; -
Usa
name: QueryParam<String, false>per ottenere il valore della stringa di query. Quando visitihttp://localhost/hello?name=chris, la stringa di querynameverrà analizzata. IlfalseinQueryParam<String, false>significa che questo parametro è opzionale. Se visitihttp://localhost/hello, non darà errore. Al contrario, se èQueryParam<String, true>, significa che questo parametro deve essere fornito, altrimenti verrà restituito un errore. -
Crea
OpenAPIe il corrispondenteRouter. Ilmerge_routerinOpenApi::new("test api", "0.0.1").merge_router(&router)significa che questoOpenAPIottiene le informazioni documentali necessarie analizzando una certa rotta e le sue sotto-rotte. AlcuniHandlerdelle rotte potrebbero non fornire informazioni per generare documenti, e queste rotte verranno ignorate, come gliHandlerdefiniti usando la macro#[handler]invece della macro#[endpoint]. Cioè, nei progetti reali, per motivi come l'avanzamento dello sviluppo, puoi scegliere di non generare documenti OpenAPI, o generare parzialmente documenti OpenAPI. Successivamente, puoi gradualmente aumentare il numero di interfacce OpenAPI generate, e tutto ciò che devi fare è cambiare#[handler]in#[endpoint]e modificare la firma della funzione.
Estrattori di Dati
Puoi importare estrattori di dati comuni predefiniti tramite use salvo::oapi::extract::*;. L'estrattore fornirà alcune informazioni necessarie a Salvo in modo che Salvo possa generare documenti OpenAPI.
-
QueryParam<T, const REQUIRED: bool>: Un estrattore per estrarre dati dalle stringhe di query.QueryParam<T, false>significa che questo parametro non è obbligatorio e può essere omesso.QueryParam<T, true>significa che questo parametro è obbligatorio e non può essere omesso. Se non viene fornito, verrà restituito un errore; -
HeaderParam<T, const REQUIRED: bool>: Un estrattore per estrarre dati dall'intestazione della richiesta.HeaderParam<T, false>significa che questo parametro non è obbligatorio e può essere omesso.HeaderParam<T, true>significa che questo parametro è obbligatorio e non può essere omesso. Se non viene fornito, verrà restituito un errore; -
CookieParam<T, const REQUIRED: bool>: Un estrattore per estrarre dati dal cookie della richiesta.CookieParam<T, false>significa che questo parametro non è obbligatorio e può essere omesso.CookieParam<T, true>significa che questo parametro è obbligatorio e non può essere omesso. Se non viene fornito, verrà restituito un errore; -
PathParam<T>: Un estrattore per estrarre i parametri del percorso dall'URL della richiesta. Se questo parametro non esiste, la corrispondenza della rotta non avrà successo, quindi non esiste il caso in cui possa essere omesso; -
FormBody<T>: Estrae informazioni dal modulo inviato dalla richiesta; -
JsonBody<T>: Estrae informazioni dal payload in formato JSON inviato dalla richiesta;
#[endpoint]
Quando si generano documenti OpenAPI, è necessario utilizzare la macro #[endpoint] invece della normale macro #[handler]. In realtà è una versione potenziata della macro #[handler].
-
Può ottenere le informazioni necessarie per generare OpenAPI tramite la firma della funzione;
-
Per le informazioni che non sono comode da fornire tramite la firma, puoi fornirle direttamente aggiungendo attributi nella macro
#[endpoint]. Le informazioni fornite in questo modo verranno unite con le informazioni ottenute tramite la firma della funzione. Se c'è un conflitto, sovrascriverà le informazioni fornite dalla firma della funzione.
Puoi usare l'attributo integrato di Rust #[deprecated] per contrassegnare un Handler come obsoleto. Sebbene l'attributo #[deprecated] supporti l'aggiunta di informazioni come il motivo della deprecazione e la versione, OpenAPI non lo supporta, quindi queste informazioni verranno ignorate durante la generazione di OpenAPI.
La parte del commento di documentazione nel codice verrà estratta automaticamente per generare OpenAPI. La prima riga viene utilizzata per generare summary, e l'intera parte del commento verrà utilizzata per generare description.
ToSchema
Puoi usare #[derive(ToSchema)] per definire strutture di dati:
Puoi usare #[salvo(schema(...))] per definire impostazioni opzionali:
-
example = ...può esserejson!(...).json!(...)verrà analizzato daserde_json::json!comeserde_json::Value. -
xml(...)può essere usato per definire le proprietà dell'oggetto Xml:
ToParameters
Genera [parametri di percorso][path_parameters] dai campi della struttura.
Questa è l'implementazione #[derive] del tratto [ToParameters][to_parameters].
Di solito, i parametri di percorso devono essere definiti in [#[salvo_oapi::endpoint(...parameters(...))]][path_parameters] dell'endpoint. Tuttavia, quando si usa una [struct][struct] per definire i parametri, i passaggi sopra possono essere omessi. Tuttavia, se è necessario fornire una descrizione o modificare la configurazione predefinita, allora i parametri di percorso di tipo [primitive types][primitive] e [String][std_string] o i parametri di percorso in stile [tuple] devono ancora essere definiti in parameters(...).
Puoi usare l'attributo integrato di Rust #[deprecated] per contrassegnare i campi come deprecati, il che si rifletterà nella specifica OpenAPI generata.
L'attributo #[deprecated] supporta l'aggiunta di informazioni extra come il motivo della deprecazione o la versione da cui è deprecato, ma OpenAPI non lo supporta. OpenAPI supporta solo un valore booleano per determinare se è deprecato. Sebbene sia perfettamente possibile dichiarare una deprecazione con un motivo, come #[deprecated = "There is better way to do this"], questo motivo non sarà presentato nella specifica OpenAPI.
Il commento di documentazione sul campo della struttura verrà utilizzato come descrizione del parametro nella specifica OpenAPI generata.
Attributi Contenitore ToParameters per #[salvo(parameters(...))]
I seguenti attributi possono essere utilizzati nell'attributo contenitore #[salvo(parameters(…))] della struttura derivata da ToParameters
names(...)Definisce un elenco separato da virgole di nomi per i campi senza nome della struttura utilizzati come parametri di percorso. Supportato solo su strutture senza nome.style = ...Definisce il metodo di serializzazione per tutti i parametri, specificato da [ParameterStyle][style]. Il valore predefinito è basato sull'attributoparameter_in.default_parameter_in = ...Definisce la posizione predefinita utilizzata dai parametri di questo campo. Il valore di questa posizione proviene da [parameter::ParameterIn][in_enum]. Se questo attributo non viene fornito, il valore predefinito èquery.rename_all = ...può essere utilizzato come alternativa arename_alldiserde. Fornisce effettivamente la stessa funzionalità.
Usa names per definire un nome per un singolo parametro senza nome.
Usa names per definire nomi per più parametri senza nome.
Attributi Campo ToParameters per #[salvo(parameter(...))]
I seguenti attributi possono essere utilizzati sui campi della struttura #[salvo(parameter(...))]:
-
style = ...Definisce come i parametri vengono serializzati da [ParameterStyle][style]. Il valore predefinito è basato sull'attributoparameter_in. -
parameter_in = ...Usa il valore da [parameter::ParameterIn][in_enum] per definire dove si trova questo parametro di campo. Se questo valore non viene fornito, il valore predefinito èquery. -
explodeDefinisce se creare una nuova coppiaparameter=valueper ogni parametro inobjectoarray. -
allow_reservedDefinisce se i caratteri riservati:/?#[]@!$&'()*+,;=sono consentiti nel valore del parametro. -
example = ...può essere un riferimento a un metodo ojson!(...). L'esempio dato sovrascriverà qualsiasi esempio del tipo di parametro sottostante. -
value_type = ...può essere utilizzato per sovrascrivere il tipo predefinito utilizzato dai campi nella specifica OpenAPI. Questo è utile quando il tipo predefinito non corrisponde al tipo effettivo, ad esempio, quando si utilizzano tipi di terze parti non definiti in [ToSchema][to_schema] o tipi [primitive][primitive]. Il valore può essere qualsiasi tipo Rust che può essere serializzato in JSON in circostanze normali, o un tipo personalizzato come _Object_._Object`_ che verrà visualizzato come un oggetto OpenAPI generico. -
inlineSe abilitato, la definizione di questo tipo di campo deve provenire da [ToSchema][to_schema], e questa definizione sarà in linea. -
default = ...può essere un riferimento a un metodo ojson!(...). -
format = ...può essere una variante dell'enum [KnownFormat][known_format], o un valore aperto in forma di stringa. Per impostazione predefinita, il formato è dedotto dal tipo dell'attributo secondo la specifica OpenApi. -
write_onlyDefinisce che l'attributo è utilizzato solo per operazioni di scrittura POST,PUT,PATCH e non per GET. -
read_onlyDefinisce che l'attributo è utilizzato solo per operazioni di lettura GET e non per POST,PUT,PATCH. -
nullableDefinisce se l'attributo può esserenull(nota che questo è diverso da non richiesto). -
required = ...è utilizzato per forzare il parametro a essere obbligatorio. Vedi regole. -
rename = ...può essere utilizzato come alternativa arenamediserde. Fornisce effettivamente la stessa funzionalità. -
multiple_of = ...è utilizzato per definire un multiplo del valore. Il valore del parametro è considerato valido solo quando il valore del parametro è diviso per il valore di questa parola chiave e il risultato è un intero. Il valore multiplo deve essere strettamente maggiore di0. -
maximum = ...è utilizzato per definire il limite superiore del valore, incluso il valore corrente. -
minimum = ...è utilizzato per definire il limite inferiore del valore, incluso il valore corrente. -
exclusive_maximum = ...è utilizzato per definire il limite superiore del valore, escluso il valore corrente. -
exclusive_minimum = ...è utilizzato per definire il limite inferiore del valore, escluso il valore corrente. -
max_length = ...è utilizzato per definire la lunghezza massima di un valore di tipostring. -
min_length = ...è utilizzato per definire la lunghezza minima di un valore di tipostring. -
pattern = ...è utilizzato per definire un'espressione regolare valida a cui il valore del campo deve corrispondere. L'espressione regolare adotta la versione ECMA-262. -
max_items = ...può essere utilizzato per definire il numero massimo di elementi consentiti in un campo di tipoarray. Il valore deve essere un intero non negativo. -
min_items = ...può essere utilizzato per definire il numero minimo di elementi consentiti in un campo di tipoarray. Il valore deve essere un intero non negativo. -
with_schema = ...utilizza un riferimento a una funzione per creare unoschemainvece delloschemapredefinito. La funzione deve soddisfare la definizionefn() -> Into<RefOr<Schema>>. Non riceve alcun parametro e deve restituire qualsiasi valore che possa essere convertito inRefOr<Schema>. -
additional_properties = ...è utilizzato per definire tipi a forma libera permap, comeHashMapeBTreeMap. I tipi a forma libera consentono di utilizzare qualsiasi tipo nei valori della mappa. I formati supportati sonoadditional_propertieseadditional_properties = true.
Regole di nullabilità e obbligatorietà dei campi
Alcune delle regole per la nullabilità e l'obbligatorietà degli attributi dei campi ToParameters possono essere utilizzate anche per gli attributi dei campi ToSchema. [Vedi regole](https