HTTP API
In this stage, you’ll build an in-memory key-value store and expose it over a REST API. It won’t survive a restart yet, but it’s the foundation every later stage builds on.
Endpoints
Section titled “Endpoints”You’ll implement the following endpoints:
PUT /kv/{key}
Section titled “PUT /kv/{key}”Add or update a key-value pair in the store.
PUT /kv/{key}Content-Type: text/plain
hello world
----
200
400Content-Type: text/plain
key cannot be empty
400Content-Type: text/plain
value cannot be emptyThe body is the value to store as plain text. Return 400 with key cannot be empty if the key is empty, or value cannot be empty if the body is empty.
GET /kv/{key}
Section titled “GET /kv/{key}”Retrieve the value associated with the given key.
GET /kv/{key}
----
200Content-Type: text/plain
hello world
404Content-Type: text/plain
key not foundDELETE /kv/{key}
Section titled “DELETE /kv/{key}”Remove a key-value pair from the store.
DELETE /kv/{key}
----
200Return 200 whether or not the key existed. Return 400 with key cannot be empty if the key is empty.
DELETE /clear
Section titled “DELETE /clear”Remove all key-value pairs from the store.
DELETE /clear
----
200GET /health
Section titled “GET /health”Reports whether the node is ready to serve requests.
GET /health
----
200The test harness polls this endpoint after starting each node and waits for a 200 OK before running any tests. Return 200 only once your server is fully initialized and ready to handle requests.
Error Handling
Section titled “Error Handling”Unsupported HTTP methods on any endpoint should return:
405Content-Type: text/plain
method not allowedStorage
Section titled “Storage”An in-memory map/dictionary is sufficient for this stage. The dataset fits in memory and you’ll add persistence later. Make sure your store handles concurrent requests safely, since some tests issue requests in parallel.
Data Model
Section titled “Data Model”Keys and values are stored as strings. Keys must contain only alphanumeric characters plus :, _, ., and -. Examples of valid keys:
user:123cache_entrymetric.latency.p99
Values are arbitrary UTF-8 text.
Testing
Section titled “Testing”Your server must listen on port 8080. The test harness builds your Dockerfile and starts a container exposing that port.
You can test your implementation using the clstr command:
$ clstr test http-apiTesting http-api: Store and Retrieve Data
✓ PUT Stores Values (15ms)✓ PUT Rejects Empty Keys and Values (575µs)✓ GET Returns Stored Values (1ms)✓ GET Rejects Missing and Invalid Keys (431µs)✓ DELETE Idempotently Removes Keys (7ms)✓ DELETE Rejects Empty Keys (154µs)✓ CLEAR Removes All Keys from the Store (7ms)✓ Concurrent Writes to Different Keys All Succeed (18ms)✓ Concurrent Writes to the Same Key Do Not Corrupt Data (5ms)✓ Unsupported HTTP Methods Return 405 (608µs)
PASSED ✓
Run clstr next to advance to the next stage.Debugging
Section titled “Debugging”Your server’s output (stdout/stderr) is captured during testing and viewable with clstr logs:
$ clstr logs n1[n1] +0.000s [START][n1] +0.127s Server listening on 0.0.0.0:8080[**] +0.379s [CLUSTER READY][**] +0.380s [TEST: PUT Stores Values][n1] +0.395s PUT /kv/kenya:capital accepted, value=Nairobi[**] +0.411s [TEST: GET Returns Stored Values][n1] +0.412s GET /kv/kenya:capital returning 200[**] +0.413s [TEST: DELETE Idempotently Removes Keys][n1] +0.420s DELETE /kv/kenya:capital accepted[n1] +0.427s GET /kv/kenya:capital returning 404Add your own logging to help debug issues.
When tests fail, clstr will show you exactly what went wrong:
$ clstr testTesting http-api: Store and Retrieve Data
✓ PUT Stores Values (15ms)✓ PUT Rejects Empty Keys and Values (575µs)✓ GET Returns Stored Values (1ms)✗ GET Rejects Missing and Invalid Keys (2ms)
GET http://n1:8080/kv/nonexistent:key → 404 Expected response: matching pattern /^key not found\n?$/ Actual response:
Your server should return 404 Not Found when a key doesn't exist. Check your key lookup logic and error handling.
FAILED ✗
Read the guide: https://clstr.io/kv-store/http-api