Skip to content

feat: Content Negotiation vervollständigen — Turtle für alle Endpunkte + Accept-Header (v2.35.0) - #88

Merged
daimpad merged 1 commit into
mainfrom
claude/fix-data-prep-errors-kJYpl
Jul 31, 2026
Merged

feat: Content Negotiation vervollständigen — Turtle für alle Endpunkte + Accept-Header (v2.35.0)#88
daimpad merged 1 commit into
mainfrom
claude/fix-data-prep-errors-kJYpl

Conversation

@daimpad

@daimpad daimpad commented Jul 31, 2026

Copy link
Copy Markdown
Owner

Schließt den letzten offenen Punkt der Harvest-Unterstützung. Bisher konnte nur der Katalog Turtle liefern, und die Serialisierung ließ sich ausschließlich über ?format= wählen.

1 · Turtle für alle Endpunkte

/datasets/<id> und /delta liefern jetzt ebenfalls text/turtle. Ein RDF-Harvester muss die Serialisierung damit nicht mehr je Route wechseln.

Der Delta-Body ist bereits ein vollständiges JSON-LD-Dokument (@context, @type: odw:DeltaCatalog, dcat:dataset, odw:removed) — er lässt sich also ohne Sonderbehandlung als Graph serialisieren.

2 · Auswertung des Accept-Headers

Fehlt ?format=, entscheidet der Header:

Accept Ergebnis
text/turtle, application/x-turtle Turtle
application/ld+json JSON-LD
application/json JSON
*/*, unbekannt, leer JSON-LD (DCAT-AP-Standardfall)
  • q-Werte nach RFC 9110 werden berücksichtigt: application/ld+json;q=0.5, text/turtle;q=0.9 → Turtle
  • Gleichstand → Reihenfolge des Clients entscheidet
  • q=0 schließt einen Typ explizit aus
  • Ein browsertypischer Header (text/html,…,*/*;q=0.8) landet korrekt bei JSON-LD

Ein explizites ?format= hat immer Vorrang vor dem Header — die URL bleibt eindeutig und kopierbar. Der Alias ttl wird weiterhin normalisiert.

3 · Vary: Accept

Alle Antworten tragen jetzt Vary: Accept, damit zwischengeschaltete Caches (CDN, Reverse Proxy) kein Turtle-Dokument an einen JSON-LD-Client ausliefern. Ohne diesen Header wäre die Aushandlung in Verbindung mit Caching schlicht falsch.

Technisch

Vier gemeinsame Helfer — resolve_format(), negotiate_accept(), serialize_document(), document_response(). Alle drei Endpunkte nutzen damit denselben Pfad für Aushandlung, Serialisierung und Turtle-Caching; letzteres gab es zuvor nur im Katalog. Die Format-Argumente der Routen sind vereinheitlicht, ein leerer Default bedeutet „nicht angegeben" und aktiviert die Header-Aushandlung.

Tests / Qualität

  • Sieben neue Tests: Media-Type-Zuordnung, q-Werte, Gleichstand, q=0, Fallbacks (inkl. browsertypischem Header), Vorrang von ?format=, Turtle-Ausgabe eines Einzeldatensatzes samt Vary: Accept.
  • WP_REST_Request-Stub um get_header()/set_header() ergänzt, damit Tests dieselben Zugriffsmethoden nutzen wie der Produktivcode.
  • Gegenprobe: Ein Einzeldatensatz als Turtle ergibt valides RDF (60 Triples, per rdflib geprüft).
  • 197 Tests grün, PHPCS 0 (mit CI-Version 3.4.1 verifiziert), PHPStan Level 6 clean.

Doku

README, API.md und CLAUDE.md beschreiben die Aushandlung; die Roadmap führt den Punkt als erledigt. Offen bleibt nur noch RDF/XML als weitere Serialisierung — Turtle und JSON-LD decken die gängigen Harvester ab.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JB1xUQM892bVZ4Yv3MZjvq


Generated by Claude Code

… (v2.35.0)

Turtle konnte bisher nur der Katalog liefern, und die Serialisierung liess
sich ausschliesslich ueber ?format= waehlen.

- /datasets/<id> und /delta liefern jetzt ebenfalls text/turtle. Ein
  RDF-Harvester muss die Serialisierung nicht mehr je Route wechseln.
- Fehlt ?format=, entscheidet der Accept-Header: text/turtle (inkl. der
  Alt-Bezeichnung application/x-turtle), application/ld+json und
  application/json. q-Werte nach RFC 9110 werden beruecksichtigt, bei
  Gleichstand gilt die Client-Reihenfolge, q=0 schliesst einen Typ aus.
  Wildcards, unbekannte Typen und ein leerer Header fallen auf JSON-LD
  zurueck (DCAT-AP-Standardfall).
- Vary: Accept auf allen Antworten, damit Caches kein Turtle-Dokument an
  einen JSON-LD-Client ausliefern.

Ein explizites ?format= hat weiterhin Vorrang vor dem Header — die URL
bleibt eindeutig und kopierbar.

Technisch: gemeinsame Helfer resolve_format/negotiate_accept/
serialize_document/document_response; alle drei Endpunkte nutzen denselben
Pfad fuer Aushandlung, Serialisierung und Turtle-Caching (bisher nur Katalog).

Tests: 7 neue (Media-Types, q-Werte, Gleichstand, q=0, Fallbacks, Vorrang
von ?format=, Turtle je Datensatz inkl. Vary). WP_REST_Request-Stub um
get_header/set_header ergaenzt. 197 gruen, PHPCS 0, PHPStan clean.
Gegenprobe: Einzeldatensatz als Turtle ist valides RDF (rdflib).

https://claude.ai/code/session_01JB1xUQM892bVZ4Yv3MZjvq

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JB1xUQM892bVZ4Yv3MZjvq
@daimpad
daimpad merged commit 7caa7c2 into main Jul 31, 2026
10 checks passed
@daimpad
daimpad deleted the claude/fix-data-prep-errors-kJYpl branch July 31, 2026 16:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants