Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

43 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Task Tracker API

A Go REST API for personal task management with JWT authentication, PostgreSQL support, and an in-memory mode for fast local development.

This project is designed as a compact but production-minded backend service: layered architecture, migrations, middleware, rate limiting, metrics, structured logging, and automated tests.

Highlights

  • A complete backend service, not a single-file demo CRUD app.
  • Supports both memory and postgres storage modes.
  • Authentication uses JWT access and refresh tokens.
  • Passwords are hashed with bcrypt.
  • The login flow is protected with rate limiting by login + IP.
  • Application metrics are exposed via a dedicated endpoint restricted to localhost.
  • The codebase is split into clear layers: app, config, service, storage, transport, security, and metrics.
  • The repository includes SQL migrations and tests for HTTP handlers, middleware, and storage logic.

Features

  • User registration
  • User login with access_token and refresh_token
  • Access token validation
  • Access token refresh
  • Authenticated task CRUD
  • Task statuses: todo, in_progress, done
  • Built-in application metrics
  • Structured JSON logging via log/slog
  • Graceful HTTP server shutdown

Tech stack

  • Go 1.25.1
  • net/http
  • PostgreSQL
  • database/sql + pgx
  • JWT: github.com/golang-jwt/jwt/v5
  • Password hashing: golang.org/x/crypto/bcrypt
  • UUIDs: github.com/google/uuid

Architecture

cmd/auth                      entrypoint
internal/app                  application bootstrap and server startup
internal/config               environment-based configuration
internal/service              business logic
internal/storage              interfaces and in-memory storage
internal/storage/postgres     PostgreSQL storage implementations
internal/transport/http       handlers, middleware, response helpers
internal/security             rate limiter
internal/metrics              application counters
migrations                    SQL schema and data migrations

Configuration

The service reads environment variables and automatically loads .env if present.

Variable Required Default Description
PORT No :8081 HTTP listen address
JWT_SECRET Yes - JWT signing secret
LOG_LEVEL No info debug, info, warn, error
STORAGE No memory memory or postgres
DATABASE_URL For postgres - PostgreSQL connection string
ACCESS_TOKEN_TTL No 15m Access token TTL
REFRESH_TOKEN_TTL No 168h Refresh token TTL

Example .env:

PORT=8081
JWT_SECRET=super-secret-key
LOG_LEVEL=info
STORAGE=postgres
DATABASE_URL=postgres://postgres:postgres@localhost:5432/task_tracker?sslmode=disable
ACCESS_TOKEN_TTL=15m
REFRESH_TOKEN_TTL=168h

Quick start

Run with in-memory storage

export JWT_SECRET=super-secret-key
go run ./cmd/auth

The API will start on http://localhost:8081.

Run with PostgreSQL

  1. Create a PostgreSQL database.
  2. Apply the migrations from migrations/001_init.sql and migrations/002_migrate_tasks_user_login_to_user_id.sql.
  3. Start the service:
export JWT_SECRET=super-secret-key
export STORAGE=postgres
export DATABASE_URL=postgres://postgres:postgres@localhost:5432/task_tracker?sslmode=disable
go run ./cmd/auth

API overview

Auth endpoints

POST /register

{
  "login": "alice",
  "password": "strongpass123"
}

POST /login

{
  "login": "alice",
  "password": "strongpass123"
}

Response:

{
  "access_token": "jwt...",
  "refresh_token": "jwt..."
}

POST /validate

{
  "token": "jwt..."
}

POST /refresh

{
  "refresh_token": "jwt..."
}

Task endpoints

All task endpoints require:

Authorization: Bearer <access_token>

GET /tasks

POST /tasks

{
  "title": "Finish README",
  "description": "Rewrite project README for GitHub"
}

PUT /tasks/{id}

{
  "title": "Finish README v2",
  "description": "Make it portfolio-ready",
  "status": "in_progress"
}

DELETE /tasks/{id}

Metrics endpoint

GET /metrics

This endpoint is restricted to localhost and returns:

{
  "successful_logins": 1,
  "failed_logins": 0,
  "task_requests": 3,
  "errors_4xx": 0,
  "errors_5xx": 0
}

Example flow with curl

Register a user:

curl -X POST http://localhost:8081/register \
  -H "Content-Type: application/json" \
  -d '{"login":"alice","password":"strongpass123"}'

Login:

curl -X POST http://localhost:8081/login \
  -H "Content-Type: application/json" \
  -d '{"login":"alice","password":"strongpass123"}'

Create a task:

curl -X POST http://localhost:8081/tasks \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <access_token>" \
  -d '{"title":"Ship portfolio project","description":"Push project to GitHub"}'

Reliability and engineering details

  • Request bodies are size-limited
  • JSON decoding uses DisallowUnknownFields() for stricter validation
  • Passwords are never stored in plain text
  • HTTP status codes are mapped explicitly for common error cases
  • The service supports graceful shutdown
  • Metrics and structured logging are built in
  • PostgreSQL schema uses foreign keys, indexes, and status constraints

Possible next improvements

  • Docker and docker-compose for one-command local setup
  • OpenAPI / Swagger documentation
  • CI with go test, linting, and migration checks
  • Prometheus-compatible metrics
  • Refresh token rotation and revocation
  • Pagination, filtering, and sorting for tasks

Testing

go test ./...

Project status

This repository is in a good state to showcase backend engineering fundamentals on GitHub and in a resume. It can also serve as a base for a more production-like version with Docker, CI/CD, and API documentation.

About

Task management REST API in Go — JWT access/refresh auth, PostgreSQL, rate limiting, metrics, structured logging, and a swappable in-memory store for local runs.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages