Undokumentierte Rails-APIs kosten Teams Stunden pro Woche: Slack-Fragen, fehlerhafte Integrationen, mühsames Onboarding. OpenAPI liefert eine maschinenlesbare Spezifikation, aus der sich interaktive Dokumentation, Client-SDKs und Mock-Server generieren lassen.

Dieser Leitfaden behandelt die zwei wichtigsten Rails-Tools für OpenAPI-Dokumentation, ihre Praxis-Trade-offs und das CI-Setup, das Spec-Drift verhindert.

Warum die meisten Rails-API-Docs veralten

Das Problem ist nicht die Generierung der Dokumentation. Das Problem ist, sie nach dem initialen Setup aktuell zu halten. Entwickler fügen Parameter hinzu, ändern Response-Strukturen und vergessen, die Spec neu zu generieren. Nach wenigen Wochen beschreibt die OpenAPI-Datei eine API, die so nicht mehr existiert.

Die Lösung: Dokumentationsgenerierung an die Test-Suite und CI-Pipeline koppeln, sodass veraltete Specs den Build brechen.

Rails 7 #131 API-Dokumentation mit OpenAPI, Swagger, RSWAG. Manifest mit ChatGPT generieren?!

RSwag: Testgetriebene OpenAPI-Specs

RSwag (aktuell v2.16.0, Stand März 2026) integriert sich direkt in RSpec. Jeder Request-Spec dokumentiert gleichzeitig den Endpunkt und verifiziert, dass die API sich wie beschrieben verhält.

Installation (ca. 15 Minuten)

# Gemfile
group :development, :test do
  gem 'rswag', '~> 2.16'
  gem 'rspec-rails', '~> 7.1'
end
bundle install
rails generate rswag:install

Der Generator erstellt spec/swagger_helper.rb mit globalen Einstellungen (API-Version, Basis-URL, Auth-Schema).

Einen Endpunkt dokumentieren und testen

# spec/requests/api/v1/orders_spec.rb
require 'swagger_helper'

RSpec.describe 'Orders API', type: :request do
  path '/api/v1/orders' do
    get 'Bestellungen auflisten' do
      tags 'Orders'
      produces 'application/json'
      parameter name: :page, in: :query, type: :integer, required: false
      parameter name: :per_page, in: :query, type: :integer, required: false

      response '200', 'Bestellungen gefunden' do
        schema type: :array, items: {
          type: :object,
          properties: {
            id: { type: :integer },
            total_cents: { type: :integer, example: 12550 },
            currency: { type: :string, example: 'CHF' },
            status: { type: :string, enum: %w[pending confirmed shipped] },
            created_at: { type: :string, format: 'date-time' }
          },
          required: %w[id total_cents currency status created_at]
        }

        let(:page) { 1 }
        let(:per_page) { 25 }
        run_test!
      end

      response '401', 'nicht autorisiert' do
        run_test!
      end
    end
  end
end

Die run_test!-Methode ist der entscheidende Punkt: Sie führt den tatsächlichen HTTP-Request aus und validiert die Antwort gegen das definierte Schema. Stimmt die Antwort nicht überein, schlägt der Test fehl.

rake rswag:specs:swaggerize
# Generiert swagger/v1/swagger.yaml

USEO’s Take: RSwag in der Praxis

Wir setzen RSwag seit über 4 Jahren in Kundenprojekten ein. Es funktioniert zuverlässig, hat aber reale Wartungskosten:

  • Schema-Duplikation: Dasselbe Response-Schema wird in jedem Spec wiederholt. Bei 50+ Endpunkten wird das unübersichtlich. Lösung: Shared Examples und $ref-Schemas in swagger_helper.rb definieren.
  • Spec-Dateigrösse: RSwag-Specs werden schnell 200+ Zeilen lang. Anders als normale Request-Specs enthalten sie viel Schema-Boilerplate. Das senkt die Bereitschaft, sie zu pflegen.
  • Fehlende Response-Body-Validierung: run_test! prüft nur den Status-Code und die Schema-Struktur, nicht den konkreten Inhalt. Ein Endpunkt kann “200 OK” mit leerer Liste zurückgeben und der Test besteht trotzdem.
  • Upgrade-Aufwand: Der Wechsel von RSwag 2.x Swagger-2.0-Output zu OpenAPI 3.0 erforderte in einem Projekt ca. 3 Tage Migrationsarbeit.

