Skip to content

martialanouman/go-workout-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

48 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Workout Tracking API

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.

Features

  • πŸ” 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

API Endpoints

Authentication

  • POST /api/tokens - Create authentication token (login)
  • POST /api/tokens/revoke-all - Revoke all tokens for authenticated user

Users

  • POST /api/users - Register new user

Workouts

  • GET /api/workouts - Get all workouts for authenticated user
  • GET /api/workouts/{id} - Get specific workout by ID
  • POST /api/workouts - Create new workout
  • PUT /api/workouts/{id} - Update existing workout
  • DELETE /api/workouts/{id} - Delete workout

Tech Stack

  • 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)

Project Structure

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

Getting Started

Prerequisites

  • Go 1.24.6 or later
  • Docker and Docker Compose
  • PostgreSQL 17 (if running without Docker)

Installation

  1. Clone the repository

    git clone https://github.com/martialanouman/go-workout-api.git
    cd go-workout-api
  2. Start the database with Docker Compose

    docker compose up -d db
  3. Install dependencies

    go mod download
  4. Set up environment variables

    The application requires a .env file for database configuration. Copy the example file and configure it:

    cp .env.example .env

    Edit the .env file 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.

  5. Run database migrations

    go run main.go migrate
  6. 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).

Running with Docker Compose

To run the entire application stack with Docker Compose:

  1. Set up environment variables (as described in step 4 above)
  2. Start all services:
docker compose up -d

This 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)

Configuration

The application uses the following default configuration:

  • Port: 8080 (configurable via -port flag)
  • Database: PostgreSQL connection via environment variables
  • Timeouts:
    • Idle: 1 minute
    • Read: 10 seconds
    • Write: 30 seconds

Database Schema

Users Table

  • id - Unique identifier
  • username - Unique username (50 chars max)
  • email - Unique email address
  • password_hash - Hashed password
  • bio - User biography
  • created_at, updated_at - Timestamps

Workouts Table

  • id - Unique identifier
  • user_id - Reference to users table
  • title - Workout title (100 chars max)
  • description - Workout description
  • duration_minutes - Workout duration
  • calories_burned - Calories burned during workout
  • created_at, updated_at - Timestamps

Tokens Table

  • Authentication tokens with expiration and user association

API Usage Examples

Register a User

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"
  }'

Login (Get Token)

curl -X POST http://localhost:8080/api/tokens \
  -H "Content-Type: application/json" \
  -d '{
    "email": "john@example.com",
    "password": "securepassword"
  }'

Create a Workout

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
  }'

Development

Running Tests

go test ./...

Database Migrations

To create a new migration:

goose -dir migrations create migration_name sql

To apply migrations:

goose -dir migrations postgres "user=workout_user password=workout_password dbname=workout_db sslmode=disable" up

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Author

Martial Anouman - GitHub


Built with ❀️ and Go

About

An API for handling workouts and their items made with Golang

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages