Automatisch generierter Javascript-Client durch Swagger

Schnittstellen Dokumentation, die sich selber schreibt!

Gepostet von Tobias Merki am 29.06.2020

Swagger API OpenSource C# Javascript-Client React

Was ist Swagger?

Swagger ist ein Open-Source Tool, um APIs zu erstellen und zu dokumentieren. Dabei ist Swagger in der Lage, bestehende APIs zu analysieren und aufgrund dieser Analyse eine standardisierte Dokumentation zu erstellen.

Mit ein wenig Mehraufwand ist Swagger zusätzlich dazu fähig, zu bestehenden APIs entsprechende Javascript-Clients zu generieren, um beispielsweise die Verwendung in einem React-Projekt zu automatisieren. So lassen sich mühsame Handarbeit und die daraus resultierende Fehleranfälligkeit minimieren.

Anforderungen

Es sollte ein ASP.NET Core API-Projekt bestehen, optimalerweise bereits mit mindestens einem funktionierenden Endpunkt. Zusätzlich sollte entweder ein weiteres Projekt für den Client oder eine entsprechende Area im bestehenden Projekt, für den der Client bestimmt ist, vorhanden sein.

Swagger installieren

Nun installieren wir Swagger in das Projekt, das die API beinhaltet. Wir haben uns hier bewusst für das Nuget „NSwag.AspNetCore“ entschieden, da dies die Installation und das Aktualisieren stark vereinfacht. Es verhindert zudem bereits bei der Initialisierung grundlegende Fehler.

Nach dem Hinzufügen des Nuget-Packages muss Swagger nur noch im Startup-File konfiguriert werden. Dazu wird die Funktion «ConfigureServices» am Ende um folgende Zeile ergänzt «services.AddSwaggerDocument();» sowie die Funktion «Configure» wie folgt (bereits bestehender Code in Zeile 1 + 7):

app.UseRouting();

// Enable the Swagger UI middleware and the Swagger generator 
app.UseOpenApi(); 
app.UseSwaggerUi3();

app.UseAuthorization();

Anschließend kann die Applikation gestartet und unter dem Pfad «/swagger» das Swagger-Interface aufgerufen werden.

Den Client generieren

Um Änderungen zu übernehmen, legen wir über den Visualstudio Code im «.vscode» Ordner ein neues File «tasks.json» an (oder erweitern dieses, sollte es bereits vorhanden sein):

{
	"version": "2.0.0", 
	"tasks": [
		{
			"label": "nswag-ts-generation", 
			"type": "shell",
			"windows": {
				"command": "nswag"
			}
			"args": ["run", ".vscode/config.nswag", "/runtime:NetCore31"], 
			"dependsOn": "build" 
		},
		{
		"label": "build", 
		"command": "dotnet", 
		"type": "process", 
		"args": [ 
			"build", 
			"${workspaceFolder}/SwaggerExampleApi/SwaggerExample.Api.csproj", 
			"/property:GenerateFullPaths=true", 
			"/consoleloggerparameters:NoSummery" 
			], 
			"problemMatcher": "$msCompile" 
		}
	]
}

Wichtig ist die Anpassung des Pfades im «build»-Task auf das Projekt-File der API. Nun erstellen wir im selben Ordner noch ein «launch.json», in welchem wir den oben erstellten Task verlinken:

{
	"version": "0.2.0",
	"configurations": [
		{
			"name": ".NET Core Launch (web)", 
			"type": "coreclr", 
			"request": "launch", 
			"preLaunchTask": "nswag-ts-generation", 
			"program": "${workspaceFolder}/SwaggerExampleApi/bin/Debug/netcoreapp3.1/SwaggerExample.Api.dll", 
			"args": [], 
			"cwd: "${workspaceFolder}/SwaggerExampleApi", 
			"stopAtEntry": false, 
			"serverReadyAction": {
				"action": "openExternally", 
				"pattern": "^\\s*Now listening on:\\s+(https?://\\S+)"
			}
			"env": {
				"ASPNETCORE_ENVIRONMENT": "Development" 
			}, 
			"sourceFileMap": {
				"/Views": "${workspaceFolder}/Views"
			}
		}
	]
}

Im File «tasks.json» haben wir bei den Argumenten das File «.vscode/config.nswag» als Konfiguration mitgegeben. Dieses müssen wir jetzt entsprechend im «.vscode» Ordner erstellen: Siehe hier

Dabei ist zu beachten, dass im ersten Teil der Projekt-Pfad und im zweiten Teil der «output» Pfad korrekt angepasst werden. Alle weiteren möglichen Konfigurationen können in der offiziellen Dokumentation nachgesehen werden: GitHub Dokumentation

Wenn wir nun das API-Projekt über Ctrl+F5 starten, wird automatisch eine neue client.ts-Datei generiert. Diese enthält für jeden Controller der API eine eigene Client-Klasse und kann direkt im Javascript-Code verwendet werden:

const bookClient = new BookClient("baseUrl"); 
bookClient.getNewest().then(book) => {
}); 
bookClient.getList(5).then((books) => {
	console.log.(books); 
}); 
bookClient.save({
	pages: 500, 
	price: 50.0, 
	publishDate: null, 
	isbn: "XXXXXXXXXX", 
});

In diesem Beispiel gibt es einen Controller «BookController», der die Aktionen «GetNewest», «GetList» sowie «Save» enthält. Diese werden direkt korrekt im Javascript abgebildet und auch die IntelliSense mit allen Rückgabe-Objekten (z.B. «book.isbn») funktioniert einwandfrei.