-
Couldn't load subscription status.
- Fork 58
Description
Summary
convex-helpers already generates an OpenAPI 3 spec from a Convex deployment, which is great for typed HTTP clients in other languages. I’m proposing a sibling AsyncAPI spec generator, and an umbrella “Standard Specs” command that outputs OpenAPI + AsyncAPI together. This pairs Convex’s HTTP pull model with a standards-based push model and unblocks non-JS runtimes (Unity/.NET, Unreal, IoT) from day one. The OpenAPI path is beta and explicitly non-reactive/non-realtime, so the AsyncAPI companion fills that gap.  
Motivation
- OpenAPI (beta) is pull-only. Convex’s OpenAPI generation relies on the HTTP API, which means queries are not reactive/real-time. 
- AsyncAPI is the standard for message-driven / streaming APIs and is protocol-agnostic (HTTP, WebSocket, MQTT, etc.). It’s the natural complement to OpenAPI for documenting server push. 
- The Functions HTTP endpoint (POST
/api/run/{functionIdentifier}) already consolidates server logic; an AsyncAPI doc can describe a streaming counterpart (SSE or WebSocket) without changing Convex’s function model. 
Proposal
1) New CLI: async-api-spec
Generate an AsyncAPI v3 document that describes Convex servers, security, channels, and messages.
Phase 1 (spec-only, no runtime changes required):
- Emit an AsyncAPI doc that models stream-shaped HTTP interactions using HTTP bindings and operation reply (sufficient to describe SSE via
text/event-stream).  - Reuse the same function discovery/validators used by the OpenAPI generator so payload schemas match.
Phase 2 (when a realtime watch endpoint ships):
- Add a WebSocket or SSE server and channels to describe subscribe/watch operations (initial snapshot + patches + errors + heartbeats). AsyncAPI has official WebSocket bindings and HTTP bindings suitable for SSE. 
Output: specs/convex-asyncapi.yaml (AsyncAPI 3.0). 
2) New umbrella CLI: spec
npx convex-helpers spec --formats openapi,asyncapi --out specs/ → writes convex-openapi.yaml and convex-asyncapi.yaml, sharing config (servers/auth/metadata). This keeps “standards export” a single, CI-friendly step.
Design outline
Discovery & schemas
- Reuse existing OpenAPI generation’s introspection so the AsyncAPI generator maps function args/returns to JSON Schema (mirroring OpenAPI components). 
Servers & security
- Point to the deployment base (same as OpenAPI). Document auth the same way used by the HTTP API (/
api/run/{functionIdentifier}), then add protocol bindings when WS/SSE is available. 
Channels & operations
- Phase 1: Represent streaming/push over HTTP via operation reply and HTTP binding (describe SSE using text/event-stream). 
- Phase 2: Add WS channels with message shapes for subscribe, init, patch, error, complete, plus a resumeToken for reconnects (just documentation initially). 
Tooling ecosystem
- Validate with the AsyncAPI CLI/Generator and enable Modelina for code-gen (including C# models for Unity). 
Example (AsyncAPI v3 sketch, Phase 2 target)
asyncapi: 3.0.0
info:
title: Convex Realtime (Watch)
version: 0.1.0
defaultContentType: application/json
servers:
ws:
protocol: ws
host: ${CONVEX_URL}
channels:
query.messages.list:
address: query.messages.list
messages:
Init:
payload:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/Message'
Patch:
payload:
type: object
properties:
ops:
type: array
items: { type: object }
operations:
receive:
summary: Initial snapshot and subsequent patches for messages.list
components:
schemas:
Message:
type: object
properties:
_id: { type: string }
text: { type: string }
required: [_id, text](SSE version would use an HTTP server and binding with text/event-stream.) 
CLI / DX
npx convex-helpers async-api-spec --out specs/convex-asyncapi.yamlnpx convex-helpers spec --formats openapi,asyncapi --out specs/- Post-run tip: “Use @asyncapi/cli or Generator to render docs or bootstrap clients; use Modelina to emit C# models.” 
Acceptance criteria
MVP (Phase 1):
- New command outputs a valid AsyncAPI 3 document describing Convex servers, security, and HTTP-based channels (SSE represented via HTTP binding + operation reply). CI validates the spec. 
- “Standard Specs” command emits both OpenAPI and AsyncAPI from shared config. (OpenAPI generator already present.) 
Phase 2 (realtime watch available): - Add WebSocket/SSE servers + channels for live subscribe/watch. Message shapes include
init, patch, error, complete, and aresumeToken. 
Why prioritize this
- Completes the story for non-yet supported clients. OpenAPI covers pull; AsyncAPI covers push, together they document how to build typed, near-real-time clients in Unity/.NET and beyond. 
- Low incremental cost. Reuses the OpenAPI generator’s discovery and schema mapping; Phase 1 is spec-only (no backend changes). 
- Ecosystem leverage. Mature tooling exists today (AsyncAPI CLI/Generator; Modelina C#) to turn the spec into docs and models.