Swagger: dokumentacja
Istotną informacją jest fakt, iż instalacja Swagger nie zastępuje domyślnych stron pomocy. Mogą być one używane równocześnie i nie powodują wzajemnych konfliktów.
W celu instalacji pakietu przechodzimy do Nuget Package Manager w poszukiwaniu poniższej paczki:
Po zainstalowaniu przejdź do folderu App_Start - możesz tam zobaczyć nowy plik konfiguracyjny SwaggerConfig.cs.
W tym pliku włączamy domyślną obsługę oraz możemy dokonać niezbędnej konfiugracji. Warto mieć na uwadzę, że 90% kodu jest zakomentowane (z odpowiednimi informacjami do rozszerzenia konfiguracji). Włączone są jedynie podstawowe opcje.
Minimalna konfiguracja niezbędna do działa (odkomentowana) prezentuje się w następujący sposób:
GlobalConfiguration.Configuration
.EnableSwagger(c => c.SingleApiVersion("v1", "Tytuł Twojej dokumentacji (W moim przpadku: SwaggerUI)"))
.EnableSwaggerUi();
Jesteśmy już gotowi do uruchomienia naszego projektu. W tym celu należy dodać do naszego adresu końcówkę /swagger
Domyślny kontroler nieco zmodyfikowałem, po uruchomieniu dokumentacji generowanej przez Swagger przedstawia się w następujący sposób:
Z tego poziomu możemy wyświetlić szczegóły danej metody a z pomocą przycisku "Try it out!" możemy nawiązać połączenie z tym konkretnym API:
Swagger: komentarze XML
Podstawowa konfiugracja jest dobra na samym początku. W tej cześci skupimy się na większej personalizacji naszej dokumentacji. Możemy powiedzieć Swashbuckle, aby używał komentarzy XML, które pozwalą na dodanie znacznie większej liczby szczegółów do metadanych Swagger. Są to te same komentarze XML z których korzystają strony pomocy ASP.NET.
W pierwszym kroku należy włączyć tworzenie dokumentacji XML podczas kompilacji. Przechodzimy do właściwości naszego projektu a następnie, w zakładce Build, zaznaczamy XML documentation file:
Możemy śmiało zostawić domyślną ścieżkę pliku – będzie ona nam jednak potrzebna do konfiguracji.
Musimy jednak odpowiednio zaktualizować naszą konfiugrację. Swashbuckle musi dodać nasze komentarze XML do metadanych Swagger. Dodajemy poniższa linię do naszej konfiguracji, tj. pliku SwaggerConfig.cs (potrzebujemy również ścieżki do pliku z poprzedniego kroku):
c.IncludeXmlComments(string.Format(@"{0}\bin\SwaggerUI.XML", System.AppDomain.CurrentDomain.BaseDirectory));
Nasza docelowa konfiguracja przedstawia się następujący sposób:
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.SingleApiVersion("v1", "Tytuł Twojej dokumentacji (W moim przpadku: SwaggerUI)");
c.IncludeXmlComments(string.Format(@"{0}\bin\SwaggerUI.XML",
System.AppDomain.CurrentDomain.BaseDirectory));
})
.EnableSwaggerUi();
Jeżeli nie mamy jeszcze żadnych komentarzy, warto poświecić na to kilka chwil i je dodać:
Po ponowym uruchomieniu projektu powiniśmy zobaczyć zdecydowanie więcej szczegółów:
Swagger: plik JSON
To co do tej pory zobaczyliście to reprezentacja UI naszych metadanych API Swagger. Aby zobaczyć co tak naprawdę kryję się pod pojęciem Swagger należy przejść do adresu URL znajdującego się w nagłówku dokumentacji:
{
"swagger":"2.0",
"info":{
"version":"v1",
"title":"SwaggerUI"
},
"host":"localhost:58122",
"schemes":[
"http"
],
"paths":{
"/api/Cars":{
"get":{
"tags":[
"Cars"
],
"summary":"Metoda pozwalająca na pobranie listy samochodów",
"operationId":"Cars_Get",
"consumes":[
],
"produces":[
"application/json",
"text/json",
"application/xml",
"text/xml"
],
"responses":{
"200":{
"description":"OK",
"schema":{
"type":"array",
"items":{
"$ref":"#/definitions/CarModel"
}
}
}
}
},
"post":{
"tags":[
"Cars"
],
"operationId":"Cars_Post",
"consumes":[
"application/json",
"text/json",
"application/xml",
"text/xml",
"application/x-www-form-urlencoded"
],
"produces":[
],
"parameters":[
{
"name":"value",
"in":"body",
"required":true,
"schema":{
"type":"string"
}
}
],
"responses":{
"204":{
"description":"No Content"
}
}
}
},
"/api/Cars/{id}":{
"get":{
"tags":[
"Cars"
],
"operationId":"Cars_Get",
"consumes":[
],
"produces":[
"application/json",
"text/json",
"application/xml",
"text/xml"
],
"parameters":[
{
"name":"id",
"in":"path",
"required":true,
"type":"integer",
"format":"int32"
}
],
"responses":{
"200":{
"description":"OK",
"schema":{
"type":"string"
}
}
}
},
"put":{
"tags":[
"Cars"
],
"operationId":"Cars_Put",
"consumes":[
"application/json",
"text/json",
"application/xml",
"text/xml",
"application/x-www-form-urlencoded"
],
"produces":[
],
"parameters":[
{
"name":"id",
"in":"path",
"required":true,
"type":"integer",
"format":"int32"
},
{
"name":"value",
"in":"body",
"required":true,
"schema":{
"type":"string"
}
}
],
"responses":{
"204":{
"description":"No Content"
}
}
},
"delete":{
"tags":[
"Cars"
],
"operationId":"Cars_Delete",
"consumes":[
],
"produces":[
],
"parameters":[
{
"name":"id",
"in":"path",
"required":true,
"type":"integer",
"format":"int32"
}
],
"responses":{
"204":{
"description":"No Content"
}
}
}
}
},
"definitions":{
"CarModel":{
"description":"Definicja pojazdu",
"type":"object",
"properties":{
"Brand":{
"description":"Marka samochodu",
"type":"string"
},
"Model":{
"description":"Model samochodu",
"type":"string"
},
"Engine":{
"description":"Pojemność silnika",
"type":"string"
},
"Power":{
"description":"Moc silnika",
"type":"string"
},
"EngineType":{
"description":"Rodzaj silnika",
"enum":[
"Diesel",
"Petrol"
],
"type":"string"
}
}
}
}
}
W ten sposób można "odkryć" i poznać cały interfejs API. Te metadane pozwalają poinformować inne API o możliwości wzajemnych oddziaływań (lub krócej: dostępnych akcji). Dzięki tej dokumentacji można również utworzyć bibliotekę klienta, którą następnie możemy przekazać do klientów/użytkowników/partnerów, w celu przejrzystego opisania interakcji z naszym API.