Wer kennt das nicht? Die Liste der Rest APIs die eine Anwendung bereit stellt wächst mit jedem Release. Dokumentationen sind rar gesät und befinden sich verstreut im Code oder externen Tools und werden nur rudimentär (oder überhaupt nicht?) auf dem aktuellen Stand gehalten. Darüber hinaus sind die Schritte um eine neue Schnittstelle ein zu binden erschreckend ähnlich und die Implementierung nimmt doch immer wieder Zeit in Anspruch. Eine Lösung? Swagger.
Swagger definiert erst einmal ein einheitliches Format (yaml oder json) in dem Schnittstellen beschrieben werden. Diese Dokumentationen kann entweder per Hand über einen entsprechenden Online Editor erstellt werden (http://editor.swagger.io/#/) oder aber aus bestehenden Rest-Schnittstellen generiert werden. Schauen wir uns einfaches Beispiel (top-down) einer solchen Definition einmal an.
Dieses Beispiel ist im YAML-Format über den Online Editor verfasst:
swagger: '2.0' info: version: 1.0.0 title: Simple Swagger Demo paths: '/echo/{name}': get: description: Simple Echo-Service parameters: - name: name in: path description: name of the caller required: true type: string - name: message in: query description: message to be echoed required: true type: string produces: - application/json responses: '200': description: Successful schema: title: Echo type: string '400': description: Parameter not fulfill the requirements /time: get: description: get the current time as object produces: - application/json responses: '200': description: Successful schema: title: current time type: object properties: year: type: number month: type: number day: type: number hour: type: number minute: type: number second: type: number
Ohne auf die einzelnen Elemente ein zu gehen wird ersichtlich das wir mithilfe dieser Beschreibung die vorhandenen Rest-Schnittstellen in einem einheitlichen Format beschrieben und dokumentieren werden können. Am Ende kann Swagger daraus eine nette Web UI erzeugen, die auch mit rudimentären Test-Aufruf-Möglichkeiten versehen ist. Das alleine wird aber wohl noch niemandem zur großen Begeisterungsstürmen veranlassen. Seine wahre Stärke spiele Swagger im nächsten Schritt aus:
Vorbei die Zeiten in denen eine Dokumentation das Dasein als simples Dokument fristen muss. Swagger bietet uns die Möglichkeit auf Basis unserer Dokumentation sowohl die Server-Komponente, als auch Client-Stubs zu generieren, die sich im eigenen Projekt einbinden lassen. Aus der oben gezeigten Beschreibung entstehen so auf Knopfdruck Server und Client die im Fall von „JaxRS Resteasy“ und „Angular 2“ so aussehen wie in den folgenden beiden Beispiel Projekten:
GITHUB – swagger-server-demo
GITHUB – swagger-angular2-demo
Botton-Up
Zugegeben auf Seiten des Servers mag das Schreiben einer Swagger Definition für komplexe Objekte eher mühsam sein. Die Alternative zum Schreiben der Definition besteht darin Swagger im eigenen Projekt als Bibliothek ein zu binden und die Definition erstellen zu lassen. Die entsprechenden Dokumentation werden dann innerhalb der Klassen per Swagger-Annotationen durchgeführt. Nach dem Deployment bietet Swagger dann die übliche Web-UI mit Test-Funktionalität und Dokumentation. Zusätzlich kann die yaml/json Beschreibung herunter geladen werden um daraus dann wieder beliebige Client-Stubs zu generieren. Um dies in bestehende Projekte ein zu binden Bedarf es einer zusätzlichen Maven-Abhänigkeit
io.swagger swagger-jaxrs 1.5.10
Anschließend konfigurieren wir Swagger noch über eine entsprechende Application-Klassen-Implementierung:
de.gedoplan.swagger.server.bu.demo.SwaggerApplication.java
import de.gedoplan.swagger.server.bu.demo.resource.CustomerAPI; import io.swagger.jaxrs.config.BeanConfig; import java.util.HashSet; import java.util.Set; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; @ApplicationPath("rest") public class SwaggerApplication extends Application { public SwaggerApplication() { BeanConfig beanConfig = new BeanConfig(); beanConfig.setVersion("1.0.0"); beanConfig.setSchemes(new String[]{"http"}); beanConfig.setHost("localhost:8080/swagger-server-bu-demo-1.0-SNAPSHOT"); beanConfig.setBasePath("/rest"); beanConfig.setResourcePackage("de.gedoplan.swagger.server.bu.demo.resource"); beanConfig.setScan(true); } @Override public Set<Class> getClasses() { HashSet<Class> set = new HashSet(); set.add(CustomerAPI.class); set.add(io.swagger.jaxrs.listing.ApiListingResource.class); set.add(io.swagger.jaxrs.listing.SwaggerSerializers.class); return set; } }
Nun können unsere Rest-Schnittstellen mit entsprechenden Annotationen versehen werden um die Dokumentation auf zu bauen (s. Annotations)
de.gedoplan.swagger.server.bu.demo.resource.CustomerAPI.java
@GET @ApiOperation(value = "Returns one random customer", notes = "Mock Implementation", response = Customer.class) public Customer getCustomer() { ... }
Anschließend kann die json/yaml Datei über den Webserver bezogen werden (http://localhost:8080/swagger-server-bu-demo-1.0-SNAPSHOT/rest/swagger.json) um dann über den Editor entsprechende Clients zu generieren. Will man gleich auf dem lokalen Webserver eine Test/Doku Funktionalität bieten kann die Swagger-UI auch im eigenen Projekt eingebunden werden. Dazu einfach den „dist“ Ordner des Github Projektes im eigenen Web-Folder unterbringen und in der index.html die URL auf die eigene swagger.json ändern.
Dokumentationen zu schreiben ist mühsam und zeitintensiv und allzu oft werden diese nicht aktuell gehalten. Swagger bietet neben der Dokumentation-Funktion einen echten Mehrwert für die Entwicklung und bietet mit der automatischen Generierung von Code, sowohl für den Server, als auch für den Client, einen echten WOW-Effekt.
Also: Schluss mit Word-Dokumente und Excel Sheets. Check Swagger!
1 Kommentar. Hinterlasse eine Antwort
Mit „Button-Up“ ist vermutlich eher „Bottom-Up“ gemeint oder?