Skip to content

Caddy JSON Schema support#280

Open
samwillis wants to merge 2 commits into
cursor/json-mode-schema-validation-fc1dfrom
cursor/caddy-json-schema-support-60a6
Open

Caddy JSON Schema support#280
samwillis wants to merge 2 commits into
cursor/json-mode-schema-validation-fc1dfrom
cursor/caddy-json-schema-support-60a6

Conversation

@samwillis
Copy link
Copy Markdown
Contributor

@samwillis samwillis commented Mar 9, 2026

This PR adds protocol-aligned JSON Schema support to the Caddy server plugin for application/json streams.

Summary

The Caddy plugin now supports optional schema-attached JSON streams with:

  • inline schema creation
  • schema URL creation
  • schema-aware append validation
  • schema metadata exposure via HEAD
  • schema retrieval via GET ?schema

Behavior now matches the RFC/protocol expectations and the existing conformance coverage.

What changed

1) Schema-aware stream creation (PUT)

Implemented both JSON schema attachment modes:

  • Inline schema mode

    • Content-Type: application/schema+json
    • Stream-Content-Type: application/json
    • request body is treated as schema document (not initial data)
  • Schema URL mode

    • Content-Type: application/json
    • Stream-Schema-Url: <absolute http/https URL>
    • schema URL is resolved once at create-time, then pinned

Validation/normalization rules now enforced on create:

  • missing $schema defaults to draft 2020-12
  • unsupported schema dialect is rejected (400)
  • invalid schema document is rejected (400)
  • schemas requiring external $ref resolution are rejected (400)
  • invalid/non-absolute/non-http(s) schema URLs are rejected (400)
  • conflicting schema modes are rejected (400)
  • schema attachment on non-JSON streams is rejected (400)

2) Schema identity in idempotent PUT

Added schema metadata to stream config and idempotency checks:

  • schema_digest
  • pinned effective schema_document
  • optional schema_source_url

PUT idempotency now includes schema identity:

  • matching config (including schema digest) => 200
  • mismatched schema config => 409

3) Schema-aware JSON validation on write path

For JSON streams with attached schema:

  • initial JSON data (URL mode create with body) is validated
  • all subsequent POST appends are validated
  • mixed JSON batches are validated atomically (no partial acceptance)
  • schema validation failures return 422 Unprocessable Content
  • malformed JSON still returns 400 (as before)

4) Schema metadata and retrieval endpoints

Implemented protocol metadata exposure:

  • HEAD now includes, when schema-attached:
    • Stream-Schema-Digest
    • Link: <absolute-url?schema>; rel="describedby"; type="application/schema+json"
    • Stream-Schema-Url (when created from URL mode)

Implemented schema retrieval:

  • GET {stream-url}?schema returns pinned effective schema:
    • 200
    • Content-Type: application/schema+json
    • Stream-Schema-Digest
  • returns 404 when stream exists but has no schema
  • rejects combinations with offset, live, or cursor (400)

5) Store + persistence updates

Extended both memory and file-backed stores (including bbolt metadata serialization) to persist schema fields and support runtime schema validator caching/lookup.

6) Header/CORS updates

Added new schema headers to CORS allow/expose lists:

  • Stream-Content-Type
  • Stream-Schema-Url
  • Stream-Schema-Digest
  • Link (exposed)

7) Additional protocol compatibility fix

Included Stream-Next-Offset on 409 responses for append-to-closed-stream to satisfy conformance expectations.

Validation

Ran the Caddy plugin test/conformance flow after implementation:

  • go test ./... (packages/caddy-plugin) ✅
  • pnpm conformance (packages/caddy-plugin) ✅
    • 254 / 254 tests passing, including JSON Schema conformance scenarios

Open in Web Open in Cursor 

@cursor
Copy link
Copy Markdown

cursor Bot commented Mar 9, 2026

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Mar 9, 2026

Open in StackBlitz

@durable-streams/benchmarks

npm i https://pkg.pr.new/@durable-streams/benchmarks@280

@durable-streams/cli

npm i https://pkg.pr.new/@durable-streams/cli@280

@durable-streams/client

npm i https://pkg.pr.new/@durable-streams/client@280

@durable-streams/client-conformance-tests

npm i https://pkg.pr.new/@durable-streams/client-conformance-tests@280

@durable-streams/proxy

npm i https://pkg.pr.new/@durable-streams/proxy@280

@durable-streams/server

npm i https://pkg.pr.new/@durable-streams/server@280

@durable-streams/server-conformance-tests

npm i https://pkg.pr.new/@durable-streams/server-conformance-tests@280

@durable-streams/state

npm i https://pkg.pr.new/@durable-streams/state@280

@durable-streams/y-durable-streams

npm i https://pkg.pr.new/@durable-streams/y-durable-streams@280

commit: 424a384

@samwillis samwillis marked this pull request as ready for review March 9, 2026 17:27
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