Skip to content

nanotaboada/go-samples-gin-restful

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

492 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

πŸ§ͺ RESTful API with Go and Gin

Go CI Go CD CodeQL Advanced Quality Gate Status codecov Go Report Card CodeFactor License: MIT Dependabot Copilot Claude CodeRabbit

Proof of Concept for a RESTful Web Service built with Gin and Go 1.25. This project demonstrates best practices for building a layered, testable, and maintainable API implementing CRUD operations for a Players resource (Argentina 2022 FIFA World Cup squad).

Features

  • πŸ—οΈ Layered Architecture - Idiomatic Go with interface-based contracts and constructor injection
  • πŸ“š Interactive Documentation - Auto-generated Swagger UI with VS Code and JetBrains REST Client support
  • ⚑ Performance Caching - In-memory response caching via gin-contrib/cache with GORM
  • 🚦 Comprehensive Testing - Full endpoint coverage with testify, race detector, and automated reporting to Codecov
  • 🐳 Containerized Deployment - Multi-stage Docker builds with migration-based database initialization
  • πŸ”„ Automated Pipeline - Continuous integration with race detector, Docker publishing, and GitHub releases

Tech Stack

Category Technology
Language Go 1.25
Web Framework Gin
ORM GORM
Database SQLite
Migrations goose
Caching gin-contrib/cache
API Documentation Swagger/OpenAPI
Testing testify
Containerization Docker & Docker Compose

Architecture

Layered architecture with dependency injection via constructors and interface-based contracts.

%%{init: {
  "theme": "default",
  "themeVariables": {
    "fontFamily": "Fira Code, Consolas, monospace",
    "textColor": "#555",
    "lineColor": "#555",
    "clusterBkg": "#f5f5f5",
    "clusterBorder": "#ddd"
  }
}}%%

graph RL

    %% Packages
    tests[tests]

    subgraph Layer 1[" "]
      main[main]
      docs[docs]
      swagger[swagger]
    end

    model[model]

    subgraph Layer 2[" "]
      route[route]
      controller[controller]
      gin[Gin]
    end

    subgraph Layer 3[" "]
      service[service]
    end

    subgraph Layer 4[" "]
      data[data]
      gorm[GORM]
    end

    %% Strong dependencies β€” functional/behavioral coupling
    controller --> main
    data --> main
    route --> main
    service --> main
    swagger --> main
    docs --> main
    gin --> route
    gin --> controller
    service --> controller
    gorm --> service
    gorm --> data

    %% Soft dependencies β€” structural/type coupling
    controller -.-> route
    model -.-> controller
    gorm -.-> controller
    model -.-> service
    model -.-> data
    main -.-> tests

    %% Node styling
    classDef core fill:#b3d9ff,stroke:#6db1ff,stroke-width:2px,color:#555,font-family:monospace;
    classDef support fill:#ffffcc,stroke:#fdce15,stroke-width:2px,color:#555,font-family:monospace;
    classDef deps fill:#ffcccc,stroke:#ff8f8f,stroke-width:2px,color:#555,font-family:monospace;
    classDef test fill:#ccffcc,stroke:#53c45e,stroke-width:2px,color:#555,font-family:monospace;

    class main,route,controller,service,data,model core
    class docs,swagger support
    class gin,gorm deps
    class tests test
Loading

Arrows follow the injection direction (A β†’ B means A is injected into B). Solid = runtime dependency, dotted = structural. Blue = core domain, yellow = support, red = third-party, green = tests.

Significant architectural decisions are documented in docs/adr/.

API Reference

Interactive API documentation is available via Swagger UI at http://localhost:9000/swagger/index.html when the server is running.

Method Endpoint Description Status
GET /players List all players 200 OK
GET /players/:id Get player by ID 200 OK
GET /players/squadnumber/:squadnumber Get player by squad number 200 OK
POST /players Create new player 201 Created
PUT /players/squadnumber/:squadnumber Update player by squad number 204 No Content
DELETE /players/squadnumber/:squadnumber Remove player by squad number 204 No Content
GET /health Health check 200 OK

