Grundlagen der OpenAPI-Spezifikation

Die OpenAPI-Spezifikation (OAS) ist ein Standardformat zur Beschreibung von RESTful-APIs.

Die OpenAPI-Spezifikation ermöglicht es Entwicklern, API-Struktur, Parameter, Antworten und andere Informationen maschinenlesbar zu definieren.

Die OpenAPI-Spezifikation hieß ursprünglich Swagger-Spezifikation; später wurde sie an die OpenAPI Initiative gespendet und in OpenAPI umbenannt.

Zu den Hauptfunktionen der OpenAPI-Spezifikation gehören:

  • Standardisierte Dokumentation für APIs bereitstellen
  • Automatisiertes Testen von APIs unterstützen
  • Client-SDKs generieren
  • Die Trennung von Frontend- und Backend-Entwicklung fördern

OpenAPI hat derzeit zwei weit verbreitete Versionen:

  1. OpenAPI 2.0 (früher Swagger 2.0)
  2. OpenAPI 3.x (neueste stabile Version)

Für neue Projekte wird die Verwendung von OpenAPI 3.x empfohlen, da es mehr Funktionen und Verbesserungen bietet.

Struktur der OpenAPI-Spezifikation

OpenAPI-Dokumente werden üblicherweise im YAML- oder JSON-Format geschrieben.

Nachfolgend ist eine grundlegende OpenAPI-Dokumentstruktur:

Beispiel

openapi: 3.1.0 # OpenAPI-Version
info:
title: Beispiel-API # API-Name
description: Dies ist ein Beispiel-API-Dokument
version: 1.0.0 # API-Version
servers:
- url: https://api.example.com/v1 # API-Serveradresse
description: Produktionsumgebung
  - url: https://dev-api.example.com/v1
description: Entwicklungsumgebung

paths: # Definitionen der API-Pfade
/users: # Endpunktpfad
get: # HTTP-Methode
summary: Alle Benutzer abrufen
description: Gibt eine Liste aller Benutzer im System zurück
      operationId: getUsers
      Tags:
- users # Gruppen-Tag
parameters: # Anfrageparameter
        - name: limit
          in: query
description: Begrenzung für die Anzahl der zurückgegebenen Ergebnisse
          schema:
            type: integer
            default: 20
responses: # Antwortdefinitionen
'200': # HTTP-Statuscode
description: Erfolgreiche Rückgabe der Benutzerliste
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/User'
        '400':
description: Ungültige Anfrageparameter

components: # Wiederverwendbare Komponenten
schemas: # Datenmodelldefinitionen
    User:
      type: object
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        email:
          type: string
          format: email
      required:
        - id
        - name

Ausführliche Erklärung der OpenAPI-Kernkonzepte

1. Dokument-Metadaten (info)

Der Abschnitt info enthält grundlegende Informationen über die API, wie Titel, Beschreibung, Version usw.:

Beispiel

info:
title: Benutzerverwaltungs-API
description: API zur Verwaltung von Benutzerinformationen im System
  version: 1.0.0
  contact:
name: API-Support-Team
    email: [email protected]
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html

2. Serverinformationen (servers)

Der Abschnitt servers definiert die Liste der verfügbaren API-Server:

Beispiel

servers:
  - url: https://api.example.com/v1
description: Produktionsumgebung
  - url: https://staging-api.example.com/v1
description: Testumgebung

3. Pfade (paths)

Der Abschnitt paths definiert alle Endpunkte der API und die HTTP-Methoden, die sie unterstützen:

Beispiel

paths:
  /users:
    get:
# Benutzerliste abrufen
    post:
# Neuen Benutzer erstellen
  /users/{userId}:
    get:
# Bestimmten Benutzer abrufen
    put:
# Benutzer aktualisieren
    delete:
# Benutzer löschen

4. Operationen (operations)

Jede HTTP-Methode unter einem Pfad definiert eine API-Operation:

Beispiel

paths:
  /users/{userId}:
    get:
summary: Benutzerdetails abrufen
description: Detaillierte Benutzerinformationen anhand der Benutzer-ID abrufen
      operationId: getUserById
      Tags:
        - users
      parameters:
        - name: userId
          in: path
          required: true
description: Benutzer-ID
          schema:
            type: integer
      responses:
        '200':
description: Benutzerinformationen erfolgreich abgerufen
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '404':
description: Benutzer existiert nicht
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

5. Parameter (parameters)

Parameter können an mehreren Stellen definiert werden:

Beispiel

parameters:
  - name: userId
in: path # Pfadparameter
    required: true
    schema:
      type: integer
  - name: filter
in: query # Abfrageparameter
    schema:
      type: string
  - name: X-API-Key
in: header # Header-Parameter
    schema:
      type: string
  - name: trace