Trotzdem: Für Teams, die bereits RSpec nutzen, ist RSwag der pragmatischste Weg zu aktueller API-Dokumentation.

OasRails: Annotation-basierte Alternative

OasRails (v0.14.0+) generiert OpenAPI-3.1-Spezifikationen direkt aus YARD-Kommentaren in Controllern. Kein separater Generierungsschritt nötig.

Installation (ca. 10 Minuten)

# Gemfile
gem 'oas_rails', '~> 0.14'
bundle install
# config/routes.rb
Rails.application.routes.draw do
  mount OasRails::Engine => '/docs' if Rails.env.development?
end

Endpunkt annotieren

class Api::V1::OrdersController < ApplicationController
  # @summary Bestellungen auflisten
  # @description Paginierte Liste aller Bestellungen
  # @parameter page [Integer] Seitennummer (query)
  # @parameter per_page [Integer] Einträge pro Seite (query)
  # @response 200 [Array<Order>] Bestellliste
  # @response 401 Nicht autorisiert
  def index
    @orders = Order.page(params[:page]).per(params[:per_page])
    render json: @orders
  end
end

Dokumentation sofort verfügbar unter http://localhost:3000/docs.

USEO’s Take: OasRails-Erfahrung

OasRails ist attraktiv, weil die Dokumentation direkt beim Code lebt. Aber in der Praxis sehen wir folgende Probleme:

  • Kommentare veralten still: Im Gegensatz zu RSwag gibt es keinen automatischen Test, der fehlschlägt, wenn die Kommentare nicht zum Code passen. Ein Entwickler ändert die Response-Struktur, vergisst den YARD-Kommentar, und niemand merkt es.
  • Keine Testabdeckung: Die Dokumentation wird generiert, aber nie validiert. Man hat eine schön aussehende Spec, die möglicherweise falsch ist.
  • Junges Projekt: OasRails hat weniger Community-Support als RSwag. Bei Problemen findet man weniger Lösungen auf Stack Overflow oder GitHub Issues.
  • Gut für interne APIs: Wenn die Dokumentation primär für das eigene Team ist und nicht für externe Konsumenten, kann der geringere Overhead sinnvoll sein.

RSwag vs OasRails: Direktvergleich

KriteriumRSwagOasRails
OpenAPI-Version3.0 (OAS 3.1 experimentell)3.1 nativ
DokumentationsquelleRSpec Request-SpecsYARD-Kommentare
ValidierungAutomatisch via TestsKeine (nur Generierung)
Setup-Zeit~15 Min~10 Min
WartungsaufwandMittel (Schema-Boilerplate)Niedrig (aber ohne Sicherheitsnetz)
CI-IntegrationNatürlich (Teil der Test-Suite)Erfordert separaten Check
Empfohlen fürExterne APIs, regulierte UmgebungenInterne APIs, Prototypen

CI-Pipeline: Spec-Drift verhindern

Der grösste Fehler, den wir bei Kunden sehen: RSwag wird installiert, die initiale Spec generiert, und dann nie wieder aktualisiert. Nach 3 Monaten ist die Dokumentation Fiktion.

GitHub Actions Workflow

name: API Docs
on: [push, pull_request]

jobs:
  verify-api-docs:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_PASSWORD: postgres
        ports: ['5432:5432']
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    steps:
      - uses: actions/checkout@v4
      - uses: ruby/setup-ruby@v1
        with:
          bundler-cache: true
      - name: Setup DB
        run: bundle exec rails db:test:prepare
      - name: Generate OpenAPI spec
        run: bundle exec rake rswag:specs:swaggerize
      - name: Fail if spec changed
        run: |
          git diff --exit-code swagger/
          echo "OpenAPI spec is up to date"

Der entscheidende Schritt ist git diff --exit-code swagger/. Wenn ein Entwickler einen Endpunkt ändert, den RSwag-Spec aktualisiert, aber vergisst, die YAML-Datei neu zu generieren und einzuchecken, schlägt der Build fehl.

Alternative: Spec in CI generieren und als Artefakt speichern

Für Teams, die die generierte Spec nicht im Repository haben wollen:

      - name: Upload spec
        uses: actions/upload-artifact@v4
        with:
          name: openapi-spec
          path: swagger/v1/swagger.yaml

Code-First vs. Design-First: Wann welcher Ansatz?

