A read-only REST API providing normalized administrative location data for Ghana, including countries, regions, districts, constituencies, and cities. https://ghana-location-api.vercel.app/api/v1/regions
This API serves as a canonical source for Ghana's administrative geography hierarchy:
Country
└── Regions
└── Districts / Metros / Municipals
└── Constituencies
└── Cities / Towns
The API is designed to be:
- Read-only - No mutations, no user data
- Fast - Optimized queries with proper indexing
- Stable - Slug-based identifiers that never change
- Cache-friendly - HTTP cache headers on all responses
- Go 1.22 or higher
- PostgreSQL (or Supabase)
- Supabase CLI (if using Supabase)
git clone https://github.com/blingyplus/ghana-location-api.git
cd ghana-location-apigo mod downloadCreate a .env file in the root directory:
DATABASE_URL=postgres://user:password@localhost:5432/ghana_location
PORT=8080For Supabase, you can get your connection string from your Supabase project dashboard or use:
supabase db get-connection-stringRun the migration using the migrate command:
go run cmd/migrate/main.goOr manually using psql:
psql $DATABASE_URL -f migrations/001_initial_schema.sqlSeed the database with location data:
go run cmd/seed/main.goThis will load data from the JSON files in the data/ directory:
countries.jsonregions.jsondistricts.jsonconstituencies.jsoncities.json
go run cmd/api/main.goThe API will start on port 8080 (or the port specified in your .env file).
All endpoints are prefixed with /api/v1.
GET /api/v1/countries- List all countriesGET /api/v1/countries/{code}- Get country by code (e.g., "GH")
GET /api/v1/regions- List all regionsGET /api/v1/regions/{slug}- Get region by slugGET /api/v1/regions/{slug}/districts- Get districts in a region
GET /api/v1/districts/{slug}- Get district by slugGET /api/v1/districts/{slug}/constituencies- Get constituencies in a district
GET /api/v1/constituencies/{slug}- Get constituency by slug
GET /api/v1/cities?district={slug}- Get cities in a district
All responses are JSON. Success responses include cache headers:
Cache-Control: public, max-age=3600
Content-Type: application/json
{
"id": "uuid",
"name": "Greater Accra",
"slug": "greater-accra",
"capital": "Accra"
}{
"error": "resource not found"
}The API follows clean architecture principles with clear boundaries:
Request → Handler → Service → Repository → Database
↓
JSON Response
- Handlers (
pkg/handlers/) - HTTP layer only, no business logic - Services (
pkg/services/) - Business logic and validation - Repositories (
pkg/repositories/) - Database access using pgx - Models (
pkg/models/) - Domain entities
countries- Country informationregions- Administrative regionsdistricts- Districts, metros, and municipalsconstituencies- Electoral constituenciescities- Cities and towns with coordinates
All tables use UUID primary keys and slug fields for public identifiers. Slugs are stable and never change.
This API is configured for deployment on Vercel as a serverless function.
- Vercel account
- PostgreSQL database (Supabase recommended)
- `DATABASE_URL environment variable
-
Connect your repository to Vercel
- Import your GitHub repository in the Vercel dashboard
- Vercel will auto-detect the Go configuration
-
Set environment variables
- In your Vercel project settings, add:
DATABASE_URL: Your PostgreSQL connection string
- In your Vercel project settings, add:
-
Run migrations and seed data
- Before deploying, ensure your production database is set up:
# Set DATABASE_URL to your production database export DATABASE_URL="your-production-database-url" # Run migrations go run cmd/migrate/main.go # Seed data go run cmd/seed/main.go
-
Deploy
- Push to your main branch or use
vercel deploy - Vercel will automatically build and deploy your function
- Push to your main branch or use
The vercel.json file configures:
- Go runtime (auto-detected from
go.mod) - Routing to the serverless function
- Build settings
- The API uses
pkg/instead ofinternal/packages to avoid Go's internal package visibility restrictions in serverless environments - Go version is set to 1.24 (Vercel's current supported version)
- The handler is located at
api/index.goand exports aHandlerfunction
The deployed API is available at:
- Production:
https://ghana-location-api.vercel.app - Health check:
https://ghana-location-api.vercel.app/health
- Language: Go 1.24
- Router: Chi
- Database: PostgreSQL with pgx driver
- Configuration: Environment variables via godotenv
- Deployment: Vercel (serverless)
ghana-location-api/
├── api/
│ └── index.go # Vercel serverless function handler
├── cmd/
│ ├── api/
│ │ └── main.go # Local development server
│ ├── migrate/
│ │ └── main.go # Database migration tool
│ └── seed/
│ └── main.go # Database seeding tool
├── pkg/
│ ├── handlers/ # HTTP handlers
│ ├── services/ # Business logic
│ ├── repositories/ # Database access
│ ├── models/ # Domain models
│ ├── config/ # Configuration
│ └── errors/ # Error handling
├── migrations/ # SQL migrations
├── data/ # Seed data files (JSON)
├── scripts/ # Data processing scripts
├── vercel.json # Vercel deployment configuration
├── go.mod
└── README.md
go build -o bin/api cmd/api/main.gogo test ./...See LICENSE file for details.
This is a read-only API designed for stability. Data normalization and seeding scripts are welcome contributions.