Kompetenzen Portfolio Referenzen Lebenslauf Blog Termin buchen

Wie du REST-Requests teilst, ohne deine Zugangsdaten mitzuliefern

Gepostet von: Felix Dziekan in: Blog am 

Diese Situation kennt jeder. Eine neue Entwicklerin kommt dazu, soll an der REST-API arbeiten und weiß nicht, wo sie anfangen soll. Also teilt jemand im Team hilfsbereit seine private Sammlung von Requests.

Das Problem ist, dass diese Sammlungen auf die Bedürfnisse desjenigen zugeschnitten sind, der sie angelegt hat. Es fehlen die Endpunkte, die diese Person nie angefasst hat, es sind drei Varianten desselben Calls aus einer Debugging-Sitzung im März drin, und etwa ein Fünftel funktioniert seit zwei Releases nicht mehr — aber es ist niemandem aufgefallen, weil diese Person aufgehört hat, sie auszuführen.

Die neue Entwicklerin kann jetzt nicht unterscheiden, welche Fehler ihre eigenen sind und welche einfach Verfall. Das ist eine schlechte erste Woche, und sie ist komplett vermeidbar.

Eine private Sammlung verfällt unsichtbar; eine Sammlung im Repository scheitert sichtbar im Review

Das eigentliche Problem

Es ist nicht, dass die Sammlung veraltet ist. Alles veraltet. Das Problem ist, dass nichts den Verfall sichtbar macht.

Wenn sich ein Endpunkt ändert, zeigt das Code-Review den Controller, den Test und die Dokumentation. Es zeigt nicht, dass Marcos Postman-Sammlung jetzt ein Feld schickt, das die API nicht mehr annimmt, denn diese Sammlung ist nicht Teil des Repositories — sie liegt in einer Anwendung, in einem Account, auf einem Laptop.

Die Lösung ist also nicht "seid disziplinierter beim Aktualisieren der Sammlung". Die Lösung ist, die Requests dorthin zu legen, wo eine Änderung am Endpunkt dich zwingt, sie anzuschauen.

Wenn es nicht im Repository ist, ist es nicht geteilt. Es wurde nur kopiert.

Möglichkeit 1: Postman, ins Repository exportiert

Wenn ihr Postman nutzt — und wenn Nicht-Entwickler Requests schicken müssen, solltet ihr das wahrscheinlich —, halte die Sammlung im Projekt statt in einem Workspace.

Exportier sie nach docs/api/collection.json und committe sie. Importier sie beim Start; exportier und committe wieder, wenn du sie änderst. Es ist ein manueller Schritt, und das ist die Schwäche dieses Ansatzes, aber es macht aus der Sammlung etwas, das in Diffs auftaucht und mit dem Code reviewt wird.

Postmans eigene Git-Integration und öffentliche Workspaces gibt es auch, und die sind in Ordnung — aber sei vorsichtig mit den Sync-Funktionen. Eine Sammlung, die automatisch in einen Cloud-Workspace synchronisiert, ist eine Sammlung, die irgendwann auch ein Produktions-Token dorthin synchronisiert.

Der wichtige Teil ist das, was du nicht committest. Umgebungen enthalten URLs und Zugangsdaten. Committe ein Umgebungs-Template mit leeren Werten und ignorier das echte per gitignore:

 

{
  "name": "local",
  "values": [
    { "key": "host",     "value": "http://localhost" },
    { "key": "email",    "value": "" },
    { "key": "password", "value": "" }
  ]
}

 

Möglichkeit 2: .http-Dateien, direkt neben dem Code

Zu der greife ich, wenn das ganze Team technisch ist. Sowohl PhpStorm als auch VS Code (mit der REST-Client-Erweiterung) lesen dasselbe Klartextformat, die Requests liegen also als ganz normale Dateien im Repository:

 

### einloggen und das Token behalten
# @name login
POST {{host}}/api/login
Content-Type: application/json

{ "email": "{{email}}", "password": "{{password}}" }

### Bewerbungen auflisten
GET {{host}}/api/applications
Authorization: Bearer {{login.response.body.token}}

 

Alles Gute daran folgt daraus, dass es eine Textdatei ist. Sie taucht in einem Diff auf. Sie wird zusammen mit dem Endpunkt reviewt, den sie ausübt. Du kannst nach einem Endpunkt greppen und jeden Request finden, der ihn berührt. Und wenn ein Reviewer eine Controller-Änderung ohne Änderung an der Request-Datei sieht, ist das eine Frage wert.

Secrets bleiben über eine geteilte Umgebungsdatei draußen. Committe http-client.env.json:

 

{
  "local": { "host": "http://localhost" },
  "stage": { "host": "https://stage.example.com" }
}

 

und ignorier http-client.private.env.json per gitignore, wo die Passwörter und Tokens tatsächlich liegen. Neue Entwicklerin klont das Repo, bekommt jeden Request und jede Umgebung, trägt einmal ihre eigenen Zugangsdaten ein und arbeitet.

Möglichkeit 3: aus der Spezifikation erzeugen

Die robusteste Möglichkeit, und die mit dem höchsten Einrichtungsaufwand: gar keine Request-Sammlung pflegen. Pflege eine OpenAPI-Spezifikation — erzeugt aus Attributen an deinen Controllern — und lass das Tooling daraus Requests produzieren.

 

#[OA\Post(
    path: '/api/applications',
    summary: 'Create an application',
    requestBody: new OA\RequestBody(/* … */),
    responses: [new OA\Response(response: 201, description: 'Created')]
)]

 

Weil die Spezifikation aus dem Code kommt, kann sie keinen Endpunkt beschreiben, den es nicht mehr gibt. Swagger UI gibt allen eine Try-it-out-Seite, und sowohl Postman als auch die IDE-Clients können die Spezifikation importieren und daraus bei Bedarf eine Sammlung erzeugen.

Das ersetzt die anderen beiden nicht vollständig — ein erzeugter Request hat leere Beispielwerte und keine Ahnung von dem vierstufigen Ablauf, den du für einen bestimmten Bug brauchst. Aber es heißt, dass niemand mehr fragen muss, welche Endpunkte es gibt.

Was ich tatsächlich mache

Erzeugtes OpenAPI für die Oberfläche, damit sich die API selbst dokumentiert und niemand von einer Person abhängt, die sie erklärt. .http-Dateien im Repository für die Abläufe, die das Team wirklich fährt, reviewt zusammen mit dem Code. Postman nur, wenn jemand außerhalb der Entwicklung Requests schicken muss.

Und für meine eigenen Endpunkte meistens nichts davon — der Funktionstest ist der Request, und er ist die einzige Version, die automatisch weiterläuft, nachdem ich aufgehört habe, daran zu denken.

Falls du dich noch nicht für einen Client entschieden hast, hier ist der Vergleich. Und wenn deiner sich vor jedem Request einloggen muss, automatisier das, statt Tokens von Hand zu kopieren.

Sie brauchen einen Senior-Entwickler, der liefert?

Über 20 Jahre. Produktionssysteme. Echte Deadlines. Ob Architekt, Entwickler oder DevOps-Engineer — ich habe alle drei Rollen übernommen, oft im selben Projekt. Sparen wir uns den Agentur-Overhead und sprechen direkt.