A LeetCode/Codeforces-style practice repository for backend API development — problems first, framework implementations second.
Contributions welcome — see CONTRIBUTING.md.
If this repo were organized as spring-boot/, go/, fastapi/, nestjs/, cpp/
at the top level, each framework folder would drift into its own vocabulary,
its own endpoint shapes, and its own idea of what "done" means. Comparing two
implementations of the same idea would mean jumping between unrelated trees
and reverse-engineering whether they actually solve the same problem.
Organizing by problem instead means:
- One spec, many implementations. Each problem has a single canonical description, endpoint contract, and OpenAPI spec. Every framework implementation is judged against the same contract, so implementations are genuinely comparable (same routes, same status codes, same payloads).
- Practice mirrors how the skill is used. You don't decide "today I do Go" — you decide "today I implement JWT auth", and then pick a framework. That matches how real interview/system-design practice works.
- Natural progression tracking. You can see at a glance which problems you've solved, in how many languages, and which concepts you've covered — like a LeetCode profile grid.
- No forced parity. Not every problem needs every framework (see rules below). Framework-first structures implicitly pressure you to keep folders "complete"; problem-first structure makes partial coverage the default, expected state.
- Easier to extend. Adding framework #6 means adding one new
implementations/<framework>/folder per problem you choose to redo — it never requires restructuring anything that exists.
api-backend/
├── README.md # you are here
├── docs/ # cross-cutting practice guidelines
│ ├── difficulty-levels.md
│ ├── concepts-glossary.md
│ ├── api-spec-guidelines.md
│ └── progress-tracker.md
├── templates/
│ ├── problem-README-template.md # copy this to scaffold a new problem
│ ├── openapi-template.yaml
│ └── frameworks/ # per-framework starter scaffolds
│ ├── spring-boot/scaffold/
│ ├── go/scaffold/
│ ├── fastapi/scaffold/
│ ├── nestjs/scaffold/
│ └── cpp/scaffold/
├── scripts/
│ └── new_problem.sh # scaffolds a new problems/NNNN-slug/ dir
└── problems/
├── 0001-crud-todo-api/
│ ├── README.md # spec: requirements, endpoints, schema, tests
│ ├── openapi.yaml
│ └── implementations/
│ ├── spring-boot/ # independent, self-contained project
│ ├── go/
│ ├── fastapi/
│ ├── nestjs/
│ └── cpp/
├── 0002-jwt-auth-service/
├── 0003-paginated-product-catalog/
├── 0004-file-upload-service/
└── 0005-rate-limited-url-shortener/
Problems are numbered LeetCode-style: NNNN-kebab-case-slug, e.g.
0001-crud-todo-api. Numbers are assigned once and never reused or
renumbered, even if a problem is later deprecated — this keeps external
references (notes, commits, branches) stable.
- Do not force every problem into every framework. Only implement a problem in a framework when you actually want the practice rep.
- Some problems may have several implementations in the same framework
over time (e.g. a v2 exploring a different pattern) — put those in
implementations/<framework>-v2/rather than overwriting. - Each framework implementation is fully independent: its own dependency manifest, own Dockerfile, own tests, own README with run instructions. Nothing is shared at runtime between implementations.
- The problem's
openapi.yamlis the contract. Every implementation of that problem should conform to it so responses are diffable across frameworks with the same Postman/curl script. - Every implementation ships tests. Unit and/or integration, using
whatever is idiomatic for that framework (JUnit,
go test,pytest, Jest, Catch2/GoogleTest). - Docker is encouraged, especially for problems needing a database,
cache, or message broker — a
docker-compose.ymlper implementation should bring up the service plus its infra dependencies.
Each templates/frameworks/<name>/scaffold/ now contains a working,
copy-ready starter project — not just instructions. Go, FastAPI, and
Spring Boot scaffolds are locally build/test/run verified (compiles, all
tests pass, live server responds correctly). The NestJS scaffold is
likewise fully verified (build + unit tests + e2e tests + live server).
The C++ scaffold follows the same conventions but is not locally
build-verified (no C++ toolchain was available when authoring it) — build
it yourself and expect to fix minor issues.
Each templates/frameworks/<name>/README.md documents both the fast path
(copy the scaffold) and a from-scratch path (exact init commands/CLI
flags), plus a Pre-implementation checklist (health-check route,
DB/cache wiring, test harness, Swagger/OpenAPI wiring) to run through
before writing real business logic:
Each problem's openapi.yaml is the canonical contract every framework
implementation must conform to. You can use it before, during, and instead
of writing real backend code:
1. Preview it as readable docs (Swagger/Redoc UI)
npx @redocly/cli preview-docs problems/0001-crud-todo-api/openapi.yamlOr paste the file into https://editor.swagger.io for a zero-install look.
2. Lint/validate it before implementing against it
npx @redocly/cli lint problems/0001-crud-todo-api/openapi.yamlCatches malformed specs early. Redocly's default ruleset is stricter than
bare OpenAPI validity (it'll also flag missing operationIds, missing
security schemes, etc.) — those are style nits, not blockers.
3. Mock a fake server from it — test clients before any backend exists
npx @stoplight/prism-cli mock problems/0001-crud-todo-api/openapi.yaml
# serves on http://127.0.0.1:4010, validates every request/response against the specUseful for building a Postman collection, a frontend, or integration tests against the contract while you haven't written (or are mid-writing) the real implementation. Prism logs whether each request passed spec validation, catching contract mismatches immediately.
4. Cross-check a real implementation's generated spec against the canonical one
- FastAPI auto-generates
/openapi.jsonfrom your Pydantic models — diff it against the problem'sopenapi.yaml. - Spring Boot + springdoc-openapi serves
/swagger-ui.htmlthe same way. - Postman: File → Import → point at the
openapi.yamlpath to get every endpoint as a ready-made request collection instantly.
See docs/api-spec-guidelines.md for the conventions (error envelope,
pagination shape, ID/timestamp formats) every spec follows.
This repo ships an AGENTS.md — instructions for AI coding
agents (Claude Code, Codex, Copilot, etc.) that work in this repository.
Agents that support AGENTS.md auto-load it as project context; if yours
doesn't, paste it into the prompt or point the agent at the file.
Use it to generate new problems without doing the spec-writing by hand:
"Add a random new practice problem to this repo."
"Add problem 0006 about webhook delivery with retries."
"Generate the next 3 problems, favoring async/messaging concepts."
The agent will: pick the next free problem number, choose or use your
topic, run scripts/new_problem.sh, fully write the README (all 9
required sections + stretch goals) and openapi.yaml, validate the spec,
update docs/progress-tracker.md, and commit — following the exact
conventions in this README and docs/. It does not implement any
solution code; it only authors the problem spec, same as problems
0001-0005.
./scripts/new_problem.sh 0006 websocket-chat-room
This scaffolds problems/0006-websocket-chat-room/ from
templates/problem-README-template.md and an empty implementations/ dir.
Fill in the README, add an openapi.yaml if the problem is REST-based, then
implement it in whichever framework(s) you want practice in — copying the
matching starter from templates/frameworks/<name>/scaffold/.
- Create
templates/frameworks/<name>/scaffold/with a minimal idiomatic starter (hello-world endpoint, test setup, Dockerfile, README on how to run it). - From then on, any problem can grow an
implementations/<name>/folder by copying that scaffold. - Document the framework's expected structure in
templates/frameworks/<name>/README.md(see existing ones for the pattern) so every implementation stays idiomatic and consistent.
| Stack | Version |
|---|---|
| Java / Spring Boot | Java 21 (LTS), Spring Boot 3.3.x |
| Go | 1.22+ |
| Python / FastAPI | Python 3.11+ |
| Node / NestJS | Node 20 LTS, Nest 10.x |
| C++ | C++20 |
See docs/progress-tracker.md for a checklist grid of problems × frameworks.