Skip to content

Commit f9c8eb1

Browse files
committed
docs: move architecture and API docs to docs/ directory
Move design and API documentation to dedicated docs/ folder: - ArchitecturalAudit.md — Audit of correctness issues in V2 - CorrectRaftStateMachinePattern.md — V3 migration design and rationale - DESIGN.md — Original design blueprint - API_DESIGN.md — HTTP API design - API_USAGE_EXAMPLES.md — HTTP API usage examples Update mix.exs to reference docs/ paths in docs.extras and package.files. Remove outdated performance and analysis documents (pre-V3 benchmarks). Update CLAUDE.md with V3 correctness invariants and architecture overview.
1 parent b1df1cb commit f9c8eb1

File tree

5 files changed

+2846
-0
lines changed

5 files changed

+2846
-0
lines changed

docs/API_DESIGN.md

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
# Concord HTTP API Design
2+
3+
## Overview
4+
RESTful HTTP API for Concord distributed key-value store with JSON request/response format.
5+
6+
## Base URL
7+
```
8+
http://localhost:4000/api/v1
9+
```
10+
11+
## Authentication
12+
Two authentication methods supported:
13+
1. **Bearer Token**: `Authorization: Bearer <token>`
14+
2. **API Key**: `X-API-Key: <token>`
15+
16+
Both use the existing Concord token system.
17+
18+
## Endpoints
19+
20+
### Core CRUD Operations
21+
22+
#### PUT /api/v1/kv/{key}
23+
Store a single key-value pair.
24+
- **Method**: PUT
25+
- **Path**: `/api/v1/kv/{key}`
26+
- **Body**:
27+
```json
28+
{
29+
"value": "any JSON-serializable value",
30+
"ttl": 3600 // optional, seconds
31+
}
32+
```
33+
- **Response**:
34+
```json
35+
{
36+
"status": "ok"
37+
}
38+
```
39+
40+
#### GET /api/v1/kv/{key}
41+
Retrieve a single value.
42+
- **Method**: GET
43+
- **Path**: `/api/v1/kv/{key}`
44+
- **Query Params**:
45+
- `with_ttl` (boolean): Include TTL information
46+
- **Response**:
47+
```json
48+
{
49+
"status": "ok",
50+
"data": {
51+
"value": "stored value",
52+
"ttl": 3600 // only if with_ttl=true
53+
}
54+
}
55+
```
56+
57+
#### DELETE /api/v1/kv/{key}
58+
Delete a single key.
59+
- **Method**: DELETE
60+
- **Path**: `/api/v1/kv/{key}`
61+
- **Response**:
62+
```json
63+
{
64+
"status": "ok"
65+
}
66+
```
67+
68+
### Bulk Operations
69+
70+
#### POST /api/v1/kv/bulk
71+
Store multiple key-value pairs atomically.
72+
- **Method**: POST
73+
- **Path**: `/api/v1/kv/bulk`
74+
- **Body**:
75+
```json
76+
{
77+
"operations": [
78+
{"key": "key1", "value": "value1"},
79+
{"key": "key2", "value": "value2", "ttl": 3600}
80+
]
81+
}
82+
```
83+
- **Response**:
84+
```json
85+
{
86+
"status": "ok",
87+
"data": {
88+
"key1": "ok",
89+
"key2": "ok"
90+
}
91+
}
92+
```
93+
94+
#### POST /api/v1/kv/bulk/get
95+
Retrieve multiple values.
96+
- **Method**: POST
97+
- **Path**: `/api/v1/kv/bulk/get`
98+
- **Body**:
99+
```json
100+
{
101+
"keys": ["key1", "key2", "key3"],
102+
"with_ttl": false
103+
}
104+
```
105+
- **Response**:
106+
```json
107+
{
108+
"status": "ok",
109+
"data": {
110+
"key1": {"status": "ok", "value": "value1"},
111+
"key2": {"status": "error", "error": "not_found"},
112+
"key3": {"status": "ok", "value": "value3", "ttl": 1800}
113+
}
114+
}
115+
```
116+
117+
#### POST /api/v1/kv/bulk/delete
118+
Delete multiple keys atomically.
119+
- **Method**: POST
120+
- **Path**: `/api/v1/kv/bulk/delete`
121+
- **Body**:
122+
```json
123+
{
124+
"keys": ["key1", "key2", "key3"]
125+
}
126+
```
127+
- **Response**:
128+
```json
129+
{
130+
"status": "ok",
131+
"data": {
132+
"key1": "ok",
133+
"key2": "ok",
134+
"key3": {"status": "error", "error": "not_found"}
135+
}
136+
}
137+
```
138+
139+
### TTL Operations
140+
141+
#### POST /api/v1/kv/{key}/touch
142+
Extend TTL for a key.
143+
- **Method**: POST
144+
- **Path**: `/api/v1/kv/{key}/touch`
145+
- **Body**:
146+
```json
147+
{
148+
"ttl": 3600 // additional TTL seconds
149+
}
150+
```
151+
- **Response**:
152+
```json
153+
{
154+
"status": "ok"
155+
}
156+
```
157+
158+
#### POST /api/v1/kv/bulk/touch
159+
Extend TTL for multiple keys.
160+
- **Method**: POST
161+
- **Path**: `/api/v1/kv/bulk/touch`
162+
- **Body**:
163+
```json
164+
{
165+
"operations": [
166+
{"key": "key1", "ttl": 3600},
167+
{"key": "key2", "ttl": 7200}
168+
]
169+
}
170+
```
171+
- **Response**:
172+
```json
173+
{
174+
"status": "ok",
175+
"data": {
176+
"key1": "ok",
177+
"key2": "ok"
178+
}
179+
}
180+
```
181+
182+
#### GET /api/v1/kv/{key}/ttl
183+
Get remaining TTL for a key.
184+
- **Method**: GET
185+
- **Path**: `/api/v1/kv/{key}/ttl`
186+
- **Response**:
187+
```json
188+
{
189+
"status": "ok",
190+
"data": {
191+
"ttl": 3600
192+
}
193+
}
194+
```
195+
196+
### Administrative Operations
197+
198+
#### GET /api/v1/kv
199+
Get all key-value pairs (use sparingly).
200+
- **Method**: GET
201+
- **Path**: `/api/v1/kv`
202+
- **Query Params**:
203+
- `with_ttl` (boolean): Include TTL information
204+
- `limit` (integer): Limit number of results
205+
- **Response**:
206+
```json
207+
{
208+
"status": "ok",
209+
"data": {
210+
"key1": {"value": "value1", "ttl": 3600},
211+
"key2": {"value": "value2"}
212+
}
213+
}
214+
```
215+
216+
#### GET /api/v1/health
217+
Health check endpoint.
218+
- **Method**: GET
219+
- **Path**: `/api/v1/health`
220+
- **Response**:
221+
```json
222+
{
223+
"status": "healthy",
224+
"timestamp": "2025-01-20T12:00:00Z",
225+
"cluster": {
226+
"status": "leader",
227+
"nodes": 3,
228+
"storage": {
229+
"size": 1000,
230+
"memory": 1048576
231+
}
232+
}
233+
}
234+
```
235+
236+
#### GET /api/v1/status
237+
Detailed cluster status.
238+
- **Method**: GET
239+
- **Path**: `/api/v1/status`
240+
- **Response**:
241+
```json
242+
{
243+
"status": "ok",
244+
"data": {
245+
"cluster": {...},
246+
"storage": {...},
247+
"node": "node@hostname"
248+
}
249+
}
250+
```
251+
252+
## Error Responses
253+
254+
All error responses follow this format:
255+
```json
256+
{
257+
"status": "error",
258+
"error": {
259+
"code": "INVALID_KEY",
260+
"message": "Key cannot be empty",
261+
"details": {...}
262+
}
263+
}
264+
```
265+
266+
### Common Error Codes
267+
- `INVALID_REQUEST` - Malformed JSON or missing required fields
268+
- `INVALID_KEY` - Invalid key format
269+
- `UNAUTHORIZED` - Missing or invalid authentication
270+
- `NOT_FOUND` - Key does not exist
271+
- `TIMEOUT` - Operation timed out
272+
- `CLUSTER_UNAVAILABLE` - Cluster not ready
273+
- `BATCH_TOO_LARGE` - Batch exceeds size limits
274+
- `VALIDATION_ERROR` - Input validation failed
275+
276+
## Rate Limiting
277+
- Configurable rate limits per API key
278+
- Response headers: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`
279+
280+
## CORS
281+
- Configurable CORS policies for cross-origin requests

0 commit comments

Comments
 (0)