Skip to content

RNV API

I767513 edited this page May 10, 2026 · 2 revisions

RNV GraphQL API

Die App kommuniziert direkt mit der öffentlichen GraphQL-API des RNV – kein Proxy-Server, keine Zwischenspeicherung durch uns.


Inhaltsverzeichnis

  1. Endpunkt & Übersicht
  2. Authentifizierung
  3. Queries
  4. Datenmodelle
  5. Fehlerbehandlung
  6. Apollo Code Generation
  7. Offizielle Ressourcen

1. Endpunkt & Übersicht

https://graphql-sandbox-dds.rnv-online.de/
Protokoll GraphQL über HTTPS
Authentifizierung Bearer Token (Azure AD)
Client Apollo iOS 2.0.4
Konfiguration AppConfiguration.swiftapiEndpoint

Der Endpunkt ist öffentlich zugänglich – für den Zugriff wird jedoch ein gültiger Bearer Token benötigt, der über Azure AD ausgestellt wird.


2. Authentifizierung

Die API verwendet Azure AD – Client Credentials Flow. Der AuthService verwaltet das Token-Lifecycle vollautomatisch.

Ablauf

App-Start / Token abgelaufen
          │
          ▼
    AuthService.fetchToken()
          │
          ▼
  POST /oauth2/v2.0/token
  client_id=...
  client_secret=...
  grant_type=client_credentials
          │
          ▼
    Bearer Token (TTL ~60 Min.)
    ← in-memory gecacht ─────────────────────────┐
          │                                        │
          ▼                                        │
  GraphQL-Request                          Token-Refresh
  Authorization: Bearer <token>            (automatisch)

Credential-Speicherung

Credentials werden niemals im Klartext gespeichert:

Secrets.xcconfig (Build-Zeit)
        │
        ▼
AppConfiguration.swift (Laufzeit)
        │
        ▼
SecureConfigurationManager (verschlüsselt in UserDefaults)
        │
        ▼
AuthService (Token in-memory, nie persistiert)

3. Queries

3.1 Haltestellensuche

Sucht Haltestellen anhand eines Freitexts oder GPS-Koordinaten (als formatierter String).

query SearchStops($input: String!) {
  stopFinder(input: $input) {
    stops {
      hafasID
      globalID
      longName
      shortName
      coord {
        lat
        lon
      }
    }
  }
}

Parameter:

Parameter Typ Beispiel
input String "Paradeplatz" oder "49.4878,8.4660"

Verwendung in der App: StationPickerViewGraphQLService.searchStations()


3.2 Verbindungssuche

Sucht Verbindungen zwischen zwei Haltestellen ab einem bestimmten Zeitpunkt.

query GetTrips(
  $originId: String!,
  $destinationId: String!,
  $time: String!,
  $arrivalOrDeparture: ArrivalOrDeparture
) {
  trip(
    originId: $originId
    destinationId: $destinationId
    time: $time
    arrivalOrDeparture: $arrivalOrDeparture
  ) {
    interchanges
    duration
    legs {
      mode
      line {
        name
        number
        type
      }
      origin {
        name
        departureTime
        delay
        platform
      }
      destination {
        name
        arrivalTime
        delay
      }
      intermediateStops {
        name
        arrivalTime
        departureTime
        coord { lat lon }
      }
      occupancy
      realtime
    }
  }
}

Verwendung in der App: ConnectionsViewGraphQLService.fetchConnections()


3.3 Abfahrtstafel

Alle Abfahrten einer Haltestelle in Echtzeit.

query GetDepartures($stopId: String!, $time: String!, $limit: Int) {
  departureMonitor(
    stopId: $stopId
    time: $time
    limit: $limit
  ) {
    departures {
      line {
        name
        number
        mode
      }
      destination {
        name
      }
      departureTime
      delay
      platform
      realtime
      occupancy
    }
  }
}

Parameter:

Parameter Typ Standard
stopId String
time String Jetzt (ISO 8601)
limit Int 20

Verwendung in der App: DepartureBoardViewGraphQLService.fetchDepartures()


4. Datenmodelle

Station

struct Station: Codable, Identifiable {
    let hafasID: String      // z. B. "de:08222:2521"
    let globalID: String     // Interne RNV-ID
    let longName: String     // "Mannheim Paradeplatz"
    let shortName: String?
    let coord: Coordinate?
}

TripLeg

struct TripLeg: Codable {
    let mode: TransportMode        // .tram, .bus, .suburban
    let line: Line
    let origin: Stop
    let destination: Stop
    let intermediateStops: [IntermediateStop]
    let occupancy: OccupancyLevel
    let realtime: Bool
}

OccupancyLevel

enum OccupancyLevel: String, Codable {
    case unknown   = "UNKNOWN"
    case low       = "LOW"
    case medium    = "MEDIUM"
    case high      = "HIGH"
    case veryHigh  = "VERY_HIGH"
    case full      = "FULL"
}

5. Fehlerbehandlung

Fehler Ursache Behandlung
401 Unauthorized Token abgelaufen oder falsche Credentials AuthService holt neuen Token, ein Retry
Network unavailable Kein Internet NetworkMonitor zeigt Offline-Hinweis
Empty result Keine Verbindungen / Abfahrten Leerer State in der View
Timeout API antwortet zu langsam Konfigurierbar in AppConfiguration.requestTimeout

6. Apollo Code Generation

Die Typsicherheit der API-Responses wird durch Apollo iOS Code Generation sichergestellt. Aus den .graphql-Dateien werden Swift-Typen generiert.

Nach Änderungen an GraphQL-Queries:

# Apollo CLI installieren (einmalig)
brew install apollo-ios-cli

# Code neu generieren
cd RNV-Transport-App
apollo-ios-cli generate

Die generierten Dateien liegen in RNV-Transport-App/GraphQL/Generated/ und werden nicht manuell bearbeitet.


7. Offizielle Ressourcen

Ressource Link
RNV Open Data Portal opendata.rnv-online.de
GraphQL Sandbox Explorer graphql-sandbox-dds.rnv-online.de
Apollo iOS Dokumentation apollographql.com/docs/ios

Clone this wiki locally