GameShelf is a small game-library API built to demonstrate using seriousdb as an external HTTP key-value datastore.
The application is intentionally small. Its purpose is to exercise seriousdb from the perspective of a real consumer application rather than from inside the seriousdb repository.
GameShelf
|
| HTTP
v
seriousdb
|
v
.sdb
GameShelf does not import seriousdb internals. It communicates with seriousdb exclusively through its HTTP API using httpx.
Game records are serialized to JSON strings before being stored in seriousdb.
- Create games with automatically generated UUID7 identifiers
- Update existing games
- Retrieve a game by ID
- List games
- Delete games
- Persist games through seriousdb
- Return
404when a game does not exist - Return
503when seriousdb is unavailable - Exercise concurrent updates through the GameShelf API
- Python 3.14+
- uv
- A running seriousdb instance
From the seriousdb repository:
uv run fastapi dev main.pyBy default, seriousdb runs on:
http://127.0.0.1:8000
From this repository:
uv run fastapi dev src/gameshelf/main.py --port 8001GameShelf runs on:
http://127.0.0.1:8001
FastAPI provides an interactive API browser at:
http://127.0.0.1:8001/docs
The documentation can be used to create, retrieve, list, update, and delete games without manually constructing HTTP requests.
POST /gamesGameShelf generates a UUID7 identifier for the new game.
Example:
curl -X POST "http://127.0.0.1:8001/games" \
-H "Content-Type: application/json" \
-d '{"title":"Darkwood","status":"playing","hours":14,"notes":"Reached the Silent Forest","tags":["horror","survival"]}'The response includes the generated game ID:
{
"id": "01a0a7df-828a-75e3-9b31-2ee3ce5b5ed6",
"title": "Darkwood",
"status": "playing",
"hours": 14,
"notes": "Reached the Silent Forest",
"tags": [
"horror",
"survival"
]
}GET /games/{game_id}Use the ID returned when the game was created.
curl "http://127.0.0.1:8001/games/01a0a7df-828a-75e3-9b31-2ee3ce5b5ed6"Example response:
{
"id": "01a0a7df-828a-75e3-9b31-2ee3ce5b5ed6",
"title": "Darkwood",
"status": "playing",
"hours": 14,
"notes": "Reached the Silent Forest",
"tags": [
"horror",
"survival"
]
}PUT /games/{game_id}The ID identifies the existing game. The request body contains the updated game data.
curl -X PUT "http://127.0.0.1:8001/games/01a0a7df-828a-75e3-9b31-2ee3ce5b5ed6" \
-H "Content-Type: application/json" \
-d '{"title":"Darkwood","status":"completed","hours":32,"notes":"Finished the game","tags":["horror","survival"]}'A successful update returns the same ID together with the updated game.
GET /gamescurl "http://127.0.0.1:8001/games"Example response:
[
{
"id": "01a0a7df-828a-75e3-9b31-2ee3ce5b5ed6",
"title": "Darkwood",
"status": "completed",
"hours": 32,
"notes": "Finished the game",
"tags": [
"horror",
"survival"
]
}
]DELETE /games/{game_id}curl -X DELETE "http://127.0.0.1:8001/games/01a0a7df-828a-75e3-9b31-2ee3ce5b5ed6"A successful delete returns 204 No Content.
GameShelf connects to seriousdb at:
http://127.0.0.1:8000
by default.
To use another seriousdb instance on Linux or macOS:
export SERIOUSDB_URL="http://127.0.0.1:9000"On Windows PowerShell:
$env:SERIOUSDB_URL="http://127.0.0.1:9000"GameShelf runs on:
http://127.0.0.1:8001
by default.
The API test suite can be pointed at another GameShelf instance.
Linux/macOS:
export GAMESHELF_URL="http://127.0.0.1:9000"Windows PowerShell:
$env:GAMESHELF_URL="http://127.0.0.1:9000"The tests exercise the seriousdb client and the GameShelf-to-seriousdb integration.
Start seriousdb and GameShelf, then run:
uv run pytestThe automated tests cover:
- Creating and retrieving games
- Updating existing games
- Handling missing games
- Listing games
- Deleting games
- Concurrent updates to the same game
- Interaction between GameShelf and seriousdb over HTTP
Persistence across a seriousdb restart and behavior when seriousdb is unavailable were also verified manually against the running services.
The integration tests create temporary records and remove them during cleanup.
The goal is to evaluate seriousdb from the perspective of an external application.
Building GameShelf provides a practical way to investigate questions such as:
- How convenient is seriousdb's HTTP API for an application developer?
- How should consumers handle missing keys?
- How should consumers handle an unavailable service?
- How natural is storing structured application data as string values?
- How useful is
/db/allwhen implementing application-level listing? - What happens to application data across seriousdb restarts?
- What behavior appears under concurrent usage?
The observations from this project can inform documentation, tests, issues, and future improvements to seriousdb.