Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
G

go-clean-template

> 编程语言
Open source

Clean Architecture template for Golang services

7.6K stars0 likes0 views
WebsiteGitHub

About

Clean Architecture template for Golang services

Go Clean template

中文 RU

Clean Architecture template for Golang services

Overview

The purpose of the template is to show:

  • how to organize a project and prevent it from turning into spaghetti code
  • where to store business logic so that it remains independent, clean, and extensible
  • how not to lose control when a microservice grows

Using the principles of Robert Martin (aka Uncle Bob).

Go-clean-template is created & supported by Evrone.

This template implements four types of servers:

  • AMQP RPC (based on RabbitMQ as transport and Request-Reply pattern)
  • MQ RPC (based on NATS as transport and Request-Reply pattern)
  • gRPC (gRPC framework based on protobuf)
  • REST API (Fiber framework)

The template includes three domains to demonstrate multi-service architecture:

  • User Authentication — registration, login, JWT-based authorization
  • Task Management — CRUD operations with status transitions (todo, in_progress, done)
  • Translation — text translation with history tracking

All domains are available across all four transports (REST, gRPC, AMQP RPC, NATS RPC).

Content

  • Domains
  • Quick start
  • Observability
  • Project structure
  • Dependency Injection
  • Clean Architecture

Domains

The template includes three fully implemented domains, each available across all four transports (REST, gRPC, AMQP RPC, NATS RPC).

User Authentication

Registration, login, and JWT-based authorization.

Operation REST gRPC Register POST /v1/auth/register AuthService/Register Login POST /v1/auth/login AuthService/Login Get profile GET /v1/user/profile AuthService/GetProfile
  • Passwords hashed with bcrypt
  • JWT tokens with configurable expiry
  • Auth middleware on all transports

Task Management

CRUD operations with a status state machine.

Operation REST gRPC Create POST /v1/tasks TaskService/CreateTask List GET /v1/tasks TaskService/ListTasks Get GET /v1/tasks/:id TaskService/GetTask Update PUT /v1/tasks/:id TaskService/UpdateTask Transition PATCH /v1/tasks/:id/status TaskService/TransitionTask Delete DELETE /v1/tasks/:id TaskService/DeleteTask
  • Status transitions: todo → in_progress → done (and in_progress → todo)
  • Pagination with limit/offset and optional status filter
  • Tasks scoped to the authenticated user

Translation

Text translation via external API with history tracking.

Operation REST gRPC Translate POST /v1/translation/do-translate TranslationHistoryService/DoTranslate History GET /v1/translation/history TranslationHistoryService/ShowHistory

Quick start

Local development

# Postgres, RabbitMQ, NATS
make compose-up
# Run app with migrations
make run

Integration tests (can be run in CI)

# DB, app + migrations, integration tests
make compose-up-integration-test

Full docker stack with reverse proxy

make compose-up-all 

Check services:

  • AMQP RPC:
    • URL: amqp://guest:[email protected]:5672/
    • Client Exchange: rpc_client
    • Server Exchange: rpc_server
  • NATS RPC:
    • URL: nats://guest:[email protected]:4222/
    • Server Exchange: rpc_server
  • REST API:
    • http://app.lvh.me/healthz | http://127.0.0.1:8080/healthz
    • http://app.lvh.me/metrics | http://127.0.0.1:8080/metrics
    • http://app.lvh.me/swagger | http://127.0.0.1:8080/swagger
  • gRPC:
    • URL: tcp://grpc.lvh.me:8081 | tcp://127.0.0.1:8081
    • v1/auth.proto
    • v1/task.proto
    • v1/translation.history.proto
  • PostgreSQL:
    • postgres://user:myAwEsOm3pa55@[email protected]:5432/db
  • RabbitMQ:
    • http://rabbitmq.lvh.me | http://127.0.0.1:15672
    • Credentials: guest / guest
  • NATS monitoring:
    • http://nats.lvh.me | http://127.0.0.1:8222/
    • Credentials: guest / guest
  • Jaeger (traces UI):
    • http://jaeger.lvh.me | http://127.0.0.1:16686

Observability

Distributed tracing is provided by OpenTelemetry. Spans are exported over OTLP/gRPC to a collector — Jaeger in the docker stack.

  • Context propagation — W3C traceparent + baggage, so a single trace spans all four transports. REST uses the otelfiber middleware, gRPC uses the otelgrpc stats handler, and AMQP RPC / NATS RPC carry the trace context in message headers via custom carriers (pkg/rabbitmq/rmq_rpc/otel_carrier.go, pkg/nats/nats_rpc/otel_carrier.go).
  • Instrumented layers — use cases and repositories are wrapped in tracing decorators (*/tracing.go), so a trace shows the full path: controller → usecase → repo / webapi.
  • No-op when disabled — with TRACING_ENABLED=false a no-op tracer provider is installed, so instrumentation runs unconditionally with zero overhead.
  • Sampling — TRACING_SAMPLE_RATE is a parent-based ratio. Use 1.0 locally; lower it (0.1 / 0.01) in production.
  • Internal routes (/healthz, /metrics, /swagger) are excluded from tracing — only the versioned API groups are instrumented.

