docs: add usage guide
This commit is contained in:
103
README.md
Normal file
103
README.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Pokedex API
|
||||
|
||||
REST API for the TrueLayer Software Engineering Challenge. It returns basic Pokémon information from PokéAPI and, on request, a fun translated description from FunTranslations.
|
||||
|
||||
## Requirements
|
||||
|
||||
You can run it either with Docker or with a local Rust toolchain.
|
||||
|
||||
### Option A: Docker
|
||||
|
||||
Install Docker Desktop or an equivalent Docker runtime, then run:
|
||||
|
||||
```bash
|
||||
docker build -t pokedex-api .
|
||||
docker run --rm -p 5000:5000 pokedex-api
|
||||
```
|
||||
|
||||
### Option B: local Rust
|
||||
|
||||
Install Rust with rustup:
|
||||
|
||||
```bash
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
source "$HOME/.cargo/env"
|
||||
rustup default stable
|
||||
```
|
||||
|
||||
Then run the service:
|
||||
|
||||
```bash
|
||||
cargo run
|
||||
```
|
||||
|
||||
The API listens on `0.0.0.0:5000` by default.
|
||||
|
||||
## Endpoints
|
||||
|
||||
```bash
|
||||
curl http://localhost:5000/health
|
||||
curl http://localhost:5000/pokemon/mewtwo
|
||||
curl http://localhost:5000/pokemon/translated/mewtwo
|
||||
curl http://localhost:5000/metrics
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "mewtwo",
|
||||
"description": "It was created by a scientist after years of horrific gene splicing and DNA engineering experiments.",
|
||||
"habitat": "rare",
|
||||
"isLegendary": true
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
| Variable | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `BIND_ADDR` | `0.0.0.0:5000` | HTTP bind address |
|
||||
| `POKEAPI_BASE_URL` | `https://pokeapi.co/api/v2` | PokéAPI base URL |
|
||||
| `FUN_TRANSLATIONS_BASE_URL` | `https://funtranslations.mercxry.me` | FunTranslations base URL |
|
||||
| `REQUEST_TIMEOUT_SECONDS` | `5` | Upstream HTTP timeout |
|
||||
| `RATE_LIMIT_PER_SECOND` | `20` | Global token refill rate |
|
||||
| `RATE_LIMIT_BURST` | `40` | Global burst capacity |
|
||||
| `OTEL_SERVICE_NAME` | `pokedex-api` | OpenTelemetry service name |
|
||||
| `RUST_LOG` | `pokedex_api=info,tower_http=info` | JSON tracing log filter |
|
||||
|
||||
## Instrumentation
|
||||
|
||||
The service includes:
|
||||
|
||||
- structured JSON logging via `tracing`
|
||||
- request spans via `tower-http`
|
||||
- `x-request-id` generation and propagation
|
||||
- OpenTelemetry metrics for HTTP requests, HTTP errors, upstream calls, upstream errors and latency histograms
|
||||
- `/metrics` in Prometheus text format backed by OpenTelemetry instruments
|
||||
- simple global token-bucket rate limiting returning `429`
|
||||
|
||||
## Development checks
|
||||
|
||||
```bash
|
||||
cargo fmt --all --check
|
||||
cargo clippy --locked --all-targets -- -D warnings
|
||||
cargo test --locked
|
||||
```
|
||||
|
||||
The crate denies unsafe code and enables strict Clippy groups: `all`, `pedantic`, `nursery` and `cargo`, with only dependency-version noise allowed.
|
||||
|
||||
## Docker multi-arch build
|
||||
|
||||
```bash
|
||||
docker buildx build \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--build-arg GIT_SHA="$(git rev-parse HEAD)" \
|
||||
-t pokedex-api:local .
|
||||
```
|
||||
|
||||
The Dockerfile uses `cargo-chef` and BuildKit cache mounts for dependency and target directory caching.
|
||||
|
||||
## Production notes
|
||||
|
||||
For a production API I would add per-client or per-token rate limiting instead of one global bucket, retries with bounded exponential backoff, circuit breakers for upstream failures, response caching for PokéAPI data, stronger health checks that distinguish readiness from liveness, dashboards and alerts from the OTEL metrics, and a dedicated OTEL collector pipeline. I would also separate public API traffic from `/metrics`, define SLOs, and add contract tests against recorded upstream fixtures.
|
||||
Reference in New Issue
Block a user