in: cookie # Cookie-Parameter
    schema:
      type: string

6. Anfragekörper (requestBody)

Definieren Sie den Anfragekörper für Methoden wie POST, PUT usw.:

Beispiel

requestBody:
description: Benutzerdaten
  required: true
  content:
    application/json:
      schema:
        $ref: '#/components/schemas/User'
    application/x-www-form-urlencoded:
      schema:
        $ref: '#/components/schemas/UserForm'

7. Antworten (responses)

Definieren Sie die möglichen Antworten für jede Operation:

Beispiel

responses:
  '200':
description: Operation erfolgreich
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/SuccessResponse'
  '400':
description: Ungültige Anfrageparameter
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/ErrorResponse'

8. Komponenten (components)

Der Abschnitt components wird verwendet, um Elemente zu speichern, die im gesamten API-Dokument wiederverwendet werden können:

Beispiel

components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        email:
          type: string
          format: email
        roles:
          type: array
          items:
            type: string
            enum: [admin, user, editor]
      required:
        - name
        - E-Mail
   
    Fehler:
      type: object
      properties:
        Code:
          type: integer
        Nachricht:
          type: string
      required:
        - Code
        - Nachricht
 
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
   
    OAuth2:
      type: oauth2
      flows:
        implicit:
          authorizationUrl: https://example.com/oauth/authorize
          scopes:
read: Leseberechtigung
write: Schreibberechtigung

9. Datenmodelle (Schemas)

Definieren Sie die in der API verwendeten Datenstrukturen:

Beispiel

schemas:
  Product:
    type: object
    properties:
      id:
        type: integer
      name:
        type: string
        maxLength: 100
      price:
        type: number
        format: float
        minimum: 0
      category:
        type: string
        enum: [electronics, books, clothing]

10. Sicherheit (security)

Definieren Sie Authentifizierungs- und Autorisierungsmethoden für die API:

Beispiel

security:
  - ApiKeyAuth: []
  - OAuth2: [read, write]

Vollständiges OpenAPI-Dokumentbeispiel erstellen

Nachfolgend finden Sie ein vollständigeres E-Commerce-API-Beispiel:

Beispiel

openapi: 3.1.0
info:
title: E-Commerce-API
description: API zur Verwaltung von Produkten und Bestellungen in einem Online-Shop
  version: 1.0.0
  contact:
name: API-Support-Team
    email: [email protected]
    url: https://api.example.com/support
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT

servers:
  - url: https://api.example.com/v1
description: Produktionsumgebung
  - url: https://dev-api.example.com/v1
description: Entwicklungsumgebung

Tags:
  - name: products
description: Produktbezogene Operationen
  - name: orders
description: Bestellbezogene Operationen
  - name: users
description: Benutzerbezogene Operationen

paths:
  /products:
    get:
summary: Produktliste abrufen
description: Gibt eine Liste aller verfügbaren Produkte mit Unterstützung für Paginierung und Filterung zurück
      operationId: getProducts
      Tags:
        - products
      parameters:
        - name: category
          in: query
description: Nach Produktkategorie filtern
          schema:
            type: string
        - name: page
          in: query
description: Seitennummer
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
description: Anzahl der Elemente pro Seite
          schema:
            type: integer
            default: 20
      responses:
        '200':
description: Produktliste erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: object
                properties:
                  total:
                    type: integer
                  products:
                    type: array
                    items:
                      $ref: '#/components/schemas/Product'
        '400':
description: Parameterfehler
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
   
    post:
summary: Neues Produkt erstellen
description: Informationen zum Erstellen eines neuen Produkts
      operationId: createProduct
      Tags:
        - products
      security:
        - ApiKeyAuth: []
        - OAuth2: [write]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProductCreate'
      responses:
        '201':
description: Produkt erfolgreich erstellt
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Product'
        '400':
description: Ungültige Anfragedaten
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
description: Nicht autorisiert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /products/{productId}:
    get:
summary: Produktdetails abrufen
description: Detaillierte Informationen zu einem bestimmten Produkt anhand der ID abrufen
      operationId: getProductById
      Tags:
        - products
      parameters:
        - name: productId
          in: path
          required: true
description: Produkt-ID
          schema:
            type: integer
      responses:
        '200':
description: Produktinformationen erfolgreich abgerufen
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Product'
        '404':
description: Produkt nicht gefunden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
   
    put:
summary: Produkt aktualisieren
description: Informationen für ein bestimmtes Produkt aktualisieren
      operationId: updateProduct
      Tags:
        - products
      security:
        - ApiKeyAuth: []
        - OAuth2: [write]
      parameters:
        - name: productId
          in: path
          required: true
description: Produkt-ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProductUpdate'
      responses:
        '200':
