641 lines
17 KiB
Markdown
641 lines
17 KiB
Markdown
# Wegwichtel REST-API
|
||
|
||
Diese Datei dokumentiert die vollständige HTTP-Schnittstelle des Wegwichtel-Servers. Die API-Basis lautet `/api`. Bild- und Audiodateien werden ebenfalls ausschließlich über API-Endpunkte ausgeliefert; die Clientanwendung verwendet dafür keine direkten Speicherpfade.
|
||
|
||
## 1. Grundlagen
|
||
|
||
### Basisadressen
|
||
|
||
Lokaler Standard:
|
||
|
||
```text
|
||
http://127.0.0.1:47145
|
||
```
|
||
|
||
API-Basis:
|
||
|
||
```text
|
||
http://127.0.0.1:47145/api
|
||
```
|
||
|
||
Bei vorgeschaltetem Nginx bleibt der Pfad erhalten, zum Beispiel:
|
||
|
||
```text
|
||
https://wegwichtel.example.org/api
|
||
```
|
||
|
||
### Formate
|
||
|
||
- JSON-Lesezugriffe liefern `application/json`.
|
||
- Bild- und Audio-GETs liefern den jeweiligen binären Medientyp.
|
||
- Schreibzugriffe ohne Datei akzeptieren JSON, URL-encoded Formulare oder `multipart/form-data`.
|
||
- Datei-Uploads verwenden `multipart/form-data`.
|
||
- Pro Medienrequest wird genau eine Datei verarbeitet.
|
||
- Zeitstempel werden als SQLite- beziehungsweise ISO-8601-Text ausgegeben.
|
||
- Die derzeitige API besitzt noch keine Authentifizierung. Schreibzugriffe dürfen nicht ungeschützt öffentlich erreichbar sein.
|
||
|
||
### Uploadgrenzen und unterstützte Dateitypen
|
||
|
||
Das Dateilimit pro Upload wird mit `MAX_UPLOAD_MB` festgelegt und beträgt standardmäßig `50 MB`.
|
||
|
||
| Ressource | Uploadfeld | Dateitypen |
|
||
|---|---|---|
|
||
| GPX | `gpx` | `.gpx`, `application/gpx+xml`, XML |
|
||
| Bild | `picture` | JPEG, PNG, WebP |
|
||
| Audio | `audio` | MP3, MP4/M4A, AAC, Ogg, WAV, WebM |
|
||
|
||
### Fehlerformat
|
||
|
||
```json
|
||
{
|
||
"error": "HttpError",
|
||
"message": "Strecke nicht gefunden."
|
||
}
|
||
```
|
||
|
||
Typische Statuscodes:
|
||
|
||
| Status | Bedeutung |
|
||
|---:|---|
|
||
| `200` | Anfrage erfolgreich |
|
||
| `201` | Ressource wurde angelegt |
|
||
| `400` | Parameter oder Datei fehlt beziehungsweise ist ungültig |
|
||
| `404` | Route, POI oder Medienressource wurde nicht gefunden |
|
||
| `409` | Ressource existiert bereits oder widerspricht dem aktuellen Zustand |
|
||
| `413` | Datei überschreitet `MAX_UPLOAD_MB` |
|
||
| `415` | Dateityp wird nicht unterstützt |
|
||
| `500` | Interner Serverfehler |
|
||
|
||
### IDs und Medienadressierung
|
||
|
||
- `:id` bezeichnet bei `/routes/:id/...` die Route.
|
||
- `:pictureId` bezeichnet ein einzelnes Bild aus `poi_images`.
|
||
- `poiId` bezeichnet einen POI innerhalb einer Route.
|
||
- Ein POI kann mehrere Bilder, aber höchstens eine Audiodatei besitzen.
|
||
- Bilder erhalten deshalb eine eigene Pfad-ID.
|
||
- Audio verwendet keinen zusätzlichen Pfadabschnitt; der POI wird über `poiId` angegeben.
|
||
|
||
Beispiele verwenden Route `1`, POI `7` und Bild `15`.
|
||
|
||
## 2. Datenmodelle
|
||
|
||
### Route
|
||
|
||
```json
|
||
{
|
||
"id": 1,
|
||
"slug": "schulwald-runde",
|
||
"name": "Schulwald-Runde",
|
||
"description": "Naturkundlicher Rundweg",
|
||
"schoolName": "Beispielschule",
|
||
"status": "active",
|
||
"start": { "lat": 52.5208, "lon": 13.407 },
|
||
"center": { "lat": 52.521, "lon": 13.408 },
|
||
"bounds": {
|
||
"minLat": 52.5208,
|
||
"minLon": 13.407,
|
||
"maxLat": 52.5212,
|
||
"maxLon": 13.409
|
||
},
|
||
"distanceM": 842.6,
|
||
"elevationGainM": 14.2,
|
||
"pointCount": 87,
|
||
"gpxUrl": "/media/routes/1/route.gpx",
|
||
"createdAt": "2026-06-16 12:00:00",
|
||
"updatedAt": "2026-06-16 12:00:00",
|
||
"deletedAt": null
|
||
}
|
||
```
|
||
|
||
### POI
|
||
|
||
```json
|
||
{
|
||
"id": 7,
|
||
"routeId": 1,
|
||
"title": "Die alte Eiche",
|
||
"description": "Hier wird das Alter der Eiche erklärt.",
|
||
"lat": 52.5208,
|
||
"lon": 13.407,
|
||
"triggerRadiusM": 60,
|
||
"sequence": 2,
|
||
"audioUrl": "/api/routes/1/audio?poiId=7",
|
||
"images": [
|
||
{
|
||
"id": 15,
|
||
"caption": "Blick auf die Baumkrone",
|
||
"sequence": 0,
|
||
"url": "/api/routes/1/pictures/15"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### Bildmetadaten
|
||
|
||
```json
|
||
{
|
||
"id": 15,
|
||
"routeId": 1,
|
||
"poiId": 7,
|
||
"poiTitle": "Die alte Eiche",
|
||
"caption": "Blick auf die Baumkrone",
|
||
"sequence": 0,
|
||
"url": "/api/routes/1/pictures/15",
|
||
"createdAt": "2026-06-16 12:30:00"
|
||
}
|
||
```
|
||
|
||
### Audiometadaten
|
||
|
||
```json
|
||
{
|
||
"routeId": 1,
|
||
"poiId": 7,
|
||
"poiTitle": "Die alte Eiche",
|
||
"url": "/api/routes/1/audio?poiId=7",
|
||
"updatedAt": "2026-06-16 12:35:00"
|
||
}
|
||
```
|
||
|
||
## 3. Endpunktübersicht
|
||
|
||
| Methode | Pfad | Zweck |
|
||
|---|---|---|
|
||
| `GET` | `/api/health` | Server- und SQLite-Zustand |
|
||
| `GET` | `/api/routes` | Routen auflisten |
|
||
| `GET` | `/api/routes/:id` | Route mit Punkten und POIs lesen |
|
||
| `POST` | `/api/routes` | Route anlegen |
|
||
| `PUT` | `/api/routes/:id` | Route aktualisieren |
|
||
| `POST` | `/api/routes/:id/append` | GPX-Punkte anhängen |
|
||
| `DELETE` | `/api/routes/:id` | Route weich löschen |
|
||
| `POST` | `/api/routes/:id/restore` | Route wiederherstellen |
|
||
| `GET` | `/api/routes/:id/pois` | POIs einer Route auflisten |
|
||
| `GET` | `/api/pois/:id` | einzelnen POI lesen |
|
||
| `POST` | `/api/routes/:id/pois` | POI anlegen |
|
||
| `PUT` | `/api/pois/:id` | POI aktualisieren |
|
||
| `GET` | `/api/routes/:id/pictures` | Bildmetadaten auflisten |
|
||
| `GET` | `/api/routes/:id/pictures/:pictureId` | Bilddatei ausliefern |
|
||
| `POST` | `/api/routes/:id/pictures` | Bild anlegen |
|
||
| `PUT` | `/api/routes/:id/pictures/:pictureId` | Bilddatei oder Metadaten aktualisieren |
|
||
| `DELETE` | `/api/routes/:id/pictures/:pictureId` | Bild löschen |
|
||
| `GET` | `/api/routes/:id/audio` | Audio auflisten oder für einen POI ausliefern |
|
||
| `POST` | `/api/routes/:id/audio` | Audio für einen POI anlegen |
|
||
| `PUT` | `/api/routes/:id/audio` | Audio eines POIs ersetzen |
|
||
| `DELETE` | `/api/routes/:id/audio` | Audio eines POIs löschen |
|
||
|
||
## 4. Systemzustand
|
||
|
||
### GET /api/health
|
||
|
||
Parameter: keine.
|
||
|
||
```bash
|
||
curl http://127.0.0.1:47145/api/health
|
||
```
|
||
|
||
Beispielantwort:
|
||
|
||
```json
|
||
{
|
||
"ok": true,
|
||
"service": "wegwichtel",
|
||
"socket": "127.0.0.1:47145",
|
||
"sqliteVersion": "3.46.1",
|
||
"timestamp": "2026-06-16T12:00:00.000Z"
|
||
}
|
||
```
|
||
|
||
## 5. Routen
|
||
|
||
### GET /api/routes
|
||
|
||
Listet aktive Routen auf. Werden `lat` und `lon` gemeinsam angegeben, berechnet der Server die Entfernung zum Routenstart, filtert mit `radiusKm` und sortiert nach Entfernung.
|
||
|
||
Query-Parameter:
|
||
|
||
| Parameter | Typ | Pflicht | Standard | Beschreibung |
|
||
|---|---|---:|---|---|
|
||
| `lat` | Dezimalzahl | nein | – | Breitengrad des Ausgangspunkts |
|
||
| `lon` | Dezimalzahl | nein | – | Längengrad des Ausgangspunkts |
|
||
| `radiusKm` | Dezimalzahl | nein | `DEFAULT_ROUTE_RADIUS_KM` | maximaler Abstand zum Routenstart |
|
||
| `includeDeleted` | `true`/`false` | nein | `false` | gelöschte Routen einschließen |
|
||
|
||
Alle aktiven Routen:
|
||
|
||
```bash
|
||
curl http://127.0.0.1:47145/api/routes
|
||
```
|
||
|
||
Mit allen Query-Parametern:
|
||
|
||
```bash
|
||
curl --get http://127.0.0.1:47145/api/routes \
|
||
--data-urlencode 'lat=52.5208' \
|
||
--data-urlencode 'lon=13.4070' \
|
||
--data-urlencode 'radiusKm=12.5' \
|
||
--data-urlencode 'includeDeleted=true'
|
||
```
|
||
|
||
### GET /api/routes/:id
|
||
|
||
Pfadparameter:
|
||
|
||
| Parameter | Typ | Pflicht | Beschreibung |
|
||
|---|---|---:|---|
|
||
| `id` | positive Ganzzahl | ja | Route |
|
||
|
||
Query-Parameter:
|
||
|
||
| Parameter | Typ | Pflicht | Standard | Beschreibung |
|
||
|---|---|---:|---|---|
|
||
| `includeDeleted` | `true`/`false` | nein | `false` | auch eine weich gelöschte Route lesen |
|
||
|
||
```bash
|
||
curl http://127.0.0.1:47145/api/routes/1
|
||
```
|
||
|
||
Die Antwort enthält `points`, `pois`, `images[].url` und `audioUrl`. Die Medien-URLs zeigen auf die API-Endpunkte.
|
||
|
||
### POST /api/routes
|
||
|
||
Content-Type: `multipart/form-data`.
|
||
|
||
| Feld | Typ | Pflicht | Beschreibung |
|
||
|---|---|---:|---|
|
||
| `gpx` | Datei | ja | GPX-Datei |
|
||
| `name` | Text | nein, wenn GPX einen Namen enthält | Anzeigename |
|
||
| `slug` | Text | nein | gewünschter URL-tauglicher Bezeichner |
|
||
| `description` | Text | nein | Beschreibung |
|
||
| `schoolName` | Text | nein | Schule oder Projekt |
|
||
|
||
```bash
|
||
curl -X POST http://127.0.0.1:47145/api/routes \
|
||
-F 'name=Schulwald-Runde' \
|
||
-F 'slug=schulwald-runde' \
|
||
-F 'description=Naturkundlicher Rundweg' \
|
||
-F 'schoolName=Beispielschule' \
|
||
-F 'gpx=@route.gpx;type=application/gpx+xml'
|
||
```
|
||
|
||
### PUT /api/routes/:id
|
||
|
||
Aktualisiert Routendaten. Eine neue GPX-Datei ersetzt die gespeicherten Trackpunkte.
|
||
|
||
| Feld | Typ | Pflicht | Beschreibung |
|
||
|---|---|---:|---|
|
||
| `name` | Text | nein | neuer Name |
|
||
| `description` | Text | nein | neue Beschreibung |
|
||
| `schoolName` | Text | nein | neue Schule |
|
||
| `gpx` | Datei | nein | vollständige Ersatzstrecke |
|
||
|
||
```bash
|
||
curl -X PUT http://127.0.0.1:47145/api/routes/1 \
|
||
-F 'name=Schulwald-Runde 2026' \
|
||
-F 'description=Überarbeitete Route' \
|
||
-F 'schoolName=Beispielschule' \
|
||
-F 'gpx=@route-neu.gpx;type=application/gpx+xml'
|
||
```
|
||
|
||
### POST /api/routes/:id/append
|
||
|
||
Hängt GPX-Punkte an eine Route an.
|
||
|
||
| Feld | Typ | Pflicht | Beschreibung |
|
||
|---|---|---:|---|
|
||
| `gpx` | Datei | ja | GPX-Datei mit zusätzlichen Punkten |
|
||
|
||
```bash
|
||
curl -X POST http://127.0.0.1:47145/api/routes/1/append \
|
||
-F 'gpx=@erweiterung.gpx;type=application/gpx+xml'
|
||
```
|
||
|
||
### DELETE /api/routes/:id
|
||
|
||
Markiert die Route als gelöscht und verschiebt GPX, Bilder und Audio in den Papierkorb.
|
||
|
||
```bash
|
||
curl -X DELETE http://127.0.0.1:47145/api/routes/1
|
||
```
|
||
|
||
### POST /api/routes/:id/restore
|
||
|
||
Stellt eine weich gelöschte Route einschließlich ihrer Dateien wieder her.
|
||
|
||
```bash
|
||
curl -X POST http://127.0.0.1:47145/api/routes/1/restore
|
||
```
|
||
|
||
## 6. POIs
|
||
|
||
### GET /api/routes/:id/pois
|
||
|
||
```bash
|
||
curl http://127.0.0.1:47145/api/routes/1/pois
|
||
```
|
||
|
||
### GET /api/pois/:id
|
||
|
||
```bash
|
||
curl http://127.0.0.1:47145/api/pois/7
|
||
```
|
||
|
||
### POST /api/routes/:id/pois
|
||
|
||
Akzeptiert JSON, URL-encoded Formulare oder Multipart ohne Mediendateien.
|
||
|
||
| Feld | Typ | Pflicht | Standard | Beschreibung |
|
||
|---|---|---:|---|---|
|
||
| `title` | Text | nein | `Unbenannter POI` | Titel |
|
||
| `description` | Text | nein | leer | Beschreibung |
|
||
| `lat` | Dezimalzahl | ja | – | Breitengrad |
|
||
| `lon` | Dezimalzahl | ja | – | Längengrad |
|
||
| `triggerRadiusM` | Dezimalzahl | nein | `DEFAULT_POI_TRIGGER_METERS` | Aktivierungsradius in Metern |
|
||
| `sequence` | Ganzzahl ≥ 0 | nein | `0` | Reihenfolge |
|
||
|
||
```bash
|
||
curl -X POST http://127.0.0.1:47145/api/routes/1/pois \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{
|
||
"title": "Die alte Eiche",
|
||
"description": "Informationen zur Baumart",
|
||
"lat": 52.5208,
|
||
"lon": 13.4070,
|
||
"triggerRadiusM": 60,
|
||
"sequence": 2
|
||
}'
|
||
```
|
||
|
||
### PUT /api/pois/:id
|
||
|
||
Alle Felder sind optional; nicht angegebene Werte bleiben erhalten.
|
||
|
||
```bash
|
||
curl -X PUT http://127.0.0.1:47145/api/pois/7 \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{
|
||
"title": "Die sehr alte Eiche",
|
||
"description": "Aktualisierte Beschreibung",
|
||
"lat": 52.5209,
|
||
"lon": 13.4071,
|
||
"triggerRadiusM": 45,
|
||
"sequence": 1
|
||
}'
|
||
```
|
||
|
||
## 7. Bilder
|
||
|
||
Ein POI kann mehrere Bilder besitzen. Die Collection wird über die Route adressiert; jedes Bild hat zusätzlich eine `pictureId`.
|
||
|
||
### GET /api/routes/:id/pictures
|
||
|
||
Liefert Bildmetadaten als JSON.
|
||
|
||
Query-Parameter:
|
||
|
||
| Parameter | Typ | Pflicht | Beschreibung |
|
||
|---|---|---:|---|
|
||
| `poiId` | positive Ganzzahl | nein | auf Bilder eines POIs einschränken |
|
||
|
||
Alle Bilder der Route:
|
||
|
||
```bash
|
||
curl http://127.0.0.1:47145/api/routes/1/pictures
|
||
```
|
||
|
||
Nur Bilder von POI 7:
|
||
|
||
```bash
|
||
curl --get http://127.0.0.1:47145/api/routes/1/pictures \
|
||
--data-urlencode 'poiId=7'
|
||
```
|
||
|
||
Beispielantwort:
|
||
|
||
```json
|
||
{
|
||
"pictures": [
|
||
{
|
||
"id": 15,
|
||
"routeId": 1,
|
||
"poiId": 7,
|
||
"poiTitle": "Die alte Eiche",
|
||
"caption": "Blick auf die Baumkrone",
|
||
"sequence": 0,
|
||
"url": "/api/routes/1/pictures/15",
|
||
"createdAt": "2026-06-16 12:30:00"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### GET /api/routes/:id/pictures/:pictureId
|
||
|
||
Liefert die Bilddatei binär mit dem passenden `Content-Type`, beispielsweise `image/jpeg`, `image/png` oder `image/webp`.
|
||
|
||
```bash
|
||
curl http://127.0.0.1:47145/api/routes/1/pictures/15 \
|
||
--output bild-15.jpg
|
||
```
|
||
|
||
Bildmetadaten werden über `GET /api/routes/:id/pictures` gelesen.
|
||
|
||
### POST /api/routes/:id/pictures
|
||
|
||
Content-Type: `multipart/form-data`.
|
||
|
||
| Feld | Typ | Pflicht | Standard | Beschreibung |
|
||
|---|---|---:|---|---|
|
||
| `picture` | Datei | ja | – | Bilddatei |
|
||
| `poiId` | positive Ganzzahl | ja | – | zugehöriger POI |
|
||
| `caption` | Text | nein | leer | sichtbare Bildbeschreibung und Alternativtext |
|
||
| `sequence` | Ganzzahl ≥ 0 | nein | nächste freie Position | Reihenfolge in der Diashow |
|
||
|
||
```bash
|
||
curl -X POST http://127.0.0.1:47145/api/routes/1/pictures \
|
||
-F 'poiId=7' \
|
||
-F 'caption=Blick auf die Baumkrone' \
|
||
-F 'sequence=0' \
|
||
-F 'picture=@eiche.jpg;type=image/jpeg'
|
||
```
|
||
|
||
Die Antwort enthält Metadaten. Der `Location`-Header zeigt auf `/api/routes/1/pictures/:pictureId`.
|
||
|
||
### PUT /api/routes/:id/pictures/:pictureId
|
||
|
||
Aktualisiert Metadaten und optional die Datei. Der Request kann JSON ohne Datei oder Multipart mit Datei verwenden.
|
||
|
||
| Feld | Typ | Pflicht | Beschreibung |
|
||
|---|---|---:|---|
|
||
| `picture` | Datei | nein | Ersatzdatei |
|
||
| `poiId` | positive Ganzzahl | nein | Bild einem anderen POI derselben Route zuordnen |
|
||
| `caption` | Text | nein | Bildbeschreibung |
|
||
| `sequence` | Ganzzahl ≥ 0 | nein | Reihenfolge |
|
||
|
||
Nur Metadaten ändern:
|
||
|
||
```bash
|
||
curl -X PUT http://127.0.0.1:47145/api/routes/1/pictures/15 \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{
|
||
"poiId": 7,
|
||
"caption": "Nahaufnahme der Eichenblätter",
|
||
"sequence": 1
|
||
}'
|
||
```
|
||
|
||
Datei und Metadaten ersetzen:
|
||
|
||
```bash
|
||
curl -X PUT http://127.0.0.1:47145/api/routes/1/pictures/15 \
|
||
-F 'poiId=7' \
|
||
-F 'caption=Neue Bildbeschreibung' \
|
||
-F 'sequence=1' \
|
||
-F 'picture=@eiche-neu.webp;type=image/webp'
|
||
```
|
||
|
||
### DELETE /api/routes/:id/pictures/:pictureId
|
||
|
||
Löscht den Datenbankeintrag und die einzelne Bilddatei.
|
||
|
||
```bash
|
||
curl -X DELETE http://127.0.0.1:47145/api/routes/1/pictures/15
|
||
```
|
||
|
||
## 8. Audio
|
||
|
||
Pro POI existiert höchstens eine Audiodatei. Deshalb gibt es keine zusätzliche Audio-ID und keinen Pfad wie `/audio/:poiId`. Alle Operationen verwenden `/api/routes/:id/audio`; der konkrete POI wird mit `poiId` angegeben.
|
||
|
||
### GET /api/routes/:id/audio
|
||
|
||
Ohne `poiId` liefert der Endpunkt alle Audiometadaten der Route als JSON:
|
||
|
||
```bash
|
||
curl http://127.0.0.1:47145/api/routes/1/audio
|
||
```
|
||
|
||
Beispielantwort:
|
||
|
||
```json
|
||
{
|
||
"audio": [
|
||
{
|
||
"routeId": 1,
|
||
"poiId": 7,
|
||
"poiTitle": "Die alte Eiche",
|
||
"url": "/api/routes/1/audio?poiId=7",
|
||
"updatedAt": "2026-06-16 12:35:00"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
Mit `poiId` liefert derselbe Endpunkt die Audiodatei binär:
|
||
|
||
| Query-Parameter | Typ | Pflicht für Dateiausgabe | Beschreibung |
|
||
|---|---|---:|---|
|
||
| `poiId` | positive Ganzzahl | ja | POI, dessen Audio geliefert wird |
|
||
|
||
```bash
|
||
curl --get http://127.0.0.1:47145/api/routes/1/audio \
|
||
--data-urlencode 'poiId=7' \
|
||
--output ansage.mp3
|
||
```
|
||
|
||
Der Response-`Content-Type` entspricht dem gespeicherten Format, beispielsweise `audio/mpeg` oder `audio/ogg`.
|
||
|
||
### POST /api/routes/:id/audio
|
||
|
||
Legt die Audiodatei für einen POI an. Besteht bereits eine Datei, antwortet der Server mit `409`; zum Ersetzen wird `PUT` verwendet.
|
||
|
||
| Feld | Typ | Pflicht | Beschreibung |
|
||
|---|---|---:|---|
|
||
| `audio` | Datei | ja | Audiodatei |
|
||
| `poiId` | positive Ganzzahl | ja | zugehöriger POI |
|
||
|
||
```bash
|
||
curl -X POST http://127.0.0.1:47145/api/routes/1/audio \
|
||
-F 'poiId=7' \
|
||
-F 'audio=@ansage.mp3;type=audio/mpeg'
|
||
```
|
||
|
||
Der `Location`-Header lautet beispielsweise:
|
||
|
||
```text
|
||
/api/routes/1/audio?poiId=7
|
||
```
|
||
|
||
### PUT /api/routes/:id/audio
|
||
|
||
Ersetzt eine vorhandene Audiodatei. `poiId` darf als Query-Parameter oder als Multipart-Feld angegeben werden.
|
||
|
||
Query-Variante:
|
||
|
||
```bash
|
||
curl -X PUT 'http://127.0.0.1:47145/api/routes/1/audio?poiId=7' \
|
||
-F 'audio=@ansage-neu.ogg;type=audio/ogg'
|
||
```
|
||
|
||
Multipart-Variante:
|
||
|
||
```bash
|
||
curl -X PUT http://127.0.0.1:47145/api/routes/1/audio \
|
||
-F 'poiId=7' \
|
||
-F 'audio=@ansage-neu.ogg;type=audio/ogg'
|
||
```
|
||
|
||
| Parameter | Ort | Typ | Pflicht | Beschreibung |
|
||
|---|---|---|---:|---|
|
||
| `poiId` | Query oder Formular | positive Ganzzahl | ja | POI |
|
||
| `audio` | Formular | Datei | ja | Ersatzdatei |
|
||
|
||
### DELETE /api/routes/:id/audio
|
||
|
||
Löscht die Audiodatei des angegebenen POIs und setzt `audioUrl` anschließend auf `null`.
|
||
|
||
Empfohlen als Query-Parameter:
|
||
|
||
```bash
|
||
curl -X DELETE 'http://127.0.0.1:47145/api/routes/1/audio?poiId=7'
|
||
```
|
||
|
||
Alternativ als JSON-Body:
|
||
|
||
```bash
|
||
curl -X DELETE http://127.0.0.1:47145/api/routes/1/audio \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{ "poiId": 7 }'
|
||
```
|
||
|
||
## 9. Verwendung durch die Clientanwendung
|
||
|
||
Die Clientanwendung konstruiert Medienadressen ausschließlich über das API-Modul:
|
||
|
||
```javascript
|
||
Wegwichtel.Api.pictureUrl(routeId, pictureId);
|
||
// /api/routes/1/pictures/15
|
||
|
||
Wegwichtel.Api.audioUrl(routeId, poiId);
|
||
// /api/routes/1/audio?poiId=7
|
||
```
|
||
|
||
Die Diashow setzt die API-Bildadresse als `src` des Bildes. Der HTML5-Audioplayer setzt die API-Audioadresse als `src` und lädt sie mit `preload="auto"`. Das Erreichen eines POIs startet keine automatische Wiedergabe.
|
||
|
||
## 10. Nginx-Hinweis
|
||
|
||
Nginx sollte `/api/` vollständig an den Node.js-Prozess weiterleiten. Da Bilder und Audio über `/api` ausgeliefert werden, muss der Proxy binäre Responses unverändert durchreichen:
|
||
|
||
```nginx
|
||
location ^~ /api/ {
|
||
proxy_pass http://127.0.0.1:47145;
|
||
proxy_http_version 1.1;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
proxy_read_timeout 120s;
|
||
}
|
||
```
|
||
|
||
Für Uploads muss außerdem `client_max_body_size` mindestens so groß wie `MAX_UPLOAD_MB` gewählt werden.
|