Section 4: A Move Is Four Characters and a Number - API Design (with Pushback)
Executive Summary: Section 3 showed that up to 28K moves a second will cross this contract at peak, each with a relay budget of p99 < 50 ms. This section writes the two surfaces they travel on: one multiplexed WebSocket per client for real-time play, and REST for everything else. We follow Priya's Re1 across the wire, reconnect Omar after his phone drops, and defend each field under pushback.
The interviewer says: "Show me the API." Before you write a path, say the rule that shapes it. The client sends intent; the server owns state. A client may say "I'd like to play f1e1 as ply 23." It never says "here is the new board" or "I used four seconds."
Two Surfaces, One Rule
| Surface | Carries | Why this shape |
|---|---|---|
WebSocket wss://play.example.com/v1/socket |
Moves, resign, draw offers, abort, reconnect sync, spectating, start, end, tournament pushes |
One long-lived, ordered connection; the server can push the opponent's move the instant it exists |
REST https://api.example.com/v1 |
Seeks, challenges, game snapshots, history, PGN, tournament create/join/standings | Cacheable, retryable, easy to rate-limit; nothing here needs to arrive in under 50 ms |
The socket is one per client, shared by the game, the lobby and tournament pages. Two sockets would mean two to authenticate, two to reconnect, and no ordering between them. Every message carries a t (type) and, where it applies, a g (game id). Clients ignore unknown fields, and the server only offers a client game types its version declares.
The first message on a new socket authenticates it:
{"t":"auth","token":"<access token>"}
The gateway verifies the 15-minute JWT locally before accepting game traffic. Before it expires, the client sends a fresh auth on the same socket, so a long rapid game never outlives its token.
Sign in to continue reading
The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.
Sign in to read the full lesson