description: Produkt erfolgreich aktualisiert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Product'
        '400':
description: Ungültige Anfragedaten
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
description: Nicht autorisiert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
description: Produkt nicht gefunden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
   
    delete:
summary: Produkt löschen
description: Ein bestimmtes Produkt löschen
      operationId: deleteProduct
      Tags:
        - products
      security:
        - ApiKeyAuth: []
        - OAuth2: [write]
      parameters:
        - name: productId
          in: path
          required: true
description: Produkt-ID
          schema:
            type: integer
      responses:
        '204':
description: Produkt erfolgreich gelöscht
        '401':
description: Nicht autorisiert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
description: Produkt nicht gefunden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /orders:
    get:
summary: Bestellliste abrufen
description: Gibt eine Liste aller Bestellungen zurück, mit Unterstützung für Paginierung und Filterung
      operationId: getOrders
      Tags:
        - orders
      security:
        - ApiKeyAuth: []
        - OAuth2: [read]
      parameters:
        - name: status
          in: query
description: Nach Bestellstatus filtern
          schema:
            type: string
            enum: [pending, processing, shipped, delivered, cancelled]
        - name: page
          in: query
description: Seitennummer
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
description: Anzahl der Elemente pro Seite
          schema:
            type: integer
            default: 20
      responses:
        '200':
description: Bestellliste erfolgreich abgerufen
          content:
            application/json:
              schema:
                type: object
                properties:
                  total:
                    type: integer
                  orders:
                    type: array
                    items:
                      $ref: '#/components/schemas/Order'
        '401':
description: Nicht autorisiert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
   
    post:
summary: Neue Bestellung erstellen
description: Eine neue Bestellung erstellen
      operationId: createOrder
      Tags:
        - orders
      security:
        - ApiKeyAuth: []
        - OAuth2: [write]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrderCreate'
      responses:
        '201':
description: Bestellung erfolgreich erstellt
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Order'
        '400':
description: Ungültige Anfragedaten
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
description: Nicht autorisiert
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

components:
  schemas:
    Product:
      type: object
      properties:
        id:
          type: integer
          format: int64
          readOnly: true
        name:
          type: string
          maxLength: 100
        description:
          type: string
        price:
          type: number
          format: float
          minimum: 0
        category:
          type: string
          enum: [electronics, books, clothing, food]
        inStock:
          type: boolean
          default: true
        createdAt:
          type: string
          format: date-time
          readOnly: true
        updatedAt:
          type: string
          format: date-time
          readOnly: true
      required:
        - name
        - price
        - category
   
    ProductCreate:
      type: object
      properties:
        name:
          type: string
          maxLength: 100
        description:
          type: string
        price:
          type: number
          format: float
          minimum: 0
        category:
          type: string
          enum: [electronics, books, clothing, food]
        inStock:
          type: boolean
          default: true
      required:
        - name
        - price
        - category
   
    ProductUpdate:
      type: object
      properties:
        name:
          type: string
          maxLength: 100
        description:
          type: string
        price:
          type: number
          format: float
          minimum: 0
        category:
          type: string
          enum: [electronics, books, clothing, food]
        inStock:
          type: boolean
   
    Order:
      type: object
      properties:
        id:
          type: integer
          format: int64
          readOnly: true
        userId:
          type: integer
          format: int64
        items:
          type: array
          items:
            $ref: '#/components/schemas/OrderItem'
        totalAmount:
          type: number
          format: float
          readOnly: true
        status:
          type: string
          enum: [pending, processing, shipped, delivered, cancelled]
          default: pending
        shippingAddress:
          $ref: '#/components/schemas/Address'
        createdAt:
          type: string
          format: date-time
          readOnly: true
        updatedAt:
          type: string
          format: date-time
          readOnly: true
      required:
        - userId
        - items
        - shippingAddress
   
    OrderCreate:
      type: object
      properties:
        userId:
          type: integer
          format: int64
        items:
          type: array
          items:
            $ref: '#/components/schemas/OrderItem'
        shippingAddress:
          $ref: '#/components/schemas/Address'
      required:
        - userId
        - items
        - shippingAddress
   
    OrderItem:
      type: object
      properties:
        productId:
          type: integer
          format: int64
        quantity:
          type: integer
          minimum: 1
          default: 1
        unitPrice:
          type: number
          format: float
          readOnly: true
      required:
        - productId
        - quantity
   
    Address:
      type: object
      properties:
        street:
          type: string
        city:
          type: string
        Status:
          type: string
        zipCode:
          type: string
        country:
          type: string
      required:
        - street
        - city
        - state
        - zipCode
        - country
   
    Fehler:
      type: object
      properties:
        Code:
          type: integer
        Nachricht:
          type: string
      required:
        - Code
        - Nachricht
 
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
   
    OAuth2:
      type: oauth2
      flows:
        implicit:
          authorizationUrl: https://example.com/oauth/authorize
          scopes:
