Öffnen Sie einen beliebigen Codebestand, der älter als zwei Jahre ist, und Sie werden die Narben finden: /getUser, /user_list, /Users/fetchAll, drei verschiedene Paginierungsschemata und ein customerID-Feld, das neben order_id in derselben Antwort sitzt. Nichts davon führt zu Fehlern. Alles davon verlangsamt jeden.
Die Benennung ist die günstigste API-Designentscheidung, die Sie jemals treffen werden, und die teuerste, die Sie rückgängig machen können. Sobald Clients von /getOrders abhängig sind, müssen Sie es jahrelang unterstützen. Dieser Leitfaden gibt Ihnen eine konkrete Regel für jede Benennungsentscheidung, zu der eine REST-API Sie zwingt, mit einem Beispiel und einem Gegenbeispiel für jede. Er folgt der gleichen Denkweise wie unsere umfassenderen REST-API-Richtlinien für Entwickler, zoomt aber auf den Teil ein, über den Teams am meisten streiten: wie man Dinge benennt.
Wenn Sie diese Regeln lieber mit Tools als mit Code-Review-Kommentaren durchsetzen möchten, können Sie mit Apidog jeden Endpunkt visuell anhand eines gemeinsamen Schemas definieren, bevor jemand Code schreibt. Mehr dazu am Ende.
Verwenden Sie Pluralnomen für Sammlungen
Eine URL benennt eine Ressource, keine Operation. Sammlungen sind Mengen von Dingen, benennen Sie sie daher als Pluralnomen.
Richtig:
GET /v1/products
GET /v1/products/89
GET /v1/orders
Falsch:
GET /v1/getProducts
GET /v1/product
GET /v1/productList
Die Pluralform funktioniert auf beiden Ebenen. /products liest sich als „die Sammlung von Produkten“ und /products/89 als „Produkt 89 innerhalb der Sammlung“. Die singuläre Benennung erzwingt ungeschickte URLs wie /product/89 für ein Element, aber /product für viele, was falsch klingt. Die Microsoft REST API-Richtlinien haben sich aus genau diesem Grund für Pluralnomen entschieden, und die meisten öffentlichen APIs (Stripe, GitHub, Shopify) sind diesem Weg gefolgt.
Eine Ausnahme: Singleton-Ressourcen. Wenn ein Benutzer genau einen Warenkorb hat, ist /users/42/cart in Ordnung. Vergeben Sie keinen Plural für etwas mit einer Kardinalität von eins.
Vermeiden Sie Verben in Pfaden
Die HTTP-Methode ist das Verb. Ein weiteres Verb im Pfad dupliziert Informationen und bricht das Ressourcenmodell.
Richtig:
GET /v1/orders/42 (lesen)
DELETE /v1/orders/42 (löschen)
PATCH /v1/orders/42 (aktualisieren)
Falsch:
GET /v1/fetchOrder/42
POST /v1/deleteOrder/42
POST /v1/updateOrderStatus
Verben-basierte Pfade vervielfachen auch Ihre Angriffsfläche. Eine Ressource mit vier Methoden wird zu vier Endpunkten, die separat dokumentiert, getestet und zwischengespeichert werden müssen. Die Cache-Invalidierung verschlechtert sich ebenfalls: Ein CDN kann GET /v1/orders/42 cachen und bei DELETE /v1/orders/42 invalidieren, da beide auf dieselbe URL zeigen. Es kann /fetchOrder/42 nicht mit /deleteOrder/42 verbinden.
Verwenden Sie Kebab-Case in URL-Pfaden
Mehrteilige Pfadsegmente benötigen einen Trennzeichen, und Bindestriche sind die richtigen.
Richtig:
/v1/gift-cards
/v1/shipping-addresses
Falsch:
/v1/giftCards
/v1/gift_cards
/v1/GiftCards
Drei Gründe. Google behandelt Bindestriche als Worttrenner für die Indexierung, sodass öffentliche API-Dokumente mit Kebab-Case besser ranken. Unterstriche verschwinden, wenn eine URL in einer E-Mail oder einem Dokument unterstrichen wird. Und CamelCase in URLs lädt zu Groß-/Kleinschreibungsempfindlichkeits-Bugs ein: /giftCards und /giftcards sind auf den meisten Servern unterschiedliche URLs, und jemand wird die falsche eingeben. Die Zalando RESTful API-Richtlinien machen Kebab-Case zu einer MUSS-Regel, und sie haben dieses Vorgehen in Hunderten von internen Diensten angewendet.
Wählen Sie eine JSON-Groß-/Kleinschreibung und halten Sie sie fest
Für Feldnamen innerhalb von Anforderungs- und Antwortkörpern lautet die ehrliche Antwort: camelCase und snake_case funktionieren beide. Was nicht funktioniert, ist deren Mischung.
Richtig (eine, konsistent):
{ "orderId": 42, "createdAt": "2026-08-30T09:15:00Z", "totalAmount": 4999 }
{ "order_id": 42, "created_at": "2026-08-30T09:15:00Z", "total_amount": 4999 }
Falsch:
{ "orderId": 42, "created_at": "2026-08-30T09:15:00Z", "TotalAmount": 4999 }
camelCase passt gut zu JavaScript- und Java-Clients. snake_case ist leichter zu scannen und passt zu Ruby, Python und den meisten SQL-Spaltennamen; Stripe verwendet es überall. Treffen Sie Ihre Wahl basierend darauf, wer Ihre API am häufigsten konsumiert, und nehmen Sie die Entscheidung dann in Ihren Styleguide auf, damit die Debatte einmal stattfindet und nicht bei jedem Pull Request. Gemischte Groß-/Kleinschreibung ist die häufigste Inkonsistenz in realen APIs, da verschiedene Teams unterschiedliche Endpunkte ausliefern. Das ist ein Governance-Versagen, kein Geschmacksversagen.
Begrenzen Sie die Verschachtelung auf zwei Ebenen
Verschachtelung drückt Besitz aus: /users/42/orders bedeutet „Bestellungen, die Benutzer 42 gehören“. Das ist nützlich. Nach zwei Ebenen ist es nicht mehr nützlich.
Richtig:
GET /v1/users/42/orders
GET /v1/orders/1337/refunds
Falsch:
GET /v1/users/42/orders/1337/refunds/7/status
Tiefe Verschachtelung zwingt Clients, jede übergeordnete ID mitzuführen, um eine Blattressource zu erreichen, selbst wenn das Blatt eine eigene global eindeutige ID hat. Wenn eine Rückerstattung die ID 7 hat, geben Sie sie unter /refunds/7 oder /orders/1337/refunds/7 an und hören Sie dort auf. Ein guter Geruchstest: Wenn eine URL drei oder mehr IDs enthält, machen Sie sie flacher. Sobald eine Bestellung existiert, benötigt sie ihren Benutzer nicht mehr im Pfad; /orders/1337 steht für sich allein.
Filtern, Sortieren und Paginierung in Abfrageparametern platzieren
Pfade identifizieren Ressourcen. Abfrageparameter ändern, wie Sie diese anzeigen. Kodieren Sie niemals einen Filter in den Pfad.
Richtig:
GET /v1/orders?status=active&sort=-created_at&limit=50&cursor=eyJpZCI6NDJ9
GET /v1/products?category=electronics&min_price=1000
Falsch:
GET /v1/orders/active
GET /v1/orders/sorted-by-date-desc
GET /v1/getOrdersByStatusAndDate
Das Muster sort=-created_at (Minus-Präfix für absteigend) stammt aus der JSON:API-Spezifikation und erspart Ihnen einen zweiten Parameter order=desc. Filterpfade wie /orders/active sehen harmlos aus, bis Sie Filter kombinieren müssen, und dann erstellen Sie für jede Kombination einen neuen Endpunkt. Paginierungsparameter-Namen verdienen dieselbe Disziplin: Wählen Sie limit/cursor oder page/per_page einmal aus und verwenden Sie sie für jede Sammlung wieder. Unser API-Paginierungsleitfaden behandelt den Kompromiss zwischen Cursor und Offset ausführlich; die Benennungsregel hier ist einfach, einheitlich zu sein.
Version im Pfad
Sie haben zwei gängige Optionen: ein Pfadsegment (/v1/products) oder einen Header (Accept: application/vnd.myapi.v1+json). Header-Versionierung ist „reiner“ REST, da die URL über Versionen hinweg dieselbe Ressource benennt, und die Google API-Designanleitung weist darauf hin, dass beide Ansätze in der Praxis existieren. Aber die Pfad-Versionierung gewinnt aus operativen Gründen: Sie ist in jeder Protokollzeile sichtbar, über einen Browser testbar, ohne Vary-Akrobatik cachebar und für einen Client unmöglich zu vergessen. Jeder Entwickler, der ein „funktioniert in curl, schlägt in der Produktion fehl“-Problem aufgrund eines fehlenden Versionsheaders debuggt hat, kennt die Kosten der Alternative. Verwenden Sie /v1/ nur mit einer Hauptversion, kein /v1.2/; geringfügige Änderungen sollten additiv und nicht-brechend sein. Für den vollständigen Entscheidungsbaum, einschließlich Content Negotiation, siehe unseren Vergleich der API-Versionierungsstrategien.
Behandeln Sie Ressourcen-IDs als undurchsichtig und geben Sie sequenzielle Ganzzahlen nicht leichtfertig preis
/orders/41, /orders/42, /orders/43: Sequenzielle Ganzzahl-IDs verraten jedem, der hinsieht, genau, wie viele Bestellungen Sie verarbeiten, und sie laden zu Enumerationsangriffen ein, bei denen ein Angreifer den ID-Raum nach Autorisierungslücken durchsucht. Diese Art von Fehler, gebrochene objektbasierte Autorisierung, steht auf Platz eins der OWASP API Security Top 10.
Richtig:
GET /v1/orders/ord_9f8e2a71b3
GET /v1/users/550e8400-e29b-41d4-a716-446655440000
Falsch (wenn Enumeration relevant ist):
GET /v1/orders/42
GET /v1/invoices/10883
Vorangestellte zufällige IDs wie Stripes ord_9f8e2a71b3 sind das stärkste Muster: unerratbar, selbsterklärend in Protokollen und sicher preiszugeben. Autorisierungsprüfungen sind in jedem Fall weiterhin zwingend erforderlich. Undurchsichtige IDs reduzieren den Schadenbereich einer fehlenden Prüfung; sie ersetzen diese nicht. Intern können Sie Ganzzahl-Primärschlüssel beibehalten; die Regel bezieht sich darauf, was Sie in URLs preisgeben.
Modellieren Sie Nicht-CRUD-Aktionen als Controller-Ressourcen
Früher oder später benötigen Sie eine Aktion ohne saubere CRUD-Zuordnung: eine Bestellung stornieren, eine Zahlung erneut versuchen, eine E-Mail erneut senden. Tunneln Sie es nicht über PATCH auf einem Statusfeld und platzieren Sie kein Verb auf der obersten Ebene.
Richtig:
POST /v1/orders/42/cancel
POST /v1/payments/pay_88a1/retry
Falsch:
PATCH /v1/orders/42 { "status": "cancelled" }
POST /v1/cancelOrder { "orderId": 42 }
Dies ist das Controller-Muster, und es ist die eine sanktionierte Ausnahme von der Keine-Verben-Regel: Das Verb steht am Ende des Pfades, unterhalb der Ressource, auf die es wirkt. Der PATCH-Ansatz sieht RESTful aus, verbirgt aber eine Zustandsmaschine innerhalb eines Feld-Updates. Eine Bestellung zu stornieren löst Rückerstattungen aus, gibt Lagerbestände frei und sendet Benachrichtigungen; so zu tun, als wäre es ein Feld-Schreibvorgang, zwingt Ihren Server, Payloads zu vergleichen, um die Absicht zu erkennen. Ein /cancel-Endpunkt gibt die Absicht an, weist der Aktion eigene Berechtigungen und einen Audit-Trail zu und lässt Raum für aktionsspezifische Eingaben wie einen Stornierungsgrund.
Halten Sie die Groß-/Kleinschreibung für Header und Abfrageparameter konsistent
Zwei kleinere Oberflächen, gleiche Disziplin. Benutzerdefinierte Header verwenden Hyphenated-Pascal-Case, passend zur HTTP-Konvention: Idempotency-Key, Request-Id. Überspringen Sie das alte X--Präfix; es wurde 2012 durch RFC 6648 veraltet. Headernamen sind im Übertragungsprotokoll nicht Groß-/Kleinschreibung-sensitiv, aber Ihre Dokumentation und SDKs sollten sie dennoch einheitlich schreiben.
Abfrageparameter sollten der Groß-/Kleinschreibung Ihres JSON-Bodys entsprechen. Wenn Ihre Bodies snake_case verwenden, schreiben Sie ?min_price=1000&created_after=2026-01-01, nicht ?minPrice=1000. Ein Entwickler, der created_at in einer Antwort liest und createdAfter in einer Abfrage eingeben muss, wird es beim ersten Versuch falsch machen, und alle nach ihm auch.
Das vollständige Regelwerk auf einen Blick
| # | Regel | Richtig | Falsch |
|---|---|---|---|
| 1 | Pluralnomen für Sammlungen | /products, /products/89 |
/getProducts, /productList |
| 2 | Keine Verben in Pfaden | DELETE /orders/42 |
POST /deleteOrder/42 |
| 3 | Kebab-Case für Pfadsegmente | /gift-cards |
/giftCards, /gift_cards |
| 4 | Eine JSON-Groß-/Kleinschreibung, dokumentiert | order_id überall |
orderId und order_id gemischt |
| 5 | Maximal zwei Verschachtelungsebenen | /orders/1337/refunds |
/users/42/orders/1337/refunds/7 |
| 6 | Filter und Paginierung in Abfrageparametern | ?status=active&sort=-created_at |
/orders/active |
| 7 | Hauptversion im Pfad | /v1/products |
/v1.2/products, Versions-Header |
| 8 | Undurchsichtige Ressourcen-IDs | /orders/ord_9f8e2a71b3 |
/orders/42 (öffentlich, aufzählbar) |
| 9 | Controller-Muster für Aktionen | POST /orders/42/cancel |
PATCH mit {"status":"cancelled"} |
| 10 | Konsistente Groß-/Kleinschreibung für Header und Parameter | Idempotency-Key, ?min_price= |
X-IDEMPOTENCY_KEY, ?minPrice= gemischt |
Konventionen im großen Maßstab durchsetzen
Ein Styleguide in einem Wiki ändert nichts. Die Teams, deren APIs konsistent bleiben, teilen eine Gewohnheit: Sie entwerfen zuerst und setzen die Konventionen durch, bevor Code existiert, was der Kern von API-Governance in der Praxis ist.
Hier verdient Apidog seinen Platz im Workflow. Endpunkte werden in einem schema-first visuellen Designer definiert, sodass Pfad, Groß-/Kleinschreibung und Parameternamen explizite Design-Artefakte sind, anstatt Zeichenketten, die im Controller-Code vergraben sind. Geteilte Komponenten bedeuten, dass Pagination, Error und Money-Schemata einmal definiert und über jeden Endpunkt hinweg wiederverwendet werden; niemand erfindet per_page als pageSize in einem neuen Dienst neu. Und da Designs in Team-Workspaces mit integrierter Überprüfung leben, kann ein Lead /getUserOrders bereits in der Designphase erkennen, wenn das Umbenennen einen Klick kostet, anstatt nachdem drei Clients es integriert haben. Die Spezifikation treibt dann Dokumentationen, Mock-Server und Tests an, sodass die von Ihnen genehmigten Namen die Namen sind, die jeder ausliefert. Laden Sie Apidog herunter und probieren Sie es kostenlos mit Ihrem nächsten neuen Endpunkt aus; eine alte API nachzurüsten ist schwierig, aber bei neuen die Linie zu halten ist es nicht.
Häufig gestellte Fragen
Sollten REST-URLs Plural oder Singular sein?
Plural, für jede Ressource mit mehr als einer Instanz: /products, /orders, /users. Die Pluralform bleibt sowohl für die Sammlung (/orders) als auch für ein Mitglied (/orders/42) natürlich. Reservieren Sie singuläre Namen für echte Singletons wie /users/42/cart. Wenn Sie die tiefere Begründung hinter der Ressourcenmodellierung erfahren möchten, führt unser Leitfaden zu was eine REST-API ist Sie durch die Grundlagen.
Ist camelCase oder snake_case besser für JSON-Feldnamen?
Keines gewinnt aus Verdienst. camelCase passt gut zu JavaScript-lastigen Konsumenten; snake_case ist lesbarer und passt zu Python, Ruby und Stripes öffentlicher API. Die durchsetzbare Regel: Wählen Sie eine, schreiben Sie sie in Ihren Styleguide und setzen Sie sie bei der Schemaüberprüfung durch. Gemischte Groß-/Kleinschreibung über Endpunkte hinweg schadet mehr als jede einzelne Wahl.
Sollte ich die API-Version in die URL oder einen Header einfügen?
Verwenden Sie den Pfad (/v1/orders), es sei denn, Sie haben eine starke Hypermedia-Anforderung. Pfadversionen erscheinen in Protokollen, Caches und Browser-Tests ohne Client-Aufwand. Header-Versionierung hält URLs über Versionen hinweg stabil, schlägt aber stillschweigend fehl, wenn Clients den Header vergessen. Nur Hauptversionen; liefern Sie kleinere Änderungen als additive, nicht-brechende Updates aus.
Sind Verben jemals in einem REST-API-Pfad akzeptabel?
Ja, an einer Stelle: Controller-Endpunkte für Nicht-CRUD-Aktionen, wie POST /orders/42/cancel oder POST /payments/pay_88a1/retry. Das Verb steht am Ende des Pfades, innerhalb seiner Ressource, und die Methode ist immer POST. Überall sonst trägt die HTTP-Methode das Verb, und der Pfad bleibt nur aus Nomen bestehend.