Error codes: 400 Bad Request (validation failed) Β· 404 Not Found (player not found) Β· 409 Conflict (duplicate squad number on POST)

For complete endpoint documentation with request/response schemas, explore the interactive Swagger UI. You can also access the OpenAPI JSON specification at http://localhost:9000/swagger.json.

Alternatively, use rest/players.rest with the REST Client extension for VS Code, or the built-in HTTP Client in JetBrains IDEs (IntelliJ IDEA, GoLand, WebStorm).

Prerequisites

Before you begin, ensure you have the following installed:

  • Go 1.25 or higher
  • Docker & Docker Compose (optional, for containerized deployment)

Quick Start

Clone

git clone https://github.com/nanotaboada/go-samples-gin-restful.git
cd go-samples-gin-restful

Install

go mod download

Run

go run .

Access

Once the application is running, you can access:

  • API Server: http://localhost:9000
  • Swagger UI: http://localhost:9000/swagger/index.html
  • Health Check: http://localhost:9000/health

Containers

Build and Start

docker compose up

πŸ’‘ Note: On first run, the app applies all goose migrations (schema + seed data) to the persistent volume. On subsequent runs, already-applied migrations are skipped automatically.

Stop

docker compose down

Reset Database

To remove the volume and reinitialize the database from migrations:

docker compose down -v

Pull Docker Images

Each release publishes multiple tags for flexibility:

# By semantic version (recommended for production)
docker pull ghcr.io/nanotaboada/go-samples-gin-restful:1.0.0

# By player name (memorable alternative)
docker pull ghcr.io/nanotaboada/go-samples-gin-restful:ademir

# Latest release
docker pull ghcr.io/nanotaboada/go-samples-gin-restful:latest

Database Migrations

Schema and seed data are managed with goose and are embedded into the binary. Migrations run automatically on startup. To inspect or manage migrations manually:

# Check migration status
goose -dir migrations sqlite3 ./storage/players-sqlite3.db status

# Apply all pending migrations
goose -dir migrations sqlite3 ./storage/players-sqlite3.db up

# Roll back the most recent migration
goose -dir migrations sqlite3 ./storage/players-sqlite3.db down

Environment Variables

# Database storage path (default: ./storage/players-sqlite3.db)
STORAGE_PATH=./storage/players-sqlite3.db

# Gin framework mode: debug, release, or test (default: debug)
GIN_MODE=release

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for details on:

  • Code of Conduct
  • Development workflow and best practices
  • Commit message conventions (Conventional Commits)
  • Pull request process and requirements

Key guidelines:

  • Follow Conventional Commits for commit messages
  • Ensure all tests pass (go test ./...)
  • Run go fmt ./... before committing
  • Keep changes small and focused
  • Review .github/copilot-instructions.md for architectural patterns

Testing:

Run the test suite with testify:

# Run all tests
go test ./...

# Run tests with coverage
go test -v ./... \
  -coverpkg=github.com/nanotaboada/go-samples-gin-restful/service,github.com/nanotaboada/go-samples-gin-restful/controller,github.com/nanotaboada/go-samples-gin-restful/route \
  -covermode=atomic \
  -coverprofile=coverage.out

Command Summary

Command Description
go run . Start development server
go build Build the application
go test ./... Run all tests
go test -v ./... -covermode=atomic -coverprofile=coverage.out Run tests with coverage
go tool cover -html=coverage.out View coverage report
go fmt ./... Format code
go mod tidy Clean up dependencies
golangci-lint run Run linter
swag init Regenerate Swagger documentation
docker compose build Build Docker image
docker compose up Start Docker container
docker compose down Stop Docker container
docker compose down -v Stop and remove Docker volume
AI Commands
/pre-commit Runs linting, tests, and quality checks before committing
/pre-release Runs pre-release validation workflow

Legal

This project is provided for educational and demonstration purposes and may be used in production at your own discretion. All trademarks, service marks, product names, company names, and logos referenced herein are the property of their respective owners and are used solely for identification or illustrative purposes.