read: Leseberechtigung
write: Schreibberechtigung

security:
  - ApiKeyAuth: []

Grundlegende Syntax der OpenAPI-Spezifikation

Die OpenAPI-Spezifikation unterstützt zwei Formate:

  1. YAML (empfohlen)
  2. JSON

YAML-Formatbeispiel

Beispiel

openapi: 3.0.0
info:
title: Pet Store API
  version: 1.0.0
paths:
  /pets:
    get:
summary: Alle Haustiere auflisten
      responses:
        '200':
description: Haustierliste erfolgreich abgerufen

JSON-Format-Beispiel

Beispiel

"openapi": "3.0.0",
  "info": {
    "title": "Pet Store API",
    "version": "1.0.0"
  },
  "paths": {
    "/pets": {
      "get": {
        "summary": "Alle Haustiere auflisten",
        "responses": {
          "200": {
            "description": "Haustierliste erfolgreich abgerufen"
          }
        }
      }
    }
  }
}

Verwendung der OpenAPI-Spezifikation

1. OpenAPI-Dokumente erstellen und bearbeiten

Sie können die folgenden Tools verwenden, um OpenAPI-Dokumente zu erstellen und zu bearbeiten:

  • Swagger Editor: Online-Editor mit Echtzeitvorschau und -validierung
  • Stoplight Studio: Visuelles API-Design-Tool
  • VS Code + OpenAPI-Plugin: In integrierter Entwicklungsumgebung bearbeiten

2. Dokumentgenerierung

Die OpenAPI-Spezifikation kann automatisch ansprechende API-Dokumentation generieren. Häufig verwendete Tools sind:

  • Swagger UI: Interaktive API-Dokumentation generieren
  • ReDoc: Bietet responsive, anpassbare Dokumentation
  • Slate: Elegante statische Dokumentation generieren

3. Code-Generierung

OpenAPI kann automatisch Client- und Servercode in mehreren Sprachen generieren:

  • OpenAPI Generator: Unterstützt 40+ Programmiersprachen
  • Swagger Codegen: Client- und Servercode generieren
  • NSwag: Codegenerator für das .NET-Ökosystem

4. API-Tests und Mocking

Die OpenAPI-Spezifikation kann auch verwendet werden für:

  • Automatisiertes Testen: Mit Tools wie Postman, SoapUI
  • API-Mocking: Prism, Microcks usw. können APIs basierend auf der OpenAPI-Spezifikation mocken

Best Practices

1. Designprinzipien

  • Endpoint-Benennung konsistent halten
  • Verwenden Sie geeignete HTTP-Methoden und Statuscodes
  • Entwerfen Sie eine klare URL-Pfadstruktur

2. Dokumentationsempfehlungen

  • Detaillierte Beschreibungen und Beispiele bereitstellen
  • Verwenden Sie Tags, um APIs zu gruppieren
  • Erforderliche Parameter klar angeben

3. Versionskontrollstrategie

  • Die Versionsnummer in die URL aufnehmen (/v1/users)
  • Request-Header verwenden, um die Version anzugeben (Accept: application/vnd.example.v1+json)
  • Versionsinformationen im OpenAPI-Dokument klar angeben

Häufig gestellte Fragen

1. Was ist der Unterschied zwischen OpenAPI und Swagger?

Swagger ist der Vorgänger der OpenAPI-Spezifikation. Im Jahr 2016 wurde die Swagger-Spezifikation an die Linux Foundation gespendet und in die OpenAPI-Spezifikation umbenannt. Heute bezieht sich „Swagger“ normalerweise auf das Toolset, das rund um die OpenAPI-Spezifikation entwickelt wurde.

2. Was sind die Hauptunterschiede zwischen OpenAPI 2.0 und 3.x?

OpenAPI 3.x hat viele neue Funktionen eingeführt, darunter:

  • Verbesserte Wiederverwendung von Komponenten
  • Flexiblere Request-Body-Definitionen
  • Leistungsfähigere Sicherheitsdefinitionen
  • Verbesserte Unterstützung für JSON Schema
  • Unterstützung für Links und Callbacks

3. Wie geht man mit Authentifizierung und Autorisierung um?

OpenAPI unterstützt mehrere Sicherheitsmechanismen:

  • API-Schlüssel
  • HTTP-Basisauthentifizierung
  • OAuth2.0
  • OpenID Connect
  • Authentifizierung über benutzerdefinierte Header

Lernressourcen

  1. Offizielle Dokumentation:OpenAPI Initiative
  2. Werkzeuge:
  3. Lernressourcen:
Weitere Erweiterungen