Configuration (see .env.example):

Variable Default Description TRACING_ENABLED false Enable OpenTelemetry tracing TRACING_OTLP_ENDPOINT localhost:4317 OTLP/gRPC collector endpoint TRACING_OTLP_INSECURE true Disable TLS for the OTLP exporter TRACING_SAMPLE_RATE 0.1 Parent-based sampling ratio

Project structure

cmd/app/main.go

Configuration and logger initialization. Then the main function "continues" in internal/app/app.go.

config

The twelve-factor app stores config in environment variables (often shortened to env vars or env). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard.

Config: config.go

Example: .env.example

docker-compose.yml uses env variables to configure services.

docs

Swagger documentation. Auto-generated by swag library. You don't need to correct anything by yourself.

docs/proto

Protobuf files. They are used to generate Go code for gRPC services. The proto files are also used to generate documentation for gRPC services. You don't need to correct anything by yourself.

integration-test

Integration tests. They are launched as a separate container, next to the application container.

internal/app

There is always one Run function in the app.go file, which "continues" the main function.

This is where all the main objects are created. Dependency injection occurs through the "New ..." constructors (see Dependency Injection). This technique allows us to layer the application using the Dependency Injection principle. This makes the business logic independent from other layers.

Next, we start the server and wait for signals in select for graceful completion. If app.go starts to grow, you can split it into multiple files.

For a large number of injections, wire can be used.

The migrate.go file is used for database auto migrations. It is included if an argument with the migrate tag is specified. For example:

go run -tags migrate ./cmd/app

internal/controller

Server handler layer (MVC controllers). The template shows 4 servers:

  • AMQP RPC (based on RabbitMQ as transport)
  • NATS RPC (based on NATS as transport)
  • gRPC (gRPC framework based on protobuf)
  • REST API (Fiber framework)

Server routers are written in the same style:

  • Handlers are grouped by area of application (by a common basis)
  • For each group, its own router structure is created, the methods of which process paths
  • The structure of the business logic is injected into the router structure, which will be called by the handlers

internal/controller/amqp_rpc

Simple RPC versioning. For v2, we will need to add the amqp_rpc/v2 folder with the same content. And in the file internal/controller/amqp_rpc/router.go add the line:

routes := make(map[string]server.CallHandler)

{
    v1.NewRoutes(routes, t, u, tk, j, l)
}

{
    v2.NewTranslationRoutes(routes, t, l)
}

internal/controller/grpc

Simple gRPC versioning. For v2, we will need to add the grpc/v2 folder with the same content. Also add the v2 folder to the proto files in docs/proto. And in the file internal/controller/grpc/router.go add the line:

{
    v1.NewAuthRoutes(app, u, l)
    v1.NewTaskRoutes(app, tk, l)
    v1.NewTranslationRoutes(app, t, l)
}

{
    v2.NewAuthRoutes(app, u, l)
    v2.NewTaskRoutes(app, tk, l)
    v2.NewTranslationRoutes(app, t, l)
}

reflection.Register(app)

internal/controller/nats_rpc

Simple RPC versioning. For v2, we will need to add the nats_rpc/v2 folder with the same content. And in the file internal/controller/nats_rpc/router.go add the line:

routes := make(map[string]server.CallHandler)

{
    v1.NewRoutes(routes, t, u, tk, j, l)
}

{
    v2.NewTranslationRoutes(routes, t, l)
}

internal/controller/restapi

Simple REST versioning. For v2, we will need to add the restapi/v2 folder with the same content. And in the file internal/controller/restapi/router.go add the line:

apiV1Group := app.Group("/v1")
{
	v1.NewRoutes(apiV1Group, t, u, tk, jwtManager, l)
}
apiV2Group := app.Group("/v2")
{
	v2.NewRoutes(apiV2Group, t, u, tk, jwtManager, l)
}

Instead of Fiber, you can use any other http framework.

In router.go and above the handler methods, there are comments for generating swagger documentation using swag.

internal/entity

Entities of business logic (models) can be used in any layer. There can also be methods, for example, for validation.

internal/usecase

Business logic.

  • Methods are grouped by area of application (on a common basis)
  • Each group has its own structure
  • One file - one structure

Repositories, webapi, rpc, and other business logic structures are injected into business l

GitHub Issues· 0 open

View all on GitHub

No open issues yet, or sync has not completed.

Highlights

  • •how to organize a project and prevent it from turning into spaghetti code
  • •where to store business logic so that it remains independent, clean, and extensible
  • •how not to lose control when a microservice grows
  • •AMQP RPC (based on RabbitMQ as transport
  • •MQ RPC (based on NATS as transport
  • •gRPC (gRPC framework based on protobuf)
  • •REST API (Fiber framework)
  • •User Authentication — registration, login, JWT-based authorization
  • •Task Management — CRUD operations with status transitions (todo, in_progress, done)
  • •Translation — text translation with history tracking

> Tags

Goclean-architecturedependency-injectionexamplego

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言