A RESTful API service for tracking workouts and managing users, built with Go and PostgreSQL. This project provides endpoints for user registration, authentication via JWT tokens, and comprehensive workout management.
- π User Authentication: JWT-based authentication system with token management
- π€ User Management: User registration with secure password hashing
- ποΈ Workout Tracking: Full CRUD operations for workout management
- ποΈ Database Migrations: Automated database schema management with Goose
- π³ Docker Support: Easy deployment with Docker Compose
- π Security: Input validation, middleware protection, and secure password handling
POST /api/tokens- Create authentication token (login)POST /api/tokens/revoke-all- Revoke all tokens for authenticated user
POST /api/users- Register new user
GET /api/workouts- Get all workouts for authenticated userGET /api/workouts/{id}- Get specific workout by IDPOST /api/workouts- Create new workoutPUT /api/workouts/{id}- Update existing workoutDELETE /api/workouts/{id}- Delete workout
- Language: Go 1.24.6
- Database: PostgreSQL 17
- Router: Chi v5
- Authentication: JWT (golang-jwt/jwt/v4)
- Password Hashing: bcrypt
- Migrations: Goose
- Database Driver: pq (PostgreSQL driver)
go-workout-api/
βββ main.go # Application entry point
βββ compose.yml # Docker Compose configuration
βββ go.mod # Go module definition
βββ internal/
β βββ api/ # HTTP handlers
β β βββ token_handler.go # Authentication endpoints
β β βββ user_handler.go # User registration
β β βββ workout_handler.go # Workout CRUD operations
β βββ app/
β β βββ app.go # Application initialization
β βββ middleware/
β β βββ middleware.go # Authentication middleware
β βββ routes/
β β βββ routes.go # Route configuration
β βββ store/ # Data access layer
β β βββ database.go # Database connection
β β βββ tokens.go # Token operations
β β βββ user_store.go # User operations
β β βββ workout_store.go # Workout operations
β βββ tokens/
β β βββ tokens.go # JWT utilities
β βββ utils/
β βββ utils.go # Common utilities
βββ migrations/ # Database migrations
βββ fs.go # Embedded migrations
βββ *.sql # Migration files
- Go 1.24.6 or later
- Docker and Docker Compose
- PostgreSQL 17 (if running without Docker)
-
Clone the repository
git clone https://github.com/martialanouman/go-workout-api.git cd go-workout-api -
Start the database with Docker Compose
docker compose up -d db
-
Install dependencies
go mod download
-
Set up environment variables
The application requires a
.envfile for database configuration. Copy the example file and configure it:cp .env.example .env
Edit the
.envfile with your database configuration:DB_HOST=localhost DB_PORT=5432 DB_USER= DB_PASSWORD= DB_NAME=
Note: These values should match your PostgreSQL setup. If using Docker Compose, the default values above will work with the provided configuration.
-
Run database migrations
go run main.go migrate
-
Start the application
go run main.go # or with custom port go run main.go -port=3000
The API will be available at http://localhost:8080 (or your specified port).
To run the entire application stack with Docker Compose:
- Set up environment variables (as described in step 4 above)
- Start all services:
docker compose up -dThis will start both the PostgreSQL database and the application. The compose file includes:
- db: PostgreSQL database on port 5432
- db_test: Test database on port 5433 (for testing purposes)
The application uses the following default configuration:
- Port: 8080 (configurable via
-portflag) - Database: PostgreSQL connection via environment variables
- Timeouts:
- Idle: 1 minute
- Read: 10 seconds
- Write: 30 seconds
id- Unique identifierusername- Unique username (50 chars max)email- Unique email addresspassword_hash- Hashed passwordbio- User biographycreated_at,updated_at- Timestamps
id- Unique identifieruser_id- Reference to users tabletitle- Workout title (100 chars max)description- Workout descriptionduration_minutes- Workout durationcalories_burned- Calories burned during workoutcreated_at,updated_at- Timestamps
- Authentication tokens with expiration and user association
curl -X POST http://localhost:8080/api/users \
-H "Content-Type: application/json" \
-d '{
"username": "johndoe",
"email": "john@example.com",
"password": "securepassword",
"bio": "Fitness enthusiast"
}'curl -X POST http://localhost:8080/api/tokens \
-H "Content-Type: application/json" \
-d '{
"email": "john@example.com",
"password": "securepassword"
}'curl -X POST http://localhost:8080/api/workouts \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"title": "Morning Run",
"description": "5km run in the park",
"duration_minutes": 30,
"calories_burned": 300
}'go test ./...To create a new migration:
goose -dir migrations create migration_name sqlTo apply migrations:
goose -dir migrations postgres "user=workout_user password=workout_password dbname=workout_db sslmode=disable" up- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Martial Anouman - GitHub
Built with β€οΈ and Go