{"id":26281883,"url":"https://github.com/nanotaboada/go-samples-gin-restful","last_synced_at":"2026-02-06T06:11:58.375Z","repository":{"id":208331202,"uuid":"721357137","full_name":"nanotaboada/go-samples-gin-restful","owner":"nanotaboada","description":"🧪 Proof of Concept for a RESTful API built with Go and Gin","archived":false,"fork":false,"pushed_at":"2026-01-31T15:05:30.000Z","size":723,"stargazers_count":2,"open_issues_count":11,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-02-01T03:13:42.094Z","etag":null,"topics":["conventional-commits","docker","docker-compose","dockerfile","gin-tonic","github-actions","go","golang","gorm","integration-testing","proof-of-concept","rest-api","restful-api","samples","sqlite","vs-code"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nanotaboada.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-11-20T22:25:45.000Z","updated_at":"2026-01-31T15:05:33.000Z","dependencies_parsed_at":"2024-04-20T01:25:31.765Z","dependency_job_id":"56a69362-f2cb-4d47-8e60-a8099da83ecd","html_url":"https://github.com/nanotaboada/go-samples-gin-restful","commit_stats":null,"previous_names":["nanotaboada/go-samples-gin-restful"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/nanotaboada/go-samples-gin-restful","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nanotaboada%2Fgo-samples-gin-restful","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nanotaboada%2Fgo-samples-gin-restful/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nanotaboada%2Fgo-samples-gin-restful/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nanotaboada%2Fgo-samples-gin-restful/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nanotaboada","download_url":"https://codeload.github.com/nanotaboada/go-samples-gin-restful/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nanotaboada%2Fgo-samples-gin-restful/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29153318,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-06T02:39:25.012Z","status":"ssl_error","status_checked_at":"2026-02-06T02:37:22.784Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["conventional-commits","docker","docker-compose","dockerfile","gin-tonic","github-actions","go","golang","gorm","integration-testing","proof-of-concept","rest-api","restful-api","samples","sqlite","vs-code"],"created_at":"2025-03-14T16:15:47.907Z","updated_at":"2026-02-06T06:11:58.370Z","avatar_url":"https://github.com/nanotaboada.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🧪 RESTful API with Go and Gin\n\n[![Go CI](https://github.com/nanotaboada/go-samples-gin-restful/actions/workflows/go-ci.yml/badge.svg)](https://github.com/nanotaboada/go-samples-gin-restful/actions/workflows/go-ci.yml)\n[![Go CD](https://github.com/nanotaboada/go-samples-gin-restful/actions/workflows/go-cd.yml/badge.svg)](https://github.com/nanotaboada/go-samples-gin-restful/actions/workflows/go-cd.yml)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=nanotaboada_go-samples-gin-restful\u0026metric=alert_status)](https://sonarcloud.io/summary/new_code?id=nanotaboada_go-samples-gin-restful)\n[![codecov](https://codecov.io/gh/nanotaboada/go-samples-gin-restful/graph/badge.svg?token=i37VDcDWwx)](https://codecov.io/gh/nanotaboada/go-samples-gin-restful)\n[![Go Report Card](https://goreportcard.com/badge/github.com/nanotaboada/go-samples-gin-restful)](https://goreportcard.com/report/github.com/nanotaboada/go-samples-gin-restful)\n[![CodeFactor](https://www.codefactor.io/repository/github/nanotaboada/go-samples-gin-restful/badge)](https://www.codefactor.io/repository/github/nanotaboada/go-samples-gin-restful)\n[![License: MIT](https://img.shields.io/badge/License-MIT-white.svg)](https://opensource.org/licenses/MIT)\n\nProof of Concept for a RESTful API built with [Go](https://github.com/golang/go) and [Gin](https://github.com/gin-gonic/gin). Manage football player data with SQLite, GORM, Swagger documentation, and in-memory caching.\n\n## Table of Contents\n\n- [Features](#features)\n- [Tech Stack](#tech-stack)\n- [Project Structure](#project-structure)\n- [Architecture](#architecture)\n- [API Reference](#api-reference)\n- [Prerequisites](#prerequisites)\n- [Quick Start](#quick-start)\n- [Testing](#testing)\n- [Docker](#docker)\n- [Releases](#releases)\n- [Environment Variables](#environment-variables)\n- [Command Summary](#command-summary)\n- [Contributing](#contributing)\n- [Legal](#legal)\n\n## Features\n\n- 🔌 **RESTful CRUD operations** for football player data\n- 📚 **Interactive API documentation** with Swagger UI and Postman collection\n- 🩺 **Health check endpoint** for monitoring\n- ⚡ **In-memory caching** (1-hour TTL)\n- 💿 **Relational database with ORM**\n- ✅ **Comprehensive integration tests**\n- 🐳 **Full containerization support**\n- 🔄 **CI/CD pipeline** with automated testing and deployment\n\n## Tech Stack\n\n| Category | Technology |\n| -------- | ---------- |\n| **Language** | [Go 1.25](https://github.com/golang/go) |\n| **Web Framework** | [Gin](https://github.com/gin-gonic/gin) |\n| **ORM** | [GORM](https://github.com/go-gorm/gorm) |\n| **Database** | [SQLite](https://github.com/sqlite/sqlite) |\n| **Caching** | [gin-contrib/cache](https://github.com/gin-contrib/cache) |\n| **API Documentation** | [Swagger/OpenAPI](https://github.com/swaggo/swag) |\n| **Testing** | [testify](https://github.com/stretchr/testify) |\n| **Containerization** | [Docker](https://github.com/docker) \u0026 [Docker Compose](https://github.com/docker/compose) |\n\n## Project Structure\n\n```tree\n/\n├── main.go                 # Entry point: DB connection, route setup, server start\n├── controller/             # HTTP handlers (request/response logic)\n│   └── player_controller.go\n├── service/                # Business logic (ORM interactions)\n│   └── player_service.go\n├── route/                  # Route configuration and middleware\n│   ├── player_route.go     # Route setup with caching middleware\n│   └── path.go             # Path constants\n├── model/                  # Data structures\n│   └── player_model.go\n├── data/                   # Database connection\n│   └── player_data.go\n├── swagger/                # Swagger configuration\n│   └── swagger.go\n├── docs/                   # Auto-generated Swagger docs (DO NOT EDIT)\n│   ├── docs.go\n│   ├── swagger.json\n│   └── swagger.yaml\n├── tests/                  # Integration tests\n│   ├── main_test.go\n│   ├── player_fake.go\n│   └── players.json\n├── storage/                # SQLite database file (pre-seeded)\n├── scripts/                # Container entrypoint \u0026 healthcheck\n└── .github/workflows/      # CI/CD pipelines\n```\n\n## Architecture\n\n```mermaid\n%%{init: {\n  \"theme\": \"default\",\n  \"themeVariables\": {\n    \"fontFamily\": \"Fira Code, Consolas, monospace\",\n    \"textColor\": \"#555\",\n    \"lineColor\": \"#555\",\n    \"lineWidth\": 2\n  }\n}}%%\n\ngraph LR\n    %% Core application packages\n    main[main]\n    route[route]\n    controller[controller]\n    service[service]\n    data[data]\n    model[model]\n\n    %% Supporting features\n    docs[docs]\n    swagger[swagger]\n\n    %% External dependencies\n    gin[Gin]\n    gorm[GORM]\n\n    %% Test coverage\n    tests[tests]\n\n    %% Module dependencies (solid arrows = imports)\n    main --\u003e data\n    main --\u003e service\n    main --\u003e controller\n    main --\u003e route\n    main --\u003e swagger\n    main --\u003e docs\n    route --\u003e controller\n    controller --\u003e service\n    service --\u003e data\n    data --\u003e model\n    data --\u003e gorm\n    route --\u003e gin\n    tests --\u003e main\n\n    %% Runtime composition (dotted arrows = main creates/wires)\n    main -.-\u003e gin\n    main -.-\u003e service\n    main -.-\u003e controller\n\n    %% Node styling\n    classDef core fill:#b3d9ff,stroke:#6db1ff,stroke-width:2px,color:#555,font-family:monospace;\n    classDef support fill:#ffffcc,stroke:#fdce15,stroke-width:2px,color:#555,font-family:monospace;\n    classDef deps fill:#ffcccc,stroke:#ff8f8f,stroke-width:2px,color:#555,font-family:monospace;\n    classDef test fill:#ccffcc,stroke:#53c45e,stroke-width:2px,color:#555,font-family:monospace;\n\n    class main,route,controller,service,data,model core\n    class docs,swagger support\n    class gin,gorm deps\n    class tests test\n```\n\n**Arrow Semantics:**\n\n- **Solid arrows** represent compile-time module dependencies (imports). For example, `controller → service` means the controller package imports and uses the service package.\n- **Dotted arrows** represent runtime composition. The `main` package creates instances (database connection, service, controller, Gin router) and wires them together at startup.\n\n**Composition Root Pattern:** The `main` package acts as the composition root, creating all dependencies and the Gin router instance. It registers player routes through the `route` package and adds Swagger/health routes directly. This pattern enables dependency injection, improves testability, and maintains clear separation of concerns.\n\n**Layered Architecture:** HTTP requests flow through distinct layers: `route` → `controller` → `service` → `data` → `model`. Each layer has a specific responsibility - routes handle HTTP mapping, controllers manage request/response, services contain business logic, data handles persistence, and models define data structures.\n\n**Color Coding:** Core packages (blue) implement the application logic, supporting features (yellow) provide documentation and utilities, external dependencies (red) are third-party frameworks and ORMs, and tests (green) ensure code quality.\n\n## API Reference\n\nInteractive API documentation is available via Swagger UI at `http://localhost:9000/swagger/index.html` when the server is running.\n\n\u003e 💡 **Note:** The Swagger documentation is automatically generated from code annotations using [swaggo/swag](https://github.com/swaggo/swag). To regenerate after making changes, run `swag init`.\n\n### Request Flow\n\n```mermaid\n%%{init: {\n  \"theme\": \"default\",\n  \"themeVariables\": {\n    \"fontFamily\": \"Fira Code, Consolas, monospace\",\n    \"textColor\": \"#555\",\n    \"lineColor\": \"#555\",\n    \"lineWidth\": 2\n  }\n}}%%\n\ngraph LR\n    %% HTTP Request Flow\n    Client[Client] --\u003e|\"HTTP Request\"| Route[route]\n    Route --\u003e Controller[controller]\n    Controller --\u003e Service[service]\n    Service --\u003e Data[data]\n    Data --\u003e DB[(SQLite)]\n\n    %% Response Flow\n    DB --\u003e Data\n    Data --\u003e Service\n    Service --\u003e Controller\n    Controller --\u003e Route\n    Route --\u003e|\"HTTP Response\"| Client\n\n    %% Middleware\n    Route -.-\u003e|\"cache check\"| Cache[(In-Memory\u003cbr/\u003eCache)]\n    Cache -.-\u003e|\"cached response\"| Route\n\n    %% Node styling\n    classDef core fill:#e6ccff,stroke:#9966ff,stroke-width:2px,color:#555,font-family:monospace;\n    classDef client fill:#ffe6cc,stroke:#ff9933,stroke-width:2px,color:#555,font-family:monospace;\n    classDef storage fill:#f5f5f5,stroke:#cccccc,stroke-width:2px,color:#555,font-family:monospace;\n\n    class Route,Controller,Service,Data core\n    class Client client\n    class DB,Cache storage\n```\n\nHTTP request-response cycle: Client → Route → Controller → Service → Data → Database. Responses flow back through the same layers. GET requests are cached for 1 hour to improve performance.\n\n**Quick Reference:**\n\n- `GET /players` - List all players\n- `GET /players/:id` - Get player by ID\n- `GET /players/squadnumber/:squadnumber` - Get player by squad number\n- `POST /players` - Create new player\n- `PUT /players/:id` - Update player\n- `DELETE /players/:id` - Remove player\n- `GET /health` - Health check\n\nFor complete endpoint documentation with request/response schemas, explore the [interactive Swagger UI](http://localhost:9000/swagger/index.html). You can also access the OpenAPI JSON specification at `http://localhost:9000/swagger.json`.\n\n### Postman Collection\n\nA pre-configured Postman collection is available at [`postman-collections/go-samples-gin-restful.postman_collection.json`](postman-collections/go-samples-gin-restful.postman_collection.json).\n\n## Prerequisites\n\nBefore you begin, ensure you have the following installed:\n\n- **Go 1.25 or higher**\n- **Docker \u0026 Docker Compose** (optional, for containerized deployment)\n\n## Quick Start\n\n### Clone the repository\n\n```bash\ngit clone https://github.com/nanotaboada/go-samples-gin-restful.git\ncd go-samples-gin-restful\n```\n\n### Install dependencies\n\n```bash\ngo mod download\n```\n\n### Start the development server\n\n```bash\ngo run .\n```\n\nThe server will start on `http://localhost:9000`.\n\n### Access the application\n\n- **API:** `http://localhost:9000`\n- **Swagger Documentation:** `http://localhost:9000/swagger/index.html`\n- **Health Check:** `http://localhost:9000/health`\n\n## Testing\n\nRun the test suite with coverage:\n\n```bash\n# Run all tests\ngo test ./...\n\n# Run tests with coverage\ngo test -v ./... -coverprofile=coverage.out\n\n# Run tests with detailed coverage for specific packages\ngo test -v ./... \\\n  -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 \\\n  -covermode=atomic \\\n  -coverprofile=coverage.out\n\n# View coverage report\ngo tool cover -html=coverage.out\n```\n\nTests are located in the `tests/` directory and use testify for integration testing. Coverage reports are generated for controllers, services, and routes only.\n\n**Coverage targets:** 80% minimum for service, controller, and route packages.\n\n## Docker\n\nThis project includes full Docker support with multi-stage builds and Docker Compose for easy deployment.\n\n### Build the Docker image\n\n```bash\ndocker compose build\n```\n\n### Start the application\n\n```bash\ndocker compose up\n```\n\n\u003e 💡 **Note:** On first run, the container copies a pre-seeded SQLite database into a persistent volume. On subsequent runs, that volume is reused and the data is preserved.\n\n### Stop the application\n\n```bash\ndocker compose down\n```\n\n### Reset the database\n\nTo remove the volume and reinitialize the database from the built-in seed file:\n\n```bash\ndocker compose down -v\n```\n\nThe containerized application runs on port 9000 and includes health checks that monitor the `/health` endpoint every 30 seconds.\n\n## Releases\n\nThis project uses famous football players as release codenames 🎖️, inspired by Ubuntu, Android, and macOS naming conventions.\n\n### Release Naming Convention\n\nReleases follow the pattern: `v{SEMVER}-{PLAYER}` (e.g., `v1.0.0-ademir`)\n\n- **Semantic Version**: Standard versioning (MAJOR.MINOR.PATCH)\n- **Player Name**: Alphabetically ordered codename from the [famous player list](CHANGELOG.md#famous-football-player-names-️)\n\n### Create a Release\n\nTo create a new release, tag a commit and push the tag:\n\n```bash\ngit tag -a v1.0.0-ademir -m \"Release 1.0.0 - Ademir\"\ngit push origin v1.0.0-ademir\n```\n\nThis triggers the CD workflow which automatically:\n\n1. Builds and tests the project with race detector\n2. Publishes Docker images to GitHub Container Registry with three tags\n3. Creates a GitHub Release with auto-generated changelog\n\n### Pull Docker Images\n\nEach release publishes multiple tags for flexibility:\n\n```bash\n# By semantic version (recommended for production)\ndocker pull ghcr.io/nanotaboada/go-samples-gin-restful:1.0.0\n\n# By player name (memorable alternative)\ndocker pull ghcr.io/nanotaboada/go-samples-gin-restful:ademir\n\n# Latest release\ndocker pull ghcr.io/nanotaboada/go-samples-gin-restful:latest\n```\n\n\u003e 💡 **Note:** See [CHANGELOG.md](CHANGELOG.md) for the complete player list (A-Z) and release history.\n\n## Environment Variables\n\nThe application can be configured using the following environment variables (declared in [`compose.yaml`](https://github.com/nanotaboada/go-samples-gin-restful/blob/master/compose.yaml)):\n\n```bash\n# Database storage path (default: ./storage/players-sqlite3.db)\n# In Docker: /storage/players-sqlite3.db\nSTORAGE_PATH=./storage/players-sqlite3.db\n\n# Gin framework mode: debug, release, or test (default: debug)\n# In Docker: release\nGIN_MODE=release\n```\n\n## Command Summary\n\n| Command | Description |\n| ------- | ----------- |\n| `go run .` | Start development server |\n| `go build` | Build the application |\n| `go test ./...` | Run all tests |\n| `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` | Run tests with coverage |\n| `go tool cover -html=coverage.out` | View coverage report |\n| `go fmt ./...` | Format code |\n| `go mod tidy` | Clean up dependencies |\n| `swag init` | Regenerate Swagger documentation |\n| `docker compose build` | Build Docker image |\n| `docker compose up` | Start Docker container |\n| `docker compose down` | Stop Docker container |\n| `docker compose down -v` | Stop and remove Docker volume |\n\n## Contributing\n\nContributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on the code of conduct and the process for submitting pull requests.\n\n**Key guidelines:**\n\n- Follow [Conventional Commits](https://www.conventionalcommits.org/) for commit messages\n- Ensure all tests pass (`go test ./...`)\n- Run `go fmt` before committing\n- Keep changes small and focused\n\n## Legal\n\nThis project is provided for educational and demonstration purposes and may be used in production environments at your discretion. All referenced trademarks, service marks, product names, company names, and logos are the property of their respective owners and are used solely for identification or illustrative purposes.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnanotaboada%2Fgo-samples-gin-restful","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnanotaboada%2Fgo-samples-gin-restful","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnanotaboada%2Fgo-samples-gin-restful/lists"}