Directus ist eine Open-Source-Datenplattform, die die Datenverwaltung und den Datenzugang vereinfacht. Sie ermöglicht es Teams, unabhängig von ihren technischen Kenntnissen, mühelos mit Datenbanken und digitalen Datenbeständen zu arbeiten. Mit Directus können Sie eine Verbindung zu Ihrer SQL-Datenbank herstellen und CRUD-Operationen, Benutzerverwaltung, komplexe Abfragen, Webhooks und Automatisierung durchführen. Es bietet eine flexible und erweiterbare Architektur, die REST- und GraphQL-APIs, CLI-Tools und ein JavaScript-SDK unterstützt. Directus fördert die Kontrolle durch die Entwickler, die Skalierbarkeit und die Anpassungsoptionen und eignet sich daher für Headless CMS, Backend-as-a-Service, Datenmanagement und Analyseprojekte. Es handelt sich um eine datenorientierte Lösung ohne Herstellerbindung und mit umfassender Dokumentation.
Im Kontext der Mobilitätslösung dient Directus als Backend-as-a-Service bzw. Headless CMS. Es bildet die zentrale Datenhaltung des Systems, gepaart mit dem nativen Dirctus-CMS Frontend, dar. Um die Funktionalitäten für Mobility-Lösung abzubilden, wurde Directus mittels Extensions in seinem Fuktionsumfang erweitert. Dazu gehören Extensions der folgenden Kategorien:
- Endpunkte
- sog. Hooks
- Module
- Views
Die entwickelten Extensions befinden sich im Ordner code
- code - dieser Ordner enthält die Extensions in JavaScript/TypeScript.
- extensions - hier erwarter Directus die kompilierten Extensions.
- http - Dieser Ordner enthält .http-Dateien, die für manuelle API-Tests genutzt werden können.
- permissions - Die Konfiguration der Berechtigungen der einzelnen Tabellen im fertigen Directus-System werden hier gepflegt.
- postman - Dieser Ordner enthält .json-Dateien, die mittels Import in Postman für manuelle API-Tests genutzt werden können.
- scripts - Dieser Ordner enthält Installations und Build-Skripte.
- uploads - Dieser Ordner enthält das Datenmodell (Tabellen), die in Directus für das lauffähige System nötig sind.
Für das Projekt existieren zwei Docker Container.
- Directus-Bootstrap
- Directus-Extensions
Dieser Container wird lediglich für das initiale Aufsetzen der Datenbank (Anwendung von sog. Datenbank-Migrationen) benötigt. Grund für eine Aufteilung in einen eigenen Container ist die Unabhängigkeit von den Extensions, die teilweise zur Startzeit bereits auf bestehende Datenstrukturen zugreifen müssen. Sind diese noch nicht vorhanden, laufen sie in Fehler. So ist der Installationsprozess in zwei Docker Container unterteilt.
Dieser Container enthält alle benötigten, "compilierten" Extensions, die für die Abbildung der Funktionalität des Mobilitätssystems benötigt werden. Dazu gehören:
Name | Typ | Beschreibung |
---|---|---|
custom-endpoints | Endpoint | Zusätzliche Endpunkte für REST-API. Z.b. Abfrage von OperatingTimes für Zeitraum X bis Y |
mphooks | Hooks | Aktionen, die bei Veränderung von Daten in Tabellen automatisch ausgelöst werden. Bsp.: Bus-Position wird aktualisiert und mit dem Routing synchronisiert (mittels RabbitMQ) |
routing-hooks | Hooks | Eigene Extension für die Herstellung der Kommunikation mit dem Routing - Abbildung aller Events zwischen Routing/Directus |
system-push-endpoint | Endpoint | Zusätzliche Endpunkte, um Push-Benachrichtigungen an Nutzer/Fahrer zu senden. Sucht nach Tokens der jeweiligen Nutzer einer Gruppe und sendet Text an FCM-Service |
system-push-module | Module | Einbindbares Modul in die Directus-Oberfläche, um Funktionalität für System-Push-Benachrichtigungen visuell abzubilden |
Um Directus lokal einrichten zu können, sind folgende Dinge zu tun
- Bauen der Extensions
- Grundkonfiguration von Zugangsdaten, API-Keys, ...
- Hochfahren der Docker container (zunächst Bootstrap, danach Extensions)
Die Extensions liegen in Form von JavaScript bzw. TypeScript im Ordner code vor.
Um die Extensions bauen und für Directus nutzbar machen zu können, müssen zunächst die Build-Tools installiert werden. Dies geschieht mittels des Skriptes npm_install.sh. Es navigiert automatisiert in alle Extension-Ordner und installiert die erforderlichen Build-Tools mittels
npm install
.
Im Ordner scripts befinden sich sowohl Build-Skripte für die einzelnen Extensions, als auch ein Build-Skript, das alle Extensions nacheinander baut.
Die fertigen Extensions werden automatisiert in den Ordner extensions kopiert.
Dies geschieht mittels der beiden Befehle
docker build -t directus-bootstrap -f Dockerfile.bootstrap
docker build -t directus-extensions -f Dockerfile.extensions
Zunächst wird die Datenbank aus docker-compose mittels docker-compose -f docker-compose.yml up -d "db"
hochgefahren. Ist diese vollständig hochgefahren, kann Directus
in der Bootstrap-Version hochgefahren werden. Innerhalb des Containers muss nun der Datenbank-Snapshot angewandt werden. Dieser enthält das komplette Datenmodell, auf dem das System aufbaut. Für die Anwendung des Snapshot dient das Skript schema_apply.sh, das innerhalb des gestarteten Containers ausgeführt werden muss.
Ist die Anwendung des Snapshots abgeschlossen, kann Directus-Bootstrap gegen Directus-Extensions ausgetauscht werden.
Daraufhin kann das komplette docker-compose mittels docker-compose -f docker-compose.yml up -d
hochgefahren werden. Dies schließt einen RabbitMQ-Broker sowie weitere Komponenten wie Redis etc. mit ein.
Folgende Environment-Variablen können bzw. müssen für Directus gesetzt werden
DB_CLIENT: "pg"
DB_HOST: "postgis"
DB_PORT: "5432"
DB_DATABASE: "directus"
DB_USER: "directus"
DB_PASSWORD: "directus"
CACHE_ENABLED: "false"
CACHE_STORE: "redis"
CACHE_REDIS: "redis://redis:6379"
CACHE_AUTO_PURGE: "true"
ADMIN_EMAIL: "${DIRECTUS_ADMIN_EMAIL}"
ADMIN_PASSWORD: "${DIRECTUS_ADMIN_PASSWORD}"
TELEMETRY: "false"
AUTH_PROVIDERS: "aws"
AUTH_AWS_DRIVER: "openid"
AUTH_AWS_CLIENT_ID: "${AWS_COGNITO_CLIENT_ID}"
AUTH_AWS_CLIENT_SECRET: "${AWS_COGNITO_CLIENT_SECRET}"
AUTH_AWS_SCOPE: "${AWS_COGNITO_SCOPE}"
AUTH_AWS_ISSUER_URL: "{AWS_ISSUER_URL}"
AUTH_AWS_ICON: "aws"
AUTH_AWS_ALLOW_PUBLIC_REGISTRATION: "true"
AUTH_AWS_IDENTIFIER_KEY: "email"
AUTH_AWS_DEFAULT_ROLE_ID: ""
CUSTOM_AUTH_DEFAULT_ROLE_ID: ""
CUSTOM_AUTH_POOL_ID: ""
# Einstellungg für die Busfahrer
CUSTOM_AUTH_DRIVER_CLIENT_ID: ""
CUSTOM_AUTH_USER_CLIENT_ID: ""
CUSTOM_AUTH_DEFAULT_ROLE_DRIVER_ID: ""
# SEND_FCM = Steuerungsvariable für den Versand von PushBenachrichtigungen
SEND_FCM: "true"
PUBLIC_URL: "http://localhost:8055"
RABBITMQ_DEFAULT_USER: "guest"
RABBITMQ_DEFAULT_PASS: "guest"
RABBITMQ_DEFAULT_VHOST: "/"
RABBIT_IP: "rabbitmq"
Die Directus-API wird durch die entwickelten Extensions um folgende Endpunkte erweitert (s. all.http)
GET
{{BASE_URL}}/customendpoints/operatingtime/{communityId}/{isoFromDateTime}/{isoToDateTime}
Name Type Data Type Description communityId required string ID of the community isoFromDateTime required string Start date and time in ISO 8601 format isoToDateTime required string End date and time in ISO 8601 format
[
{
"busId": 11,
"communityId": 1,
"name": "ErzMobil",
"seats": 6,
"seatsWheelchair": 1,
"seatsBlockedPerWheelchair": 2,
"availabilitySlots": [],
"blockingSlots": []
}
]
GET
/customendpoints/operatingtime/{communityId}/{isoFromDateTime}/{isoToDateTime}
Name Type Data Type Description communityId required string ID of the community isoFromDateTime required string Start date and time in ISO 8601 format isoToDateTime required string End date and time in ISO 8601 format
[
{
"busId": 11,
"communityId": 1,
"name": "ErzMobil",
"seats": 6,
"seatsWheelchair": 1,
"seatsBlockedPerWheelchair": 2,
"availabilitySlots": [
{
"startDate": "2023-07-12T06:00:00+00:00",
"endDate": "2023-07-12T08:00:00+00:00"
}
],
"blockingSlots": []
}
]
GET
/customendpoints/roadclosures/{communityId}/{isoFromDateTime}/{isoToDateTime}
Name Type Data Type Description communityId required string ID of the community isoFromDateTime required string Start date and time in ISO 8601 format isoToDateTime required string End date and time in ISO 8601 format
HTTP Code Content-Type Response 200 application/json;charset=UTF-8
Road closures
GET
/routes/:routeId/phoneNumbers
Name Type Data Type Description routeId required string ID of the specific route
HTTP Code Content-Type Response 200 application/json;charset=UTF-8
Phone numbers
GET
/customendpoints/canbook
No parameters required.
HTTP Code | Content-Type | Response |
---|---|---|
200 | text/plain;charset=UTF-8 |
false |
200 | text/plain;charset=UTF-8 |
true |
POST
/token
No request body required.
HTTP Code Content-Type Response 200 text/plain;charset=UTF-8
Token added
DELETE
/token/:token
Name Type Data Type Description token required string FCM token to be deleted
HTTP Code Content-Type Response 200 text/plain;charset=UTF-8
Token deleted
POST
/stops/nearest
{
"lat": "12.2",
"lng": "13.3",
"r": "500",
"n": 1
}
Name | Type | Data Type | Description |
---|---|---|---|
lat | required | string | Latitude of the location |
lng | required | string | Longitude of the location |
r | required | string | Radius in meters |
n | optional | number | Number of stops to retrieve |
HTTP Code | Content-Type | Response |
---|---|---|
200 | application/json;charset=UTF-8 |
Nearest stop data |
GET
/users/me
(returns clients userId in directus)
name type data type description Authorization required Headers Authorizationtoken provided by /auth/login from Directus
http code content-type response 200
text/plain;charset=UTF-8
true
/false
GET
/customendpoints/cognito
(returns cognito configuration)
http code content-type response 200
text/plain;charset=UTF-8
"userPoolId": "eu-central-1_tdwybtbCf","userClientId": "6ocqpe3d13dtpa0j72a30nkdek","driverClientId":"252a9fstcdet8l180mu4d5329a"
GET
/items/tickettype
(returns items from tickettype-collection)
http code content-type response 200
application/json;charset=UTF-8
{"data": [{"Name": "Schnell zum Arzt-Ticket"},{"Name": "Feierabendsause"},{"Name": "Schüler ABC"}]}
GET
/items/NewBackendAvailability
(returns toggle value for directus availability)
http code content-type response 200
text/plain;charset=UTF-8
true
/false
POST
/awsmw/auth
(login mechanism which exchanges a cognito token against a directus token)
name type data type description IdToken required JSON Body RefreshToken required JSON Body clientId required JSON Body
http code content-type response 200
application/json;charset=UTF-8
{"accessToken": "...", "expires": 2022-05-02T15:08:22.499Z, "refreshToken": "..."}
GET
/items/stop
(returns stops (haltestellen) configured in directus)
http code content-type response 200
application/json;charset=UTF-8
{ "data": [{"id":5,"name":"Test","location":{"coordinates":[13.326656180707829,52.51944337812006],"type": "Point"},"communityId": 2}]}
GET
/items/stop
(returns stops (haltestellen) configured in directus)
http code content-type response 200
application/json;charset=UTF-8
{ "data": [{"id":5,"name":"Test","location":{"coordinates":[13.326656180707829,52.51944337812006],"type": "Point"},"communityId": 2}]}
GET
/items/token/{token}
(returns token)
http code content-type response 200
application/json;charset=UTF-8
{"fcmToken":"kwjfalkjbafkjbflkjb", "isDriver": true}
POST
/items/token
POST a new token for FCM-Notifications
name type data type description fcmToken required JSON Body
http code content-type response 200
application/json;charset=UTF-8
{"fcmToken":"kwjfalkjbafkjbflkjb"}
POST
/items/token
POST a new token for FCM-Notifications
name type data type description fcmToken required JSON Body
http code content-type response 200
application/json;charset=UTF-8
{"fcmToken":"kwjfalkjbafkjbflkjb", "isDriver": true}