Skip to content

HTTP API

In this stage, you’ll build an in-memory key-value store and expose it over a REST API.

You’ll implement the following endpoints:

Add or update a key-value pair in the store.

PUT /kv/{key}
hello world
----
200
400
key cannot be empty
400
value cannot be empty

The 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.

Retrieve the value associated with the given key.

GET /kv/{key}
----
200
hello world
404
key not found

Remove a key-value pair from the store.

DELETE /kv/{key}
----
200

Return 200 whether or not the key existed.

Remove all key-value pairs from the store.

DELETE /clear
----
200

Reports whether the node is ready to serve requests.

GET /health
----
200

The 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.

Unsupported HTTP methods on any endpoint should return:

  • 405 Method Not Allowed: Return method not allowed

A simple in-memory map/dictionary is sufficient for this stage; the dataset fits in memory and you’ll add persistence in the next stage. Make sure your store handles concurrent requests safely; the tests will hit multiple endpoints in parallel.

Keys and values are stored as simple strings. This keeps the data model straightforward so you can focus on building intuition in distributed systems, not implementing complex data types.

Keys must contain only alphanumeric plus :, _, ., and - characters. Examples of valid keys:

  • user:123
  • cache_entry
  • metric.latency.p99

Values are stored as UTF-8 encoded text and can contain:

  • Unicode characters like 😊
  • Spaces and special symbols
  • Long strings (up to reasonable memory limits)

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:

Terminal window
$ clstr test http-api
Testing http-api: Store and Retrieve Data
✓ PUT Stores Values
✓ PUT Rejects Empty Keys and Values
✓ GET Returns Stored Values
✓ GET Rejects Missing and Invalid Keys
✓ DELETE Idempotently Removes Keys
✓ DELETE Rejects Empty Keys
✓ CLEAR Removes All Keys from the Store
✓ Concurrent Writes to Different Keys All Succeed
✓ Concurrent Writes to the Same Key Do Not Corrupt Data
✓ Unsupported HTTP Methods Return 405
PASSED ✓
Run 'clstr next' to advance to the next stage.

Your server’s output (stdout/stderr) is captured during testing and viewable with clstr logs:

Terminal window
$ clstr logs n1
================ STARTED ================
Server listening on 0.0.0.0:8080
PUT /kv/kenya:capital accepted, value=Nairobi
GET /kv/kenya:capital returning 200
DELETE /kv/kenya:capital accepted
GET /kv/kenya:capital returning 404

Add your own logging to help debug issues.

When tests fail, clstr will show you exactly what went wrong:

Terminal window
$ clstr test
Testing http-api: Store and Retrieve Data
✓ PUT Stores Values
✓ PUT Rejects Empty Keys and Values
✓ GET Returns Stored Values
✗ GET Rejects Missing and Invalid Keys
GET http://127.0.0.1:42409/kv/nonexistent:key (n1) → 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