Problem

Du willst eine REST-API mit Node.js und Typescript bauen und API-Konsument*innen eine OpenAPI-Dokumentation aka Swagger bereitstellen? Du hast aber keine Lust, alles doppelt in Code und Doku zu pflegen?

Lösung

Es gibt ein npm-Paket namens "tsoa" (ein Akronym für TypeScript OpenAPI), das aus deinem Typescript-Code automatisch eine passende OpenAPI-Spezifikation generiert. Auf Wunsch kümmert sich tsoa auch um das Routing – also für jeden Request die richtige TypeScript-Funktion aufzurufen. Und es übernimmt auch die Validierung und stellt so sicher, dass die Request-Daten der generierten Spezifikation entsprechen. Weil damit "fast alles" abgedeckt ist, eignet sich tsoa insbesondere für neue Projekte.

Um den TypeScript-Code zur single source of truth zu machen, setzt tsoa auf eine Kombination aus TypeScript-Types (zur Beschreibung des Datenformats), Decorators (für Metadaten wie HTTP-Methods und -Statuscodes) und Doc-Comments (für reine Dokumentation und für Dinge, die sich in TypeScript nicht abbilden lassen, wie z. B. Integers).

Beispiel

import { Body, Controller, Example, Get, Path, Post, 
  Query, Route, Security, SuccessResponse } from "tsoa";
import { userService } from "my-user-service";

/** @isInt @minimum 0 */
export type UserId = number;
export type User = { id: UserId; name: string };
export type UserWithoutId = Omit<User, "id">;

@Route("users")
export class UsersController extends Controller {
  @Example<User>({
    id: 1,
    name: "Benjamin Hogl",
  })
  @Get("{userId}")
  public async getUser(
    @Path() userId: UserId,
    @Query() name?: string
  ): Promise<User> {
    return await userService.get(userId, name);
  }

  @SuccessResponse("201", "Created")
  @Security("jwt", ["ADMIN_ONLY_SCOPE"])
  @Post()
  public async createUser(
    @Body() requestBody: UserWithoutId
  ): Promise<void> {
    await userService.create(requestBody);
    this.setStatus(201);
    return;
  }
}
jambit-ToiletPaper-167-OpenAPI-Dokumentation-mit-TypeScript-Beispiel
jambit-ToiletPaper-167-OpenAPI-Dokumentation-mit-TypeScript

Weitere Aspekte

  • https://tsoa-community.github.io/docs/
  • Die Dokumentation ist leider etwas dürftig, teilweise muss man sich die nötigen Infos aus ein paar Beispielen rausziehen.
  • tsoa bringt Integrationen für die üblichen Node-Server-Frameworks (Express, Koa, Hapi) mit, weitere lassen sich selbst implementieren.
  • Die Logik für Authentication/Authorization muss man in einer zentralen Funktion selbst implementieren. tsoa ruft diese Funktion dann für jeden Request mit den im Security-Decorator angegebenen Parametern auf (siehe Doku).
  • Für die Entwicklung empfiehlt es sich, den Build-Step (=Generierung der OpenAPI-Spezifikation und des Routing-Codes) per nodemon bei jeder Codeänderung neu zu starten (siehe Doku). Das geht zum Glück sehr schnell.
  • Das npm-Paket swagger-ui-express sorgt für die interaktive Anzeige der OpenAPI-Spezifikation (siehe Screenshot).
  • Eine saubere Typisierung macht Refactorings sehr einfach, und mit tsoa meckert der Typechecker sogar über veraltete Beispiele in der API-Doku. Das ist insbesondere praktisch, wenn sich die Anforderungen des Kunden dauernd ändern.

---

SCHREIB UNS

* Pflichtfeld

SCHREIB UNS

* Pflichtfeld

Cookie-Einstellungen

Diese Website verwendet Cookies, um Inhalte und Anzeigen zu personalisieren, Funktionen für soziale Medien anbieten zu können und Zugriffe auf die Website zu analysieren. Zudem werden Informationen zu Ihrer Verwendung der Website an Partner für soziale Medien, Werbung und Analysen weitergegeben. Die Partner führen diese Informationen möglicherweise mit weiteren Daten zusammen, die Sie ihnen bereitgestellt haben oder die sie im Rahmen Ihrer Nutzung der Dienste gesammelt haben.

Weitere Informationen finden Sie in unserer Datenschutzerklärung. Dort können Sie nachträglich auch Ihre Cookie-Einstellungen ändern.

contact icon

Kontakt aufnehmen