miroir/docs/notes/api-compatibility.md
jedarden 409f952f59 Add repo hygiene: LICENSE, CHANGELOG, .gitignore
- LICENSE: MIT (per plan §12)
- CHANGELOG.md: Keep a Changelog 1.1.0 skeleton with [Unreleased]
  and [0.1.0] sections matching the awk extractor from plan §7
- .gitignore: Rust target/, editor junk; Cargo.lock kept in VCS

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-18 20:47:36 -04:00

3.1 KiB

API Compatibility

Goal

Miroir must be a drop-in replacement for a single Meilisearch instance. A client configured to talk to a Meilisearch host should work identically when pointed at Miroir instead — no SDK changes, no query changes, no schema changes.

What This Means

  • Miroir exposes the Meilisearch REST API verbatim on its inbound interface
  • All request and response shapes, status codes, error formats, and headers must match the Meilisearch spec exactly
  • The X-Meili-API-Key / Authorization header must be accepted and forwarded (or validated at the orchestrator boundary)
  • Async task responses (taskUid, GET /tasks/{uid}) must work — the orchestrator must track and reconcile task states across nodes

The Core Value Proposition

A single Meilisearch instance is limited by the RAM of one server. Miroir removes that ceiling:

  • The logical index can be arbitrarily large — sharded across N nodes, each holding a fraction
  • Replication factor is tunable: RF=1 for maximum capacity, RF=2+ for resilience and read throughput
  • Adding nodes expands capacity; removing nodes contracts it — the rebalancer handles redistribution
  • From the client's perspective, none of this is visible

API Surface Categories

Pass-through (broadcast to all nodes):

  • Index create/update/delete
  • Settings (ranking rules, synonyms, stop words, filterable/sortable attributes, etc.)
  • Index stats (GET /indexes/{uid}/stats) — aggregate across nodes

Shard-routed writes:

  • POST /indexes/{uid}/documents — route each document by hash(primary key) to RF nodes
  • PUT /indexes/{uid}/documents — same
  • DELETE /indexes/{uid}/documents/{id} — route to owning shard's RF nodes
  • DELETE /indexes/{uid}/documents by filter — must broadcast to all nodes

Scatter-gather reads:

  • POST /indexes/{uid}/search — fan out to one replica per shard, merge results
  • GET /indexes/{uid}/documents — fan out, merge, paginate globally
  • GET /indexes/{uid}/documents/{id} — route to any replica of owning shard

Orchestrator-local:

  • GET /health — orchestrator health (not proxied)
  • GET /version — return Meilisearch version of the backing nodes
  • GET /tasks, GET /tasks/{uid} — orchestrator maintains a unified task registry

Task ID Reconciliation

Meilisearch returns a taskUid for every write operation. Nodes have independent task ID sequences. Miroir must:

  1. Issue writes to RF nodes
  2. Collect the per-node taskUid for each operation
  3. Generate a Miroir task ID that maps to the set of per-node task IDs
  4. Return the Miroir task ID to the client
  5. When polled (GET /tasks/{uid}), aggregate node task statuses — report succeeded only when all RF nodes report succeeded

Non-Goals

  • Miroir does not expose any Miroir-specific management API on the Meilisearch port — topology management (add/remove nodes, rebalance) is handled out-of-band via config or a separate admin interface
  • Miroir does not need to implement Meilisearch's tenant tokens or fine-grained key management — it can forward the master key to nodes and let them validate