Die meisten Rails-Teams fahren mit Code-First besser. Der Grund: Rails-Projekte entwickeln sich iterativ. Endpunkte entstehen, ändern sich, werden deprecated. Eine vorab geschriebene Spezifikation ist nach dem zweiten Sprint oft veraltet.

Design-First lohnt sich bei:

  • Öffentlichen APIs mit externen Konsumenten
  • Stark regulierten Umgebungen (z.B. Finanzbranche in der Schweiz)
  • Projekten, in denen Frontend- und Backend-Teams parallel entwickeln

Code-First ist pragmatischer bei:

  • Internen APIs
  • MVPs und Prototypen
  • Teams, die bereits umfangreiche RSpec-Suites haben

In der Praxis kombinieren viele Teams beide Ansätze: Design-First für die initiale API-Planung, dann Code-First (RSwag) für die laufende Wartung.

Interaktive Dokumentation bereitstellen

Wenn die OpenAPI-Spec generiert ist, brauchen Konsumenten eine lesbare Oberfläche.

Swagger UI (klassisch):

# Gemfile
gem 'rswag-ui'

Wird von RSwag automatisch unter /api-docs gemountet.

RapiDoc (modern, bessere Mobile-Ansicht): OasRails liefert RapiDoc standardmässig unter /docs aus.

Redoc (beste Lesbarkeit für externe Dokumentation): Kann als statische HTML-Seite generiert werden:

npx @redocly/cli build-docs swagger/v1/swagger.yaml -o public/api-docs.html

SDK-Generierung und Mock-Server

Aus einer validen OpenAPI-Spec lassen sich Client-SDKs automatisch generieren:

# TypeScript-Client generieren
npx @openapitools/openapi-generator-cli generate \
  -i swagger/v1/swagger.yaml \
  -g typescript-fetch \
  -o generated/ts-client

Mock-Server für parallele Frontend-Entwicklung:

npx @stoplight/prism-cli mock swagger/v1/swagger.yaml
# Mock-API verfügbar auf http://127.0.0.1:4010

Das Frontend-Team kann sofort gegen realistische API-Antworten entwickeln, bevor das Backend fertig ist.

Zusammenfassung

SchrittToolZeitaufwand
OpenAPI-Spec generierenRSwag oder OasRails15-30 Min Setup
CI-Enforcement einrichtenGitHub Actions10 Min
Interaktive Docs bereitstellenSwagger UI / RapiDoc5 Min
SDK generierenOpenAPI Generator5 Min
Mock-Server aufsetzenPrism5 Min

Die wichtigste Erkenntnis: Das Generieren der initialen Spec ist trivial. Die eigentliche Arbeit ist, sie über Monate und Jahre aktuell zu halten. Ohne CI-Enforcement wird jede API-Dokumentation irgendwann zur Lüge.

RSwag mit CI-Integration ist der zuverlässigste Ansatz für Rails-Teams, die ihre API-Dokumentation ernst nehmen.

FAQs

Was ist der Unterschied zwischen Code-First und Design-First?

Code-First bedeutet: API implementieren, Tests schreiben, Dokumentation aus dem Code generieren. Der Vorteil ist, dass die Docs immer das tatsächliche Verhalten widerspiegeln. Der Nachteil: Kein vorab definierter API-Vertrag.

Design-First bedeutet: Zuerst die OpenAPI-Spec schreiben, dann implementieren. Gut für externe APIs und parallele Entwicklung, aber die Spec muss manuell synchron gehalten werden.

Wie verhindere ich, dass die Dokumentation veraltet?

Drei Massnahmen:

  1. RSwag-Tests in CI: Jeder Build generiert die Spec neu und prüft auf Diff
  2. PR-Reviews: OpenAPI-Änderungen als Teil des Code-Reviews behandeln
  3. Swagger UI im Staging: Team und Stakeholder sehen immer den aktuellen Stand

Brauche ich RSwag, wenn ich bereits Request-Specs habe?

Ja, weil Standard-Request-Specs keine OpenAPI-Spec generieren. RSwag erweitert die RSpec-DSL um Schema-Definitionen, die dann in eine valide OpenAPI-YAML-Datei umgewandelt werden. Der Migrationsaufwand bestehender Specs liegt bei ca. 30-60 Minuten pro Controller.

Ähnliche Blog-Beiträge

Verwandte Artikel