{"id":40849756,"url":"https://github.com/sergicanet9/go-hexagonal-api","last_synced_at":"2026-01-21T23:32:28.783Z","repository":{"id":41309499,"uuid":"380475969","full_name":"sergicanet9/go-hexagonal-api","owner":"sergicanet9","description":"A robust gRPC + REST API for user management built with Go and implementing the Hexagonal Architecture (Ports \u0026 Adapters) pattern, built on top of the scv-go-tools library.","archived":false,"fork":false,"pushed_at":"2025-12-02T15:05:35.000Z","size":10775,"stargazers_count":13,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-12-05T13:21:44.470Z","etag":null,"topics":["docker","go","grpc","grpc-gateway","hexagonal-architecture","kubernetes","mongodb","observability","postgresql","restapi"],"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/sergicanet9.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"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":"2021-06-26T10:34:38.000Z","updated_at":"2025-12-02T15:05:40.000Z","dependencies_parsed_at":"2024-06-20T16:19:37.618Z","dependency_job_id":"12cbcf35-e110-4ccf-b941-00149918da8f","html_url":"https://github.com/sergicanet9/go-hexagonal-api","commit_stats":null,"previous_names":["sergicanet9/go-mongo-restapi","scanet9/go-mongo-restapi"],"tags_count":95,"template":false,"template_full_name":null,"purl":"pkg:github/sergicanet9/go-hexagonal-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergicanet9%2Fgo-hexagonal-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergicanet9%2Fgo-hexagonal-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergicanet9%2Fgo-hexagonal-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergicanet9%2Fgo-hexagonal-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sergicanet9","download_url":"https://codeload.github.com/sergicanet9/go-hexagonal-api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergicanet9%2Fgo-hexagonal-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28646948,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T21:29:11.980Z","status":"ssl_error","status_checked_at":"2026-01-21T21:24:31.872Z","response_time":86,"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":["docker","go","grpc","grpc-gateway","hexagonal-architecture","kubernetes","mongodb","observability","postgresql","restapi"],"created_at":"2026-01-21T23:32:28.712Z","updated_at":"2026-01-21T23:32:28.766Z","avatar_url":"https://github.com/sergicanet9.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# go-hexagonal-api\n![CI](https://github.com/sergicanet9/go-hexagonal-api/actions/workflows/ci.yml/badge.svg)\n![CD](https://github.com/sergicanet9/go-hexagonal-api/actions/workflows/cd.yml/badge.svg)\n![Coverage](https://img.shields.io/badge/Coverage-73.5%25-brightgreen)\n[![Go Reference](https://pkg.go.dev/badge/github.com/sergicanet9/go-hexagonal-api.svg)](https://pkg.go.dev/github.com/sergicanet9/go-hexagonal-api)\n\nA robust gRPC + REST API for user management built with **Go** and implementing the **Hexagonal Architecture** (Ports \u0026 Adapters) pattern, built on top of the [scv-go-tools](https://github.com/sergicanet9/scv-go-tools) library.\n\u003cbr /\u003e\nThe gRPC handlers are automatically exposed as REST endpoints, so the same functionality is available over HTTP without duplicating code.\n\u003cbr /\u003e\nThe API is designed to work seamlessly with either a MongoDB or PostgreSQL database instance, using the same business logic and handlers.\n\n## 🚀 Features\n- **Hexagonal Architecture**: Clear separation of concerns with transport, business logic and repository layers.\n- **gRPC + gRPC-Gateway**: gRPC API implementation, with automatically generated REST endpoints from the gRPC handlers via gRPC-Gateway.\n- **Database Agnostic**: Decoupled repository adapters allow injecting a MongoDB or PostgreSQL storage without changing core logic.\n- **Authentication \u0026 Authorization**: Implements JWT authentication and claim-based authorization for secure endpoints.\n- **Asynchronous Processes**: Go routines management with built in processes for periodically health checking connectivity with the HTTP and gRPC servers.\n- **Testing**: Comprehensive unit tests with code coverage and integration tests for the happy path.\n- **Developer Experience**: Built-in Makefile, Swagger UI, gRPC UI, pgAdmin, and mongo-express.\n- **Lifecycle Management**: Multi-environment support with config files, Dockerfile and docker compose, CI/CD pipelines, Kubernetes deployment and New Relic observability.\n\n## 🏁 Getting Started\n### Run it with Docker\nTo start the entire application stack using Docker Compose, run:\n```\nmake up\n```\nThis command launches six containers:\n* Two databases (MongoDB and PostgreSQL).\n* Two database UIs (mongo-express and pgAdmin).\n* Two API instances, one for each database.\n\nCheck the console output for Swagger UI, gRPC UI, database UIs, and HTTP and gRPC command examples.\n\nTo stop and remove all containers, run:\n```\nmake down\n```\n\n### Run it with command line\nRun a single API instance with command-line arguments with the following command:\n```\n    go run cmd/main.go --ver={version} --env={environment} --hport={http_port} --gport={grpc_port} --db={database} --dsn={dsn} --jsecret={jwt_secret} --nrkey={newrelic_key}\n```\nor:\n```\ngo build cmd/main.go\n ./main --ver={version} --env={environment} --hport={http_port} --gport={grpc_port} --db={database} --dsn={dsn} --jsecret={jwt_secret} --nrkey={newrelic_key}\n```\nProvide the desired values for: `{version}`, `{environment}`, `{http_port}`, `{grpc_port}`, `{database}`, `{dsn}`, `{jwt_secret}`.\n\u003cbr /\u003e\nThe `--nrkey` flag and its value `{newrelic_key}` are optional and can be omitted if you do not want to configure New Relic observability.\n\u003cbr /\u003e\nThen open:\n* Swagger UI: `http://localhost:{http_port}/v1/swagger/index.html`\n* gRPC UI: `http://localhost:{http_port}/v1/grpcui/`\n\u003cbr /\u003e\n\nNOTES:\n- The target database container needs to be up and running (run `make up`).\n\n### Debug it with VS Code\nThe project includes debugging profiles in [launch.json](https://github.com/sergicanet9/go-hexagonal-api/blob/main/.vscode/launch.json) for both MongoDB and PostgreSQL setups. Simply select the desired configuration in the VS Code debugger and run it.\n\u003cbr /\u003e\nThen open:\n* Swagger UI: `http://localhost:{http_port}/v1/swagger/index.html`\n* gRPC UI: `http://localhost:{http_port}/v1/grpcui/`\n\u003cbr /\u003e\n\nNOTES:\n- The target database container needs to be up and running (run `make up`).\n\n## 📦 API Endpoints\n### Public Routes\nThese endpoints do not require authentication.\n\n| HTTP Endpoint         | gRPC Method                         | Description                                   |\n| :-------------------- | :---------------------------------- | :-------------------------------------------- |\n| GET `/v1/health`      | `health.HealthService.HealthCheck`  | Performs a health check.                      |\n| POST `/v1/users`      | `user.UserService.Create`           | Creates a new user.                           |\n| POST `/v1/users/many` | `user.UserService.CreateMany`       | Creates multiple users.                       |\n| POST `/v1/users/login`| `user.UserService.Login`            | Authenticates a user and returns a JWT token. |\n\n### Protected Routes\nThese endpoints require a valid JWT in the Authorization header, formatted as `Bearer {token}`.\n* For HTTP, include it as `Authorization` header.\n* For gRPC, include it in the metadata with the key `authorization`.\n\n| HTTP Endpoint                  | gRPC Method                    | Description                   |\n| :----------------------------- | :----------------------------- | :---------------------------- |\n| GET `/v1/users`                | `user.UserService.GetAll`      | Retrieves all users.          |\n| GET `/v1/users/email/{email}`  | `user.UserService.GetByEmail`  | Retrieves a user by email.    |\n| GET `/v1/users/{id}`           | `user.UserService.GetByID`     | Retrieves a user by ID.       |\n| PATCH `/v1/users/{id}`         | `user.UserService.Update`      | Updates a user's information. |\n| GET `/v1/claims`               | `user.UserService.GetClaims`   | Returns all claims.           |\n\n### Admin Routes\nThese endpoints require a valid JWT, formatted as `Bearer {token}` and containing the `admin` claim.\n* For HTTP, include it as `Authorization` header.\n* For gRPC, include it in the metadata with the key `authorization`.\n\n| HTTP Endpoint           | gRPC Method                | Description           |\n| :---------------------- | :------------------------- | :-------------------- |\n| DELETE `/v1/users/{id}` | `user.UserService.Delete`  | Deletes a user by ID. |\n\n## ✅ Testing\n### Run unit tests with code coverage\n```\nmake test-unit\n```\n\n### View coverage report\n```\nmake cover\n```\n\n### Run integration tests\n```\nmake test-integration\n```\n\u003cbr /\u003e\n\n NOTES:\n- Docker is required for running integration tests.\n\n## 🛠️ Developer Commands \n### (Re)Generate gRPC stubs and Swagger documentation\n```\nmake swagger\n```\n### (Re)Generate Mockery mocks\n```\nmake mocks\n```\n\n### Create a new PostgreSQL migration\n```\nmake goose\n```\nWrite the file name without \".sql\" suffix and press enter.\nThen edit the newly created file to define the behavior of the migration.\n\n### Connect to pgAdmin\nOpen the pgAdmin URL printed after running `make up`.\n\u003cbr /\u003e\nLog in with the email and password specified as `PGADMIN_LOGIN_EMAIL` and `PGADMIN_LOGIN_PASSOWRD` in the [.env](https://github.com/sergicanet9/go-hexagonal-api/blob/main/.env) file.\n\u003cbr /\u003e\nWhen prompted for the database user password, use the value of `POSTGRES_PASSWORD` from the same file.\n\n### Connect to mongo-express\nOpen the mongo-express URL printed after running `make up`.\n\u003cbr /\u003e\nLog in with the username and password specified as `MONGO_EXPRESS_LOGIN_USERNAME`and `MONGO_EXPRESS_LOGIN_PASSWORD`in the [.env](https://github.com/sergicanet9/go-hexagonal-api/blob/main/.env) file.\n\n## 📤 Github Actions\nThe following GitHub Actions workflows are included for Continuous Integration and Continuous Deployment (CI/CD):\n* [ci.yml](https://github.com/sergicanet9/go-hexagonal-api/blob/main/.github/workflows/ci.yml): Runs on every push to the main branch. It executes unit tests and integration tests to ensure code quality and stability before deploying.\n* [cd.yml](https://github.com/sergicanet9/go-hexagonal-api/blob/main/.github/workflows/cd.yml): Triggered when a Git tag is pushed. It performs the following steps:\n  1. Runs all the tests to validate the codebase.\n  2. Builds, validates and pushes protobuf schemas to the [Buf Schema Registry (BSR)](https://buf.build/sergicanet9/go-hexagonal-api-v1).\n  3. Builds and publishes the API Docker image to the [GitHub Container Registry (GHCR)](https://github.com/sergicanet9/go-hexagonal-api/pkgs/container/go-hexagonal-api%2Fgo-hexagonal-api).\n  4. Deploys the application to Kubernetes using the appropriate secrets and configs.\n  5. Exposes the API to the internet through a tunnel.\n* [gcp-infrastructure.yml](https://github.com/sergicanet9/go-hexagonal-api/blob/main/.github/workflows/gcp-infrastructure.yml): Manually triggered. It allows creating and deleting the GKE cluster required for deploying the application.\n\n## ☁️ Live Environment\n⚠️ **Cluster may be turned off:** To save costs, the cluster is usually deleted after use via the [gcp-infrastructure.yml](https://github.com/sergicanet9/go-hexagonal-api/blob/main/.github/workflows/gcp-infrastructure.yml) action.\n\u003cbr /\u003e\n\u003cbr /\u003e\nThe API gets deployed on a Google Kubernetes Engine (GKE) cluster, using Mongo Atlas as database, New Relic Go agent for APM and log forwarding, and a Cloudflare tunnel for public access through HTTP.\u003cbr/\u003e\n* Swagger UI: https://mongo-prod-go-hexagonal-api.sergicanet.com/v1/swagger/index.html\n* gRPC UI: https://mongo-prod-go-hexagonal-api.sergicanet.com/v1/grpcui/\n\u003cbr /\u003e\n\nNOTES:\n- The gRPC UI gets publically exposed through HTTP. However, direct gRPC calls (e.g., using `grpcurl`) are not allowed outside the cluster.\n\n## 📝 Other usage examples\nCheck out [go-microservices-demo](https://github.com/sergicanet9/go-microservices-demo) to see this project used as a component in a microservices architecture.\n\n## ✍️ Author\nSergi Canet Vela\n\n## ⚖️ License\nThis project is licensed under the terms of the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsergicanet9%2Fgo-hexagonal-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsergicanet9%2Fgo-hexagonal-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsergicanet9%2Fgo-hexagonal-api/lists"}