High-performance REST API for Indonesian administrative regions built with Rust, Axum, and PostgreSQL.
This service is read-only and uses relational tables in the region-id-01 database:
- provinces
- districts
- subdistricts
- villages
- Fast HTTP API powered by Axum + Tokio
- PostgreSQL access via SQLx
- SeaORM-based migration support
- Hierarchical region endpoints
- Query-based filtering support
- Consistent JSON error format
- Rust
- Axum
- SQLx (PostgreSQL)
- Tokio
- dotenvy
The API uses these tables in PostgreSQL (created via migration):
| Table | Columns |
|---|---|
| provinces | id (bigint), name (varchar) |
| districts | id (bigint), name (varchar), province_id (bigint), longitude (double precision, nullable), latitude (double precision, nullable) |
| subdistricts | id (bigint), name (varchar), district_id (bigint), longitude (double precision, nullable), latitude (double precision, nullable) |
| villages | id (bigint), name (varchar), subdistrict_id (bigint), longitude (double precision, nullable), latitude (double precision, nullable) |
- Rust toolchain installed
- PostgreSQL running
- Database region-id-01 available (tables can be created using migration)
Create a file named .env in the project root:
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=region-id-01
DB_USERNAME=postgres
DB_PASSWORD=
APP_ADDR=0.0.0.0:3000Notes:
- DB_CONNECTION must be pgsql or postgres.
- APP_ADDR defaults to 0.0.0.0:3000 when not set.
Run database migrations first:
cargo run --bin migrate -- upThen start the API server:
cargo runDefault base URL:
http://0.0.0.0:3000
- Response format: JSON
- ID parameters must be positive integers
- Invalid input returns HTTP 400
- Missing records return HTTP 404
- Database/internal errors return HTTP 500
This project uses SeaORM migration to manage schema changes.
For team workflow and release policy, see docs/migration-workflow.md.
Useful commands:
# Apply all pending migrations
cargo run --bin migrate -- up
# Show migration status
cargo run --bin migrate -- status
# Roll back the last migration
cargo run --bin migrate -- down
# Drop all tables and re-run migrations (destructive)
cargo run --bin migrate -- freshCurrent migrations create these tables:
- provinces
- districts (includes longitude, latitude)
- subdistricts (includes longitude, latitude)
- villages (includes longitude, latitude)
| Resource | Method | Path | Query Params |
|---|---|---|---|
| Health | GET | /health | - |
| Provinces | GET | /provinces | - |
| Province Detail | GET | /provinces/:id | - |
| Districts by Province | GET | /provinces/:id/districts | - |
| Districts | GET | /districts | province_id (optional) |
| District Detail | GET | /districts/:id | - |
| Subdistricts by District | GET | /districts/:id/subdistricts | - |
| Subdistricts | GET | /subdistricts | district_id (optional) |
| Subdistrict Detail | GET | /subdistricts/:id | - |
| Villages by Subdistrict | GET | /subdistricts/:id/villages | - |
| Villages | GET | /villages | subdistrict_id (optional) |
| Village Detail | GET | /villages/:id | - |
# Health check
curl http://127.0.0.1:3000/health
# List provinces
curl http://127.0.0.1:3000/provinces
# List districts in a province
curl "http://127.0.0.1:3000/districts?province_id=31"
# List subdistricts in a district
curl "http://127.0.0.1:3000/subdistricts?district_id=3171"
# List villages in a subdistrict
curl "http://127.0.0.1:3000/villages?subdistrict_id=3171010"Health:
{
"status": "ok"
}Province:
{
"id": 31,
"name": "DKI JAKARTA"
}District:
{
"id": 3171,
"name": "JAKARTA SELATAN",
"province_id": 31,
"longitude": 106.84513,
"latitude": -6.22211
}Subdistrict:
{
"id": 3171010,
"name": "TEBET",
"district_id": 3171,
"longitude": 106.85221,
"latitude": -6.22978
}Village:
{
"id": 3171010001,
"name": "MENTENG DALAM",
"subdistrict_id": 3171010,
"longitude": 106.84591,
"latitude": -6.23626
}Error:
{
"error": "province id harus lebih dari 0"
}- src/main.rs: API server, routing, handlers, and PostgreSQL connection setup
- src/bin/migrate.rs: SeaORM migration CLI entry point
- src/migration/: migration definitions
- .env.example: sample environment variables
- docs/production-installation.md: production installation guide
- docs/migration-workflow.md: migration SOP for local, staging, and production
- Cargo.toml: project dependencies and metadata
This project is licensed under the MIT License. See LICENSE for details.