Event Booking API is a backend service for browsing events, creating and managing ticket bookings, and retrieving basic administrative statistics. The codebase is structured as a layered Go application with Gin for HTTP handling, PostgreSQL for persistence, raw SQL repositories via pgx, and Swagger documentation served directly by the API.
This project exposes a small REST API focused on event booking workflows:
- list active events with computed ticket availability
- fetch full event details with recent bookings
- create bookings with transactional business rules
- get booking details by booking reference
- cancel confirmed bookings
- retrieve aggregated admin statistics
- Active event listing with derived
available_ticketsandtotal_bookings - Event details endpoint that includes up to 10 recent bookings
- Booking creation flow with validation for user existence, event existence, event status, ticket price, capacity, and a max 4 tickets per user per event rule
- Booking lookup and cancellation by booking reference
- Admin stats endpoint with total events, bookings, revenue, top event, and bookings created today
- Swagger UI for interactive API exploration
- Structured separation of concerns across handlers, services, repositories, DTOs, and request models
| Area | Technology |
|---|---|
| Backend language | Go 1.25.5 |
| HTTP framework | Gin |
| Database | PostgreSQL 15 |
| Query / data access | pgx/v5 with pgxpool, hand-written SQL |
| API style | REST API over JSON |
| Validation | go-playground/validator/v10 |
| Environment loading | joho/godotenv |
| Documentation | Swaggo-generated Swagger docs + Swagger UI |
| Containerization | Docker Compose, postgres:15-alpine |
| Middleware | Custom request logging middleware + Gin recovery |
| Authentication / authorization | Not present in the current repository |
| ORM | No ORM is used; the project relies on raw SQL queries |
cmd/server/main.go application entry point and Swagger metadata
internal/app/ dependency wiring and router setup
internal/database/ PostgreSQL connection pool configuration
internal/handlers/ HTTP handlers and HTTP error mapping
internal/services/ business rules and use-case logic
internal/repository/ repository interfaces, transactions, raw SQL queries
internal/models/ database/domain models
internal/requests/ request payload structs
internal/dto/ response DTOs
internal/validation/ request validation and validation error formatting
pkg/middlewares/ HTTP middleware
docs/ generated Swagger files
sql/init.sql schema creation and seed data
docker-compose.yml local PostgreSQL setup
- Go version matching
go.mod(currently1.25.5) - Docker and Docker Compose
- Copy the example environment file:
cp .env.example .env- Start PostgreSQL:
docker compose up -d postgres- Run the API:
go run ./cmd/serverThe application loads environment variables from .env automatically.
| Variable | Description | Example |
|---|---|---|
POSTGRES_DB |
PostgreSQL database name used by Docker Compose | event_booking |
POSTGRES_USER |
PostgreSQL user | app |
POSTGRES_PASSWORD |
PostgreSQL password | app_secret |
POSTGRES_PORT |
Host port mapped to PostgreSQL | 5432 |
POSTGRES_CONTAINER_NAME |
Docker container name for PostgreSQL | event_booking_postgres |
DATABASE_URL |
Connection string used by the Go application | postgres://app:app_secret@localhost:5432/event_booking |
SERVER_PORT |
HTTP port used by the API server | 8080 |
With .env in place:
docker compose up -d postgres
go run ./cmd/serverBy default, the API starts on:
http://localhost:8080
Useful endpoints:
GET /eventsGET /events/:idPOST /bookingsGET /bookings/:refDELETE /bookings/:refGET /admin/stats
This repository does not use a dedicated migration tool or ORM migration framework.
- Database schema creation and seed data are defined in
sql/init.sql. - The script is mounted into the PostgreSQL container and runs automatically when the database is initialized on a fresh Docker volume.
- Because this is bootstrap-based initialization, the SQL script is not re-applied automatically to an already populated volume.
If you need a fresh local database state, recreate the PostgreSQL volume. This removes existing local data:
docker compose down -v
docker compose up -d postgresSwagger documentation is included in the repository under docs/ and served by the application.
After starting the API, open:
http://localhost:8080/swagger/index.html
The raw Swagger document is exposed at:
http://localhost:8080/swagger/doc.json
- The codebase follows a layered architecture: handlers -> services -> repositories -> database.
- Business rules are centralized in the service layer, while SQL remains explicit in the repository layer.
- Booking creation and cancellation use database transactions and
SELECT ... FOR UPDATElocking to protect capacity-sensitive operations. - Request payloads (
internal/requests) are separated from response DTOs (internal/dto) and persistence models (internal/models). - Service-level domain errors are translated into consistent HTTP responses such as
400,404,409, and500. - No authentication or authorization middleware is implemented in the current codebase, so all registered routes are publicly accessible.