Hosting on Plug
Arc.Plug serves the Arc HTTP contract from any Plug pipeline. That is what lets the existing frontend packages, and any HTTP client, talk to an Elixir backend.
defmodule Counters.Router do @moduledoc """ A plain Plug pipeline: no Phoenix. Arc answers its own routes and passes everything else on. """
use Plug.Router
plug Arc.Plug, application: Counters.Arc plug :match plug :dispatch
get "/health", do: send_resp(conn, 200, "ok") match _, do: send_resp(conn, 404, "not found")endArc answers a request only when it is an Arc route. Everything else passes through untouched, so the plug can sit in front of the rest of your application. Start it under Bandit with {Bandit, plug: Counters.Router, port: 4001}; the sample’s application module shows the supervision tree.
Routes
Section titled “Routes”| Route | Method | What it does |
|---|---|---|
| a command route | POST |
Executes the command; JSON body; returns the command result envelope |
<command route>/validate |
POST |
Authorization and validation only |
| a query route | GET |
Arguments in the query string |
| a query route | QUERY |
Arguments, paging and sorting in a JSON body; responses carry Cache-Control: no-store |
| an observable query route | GET |
Snapshot, or Server-Sent Events with Accept: text/event-stream, or a WebSocket upgrade |
/.cratis/queries/ws |
WebSocket | The multiplexed observable-query hub |
/.cratis/commands, /.cratis/queries |
GET |
Operation catalogs; see discovery routes |
/.cratis/me |
GET |
The caller’s identity; served only when an identity provider exists. Private: Cache-Control: no-store, private |
/.cratis/identity-details/schema |
GET |
The JSON schema of the identity details type; {} without a typed provider |
/.cratis/users, /.cratis/tenants |
GET |
Development users and tenants from your providers; [] without any |
Routes are derived from module names; see How Arc works. The bodies are the result envelopes.
Status codes
Section titled “Status codes”Selected in this order: success 200; not authorized 403; invalid 400; query not ready 202; exception 500. An authentication handler that returns :failed gives 401. A malformed body is a 400 with a malformedRequest result, never a 500. A failed result never carries a response value.
Headers
Section titled “Headers”| Header | Behavior |
|---|---|
X-Correlation-ID |
A valid UUID is reused; anything else is replaced. The effective value is echoed on every Arc response and appears as correlationId in the envelope. Configurable with correlation_header |
X-Allowed-Severity |
The highest validation severity the caller tolerates, capped at Warning. See Validation |
x-cratis-tenant-id |
Becomes ctx.tenant. Configurable with tenant_header. Arc does not enforce tenancy |
Header names are matched case-insensitively.
Request bodies
Section titled “Request bodies”Arc reads the body itself when Plug.Parsers has not. If you parse JSON earlier, Arc uses conn.body_params. The body limit is max_body_bytes (default 1,000,000); a larger body is a 400. Unknown fields in a command body are ignored.
Observable transports
Section titled “Observable transports”- Snapshot. A plain
GETreturns the current result. - Server-Sent Events. Each result is written as
data: {envelope}followed by a blank line. A: keep-alivecomment is sent every 15 seconds while idle so a closed connection is noticed. - WebSocket, direct. Messages carry a
typeofData,PingorPong. - WebSocket, hub.
/.cratis/queries/wsopens withConnectedand then carriesSubscribe,Unsubscribe,QueryResult,Unauthorized,Error,PingandPong, with per-subscription revisions. A denied subscription ends withUnauthorizedfor that query without disturbing the others.
All need the Arc application in your supervision tree. See Queries and the limits.
Verified with
Section titled “Verified with”The HTTP behavior is exercised against Bandit, and the proxy contract runs the real @cratis/arc client against it, including the QUERY method, the hub and Server-Sent Events. The WebSocket support uses WebSock, so other WebSock-capable servers should work; they are not part of the test matrix.
Next steps
Section titled “Next steps”- Hosting on Phoenix adds authentication, the SPA and LiveView.
- Configuration lists every option.