ADR 0008 — OpenCollection native format
Context
Section titled “Context”Every API client locks you into its own format. Postman’s is locked, Insomnia’s is locked, Bruno’s is its own dialect. Switching tools means a lossy migration each time, which is a real reason teams stay on tools they’ve outgrown. Restura needs a canonical on-disk representation for collections that survives round-trips, is vendor-neutral so users can leave, and covers the request-shaped protocols Restura supports — not just HTTP. We also need the in-memory TypeScript types to stay in lock-step with the schema; hand-maintaining types alongside a JSON Schema drifts immediately.
Decision
Section titled “Decision”Adopt OpenCollection as Restura’s native read/write format, implemented in src/lib/opencollection/. Two on-disk layouts are supported: a single bundled JSON document and a directory layout (fs-reader.ts / fs-writer.ts).
- The spec’s TypeScript types (
spec-types.ts) are generated from the vendored JSON Schema, not hand-written.npm run gen:opencollection-typesregenerates them andnpm run verify:opencollection-typesis a CI gate that fails the build if the committed types drift. - Protocols map as follows: HTTP, GraphQL (an HTTP item with a
graphqlbody), gRPC, and WebSocket are first-class OpenCollection items. Socket.IO, SSE, and MCP ride along inextensionsasx-restura-socketio/x-restura-sse/x-restura-mcp, preserved verbatim across import/export. - Connection-based protocols (Kafka, MQTT) have no per-request shape, so they are deliberately not represented in a collection.
to-internal.ts/from-internal.tsconvert between the OpenCollection document and Restura’s internal model. An_ocbag preserves original fields the internal model can’t represent, so a round-trip is lossless even for features Restura doesn’t surface in its UI.
Consequences
Section titled “Consequences”Positive
- Users can move in and out of Restura without losing fidelity; the same files drive the desktop app, the web app, and
@restura/cli. - The codegen gate guarantees the runtime types never silently diverge from the published schema.
- Vendor extensions give Restura room to represent its own protocols without forking the spec.
Negative
- Two layouts (bundled + directory) double the reader/writer surface and its tests.
- The
_ocpreservation bag adds complexity to the converters — the price of lossless round-trips. - Kafka/MQTT can’t be saved to a collection, which can surprise users who expect “everything” to persist.
References
Section titled “References”- Source:
docs/adr/0008-opencollection-native-format.md - User guide: OpenCollection.
- Related: ADR 0005, ADR 0007.