Go (Golang) Clean Architecture based on Reading Uncle Bob's Clean Architecture

Overview

go-clean-arch

Changelog

Description

This is an example of implementation of Clean Architecture in Go (Golang) projects.

Rule of Clean Architecture by Uncle Bob

  • Independent of Frameworks. The architecture does not depend on the existence of some library of feature laden software. This allows you to use such frameworks as tools, rather than having to cram your system into their limited constraints.
  • Testable. The business rules can be tested without the UI, Database, Web Server, or any other external element.
  • Independent of UI. The UI can change easily, without changing the rest of the system. A Web UI could be replaced with a console UI, for example, without changing the business rules.
  • Independent of Database. You can swap out Oracle or SQL Server, for Mongo, BigTable, CouchDB, or something else. Your business rules are not bound to the database.
  • Independent of any external agency. In fact your business rules simply don’t know anything at all about the outside world.

More at https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html

This project has 4 Domain layer :

  • Models Layer
  • Repository Layer
  • Usecase Layer
  • Delivery Layer

The diagram:

golang clean architecture

The original explanation about this project's structure can read from this medium's post : https://medium.com/@imantumorang/golang-clean-archithecture-efd6d7c43047.

It may different already, but the concept still the same in application level, also you can see the change log from v1 to current version in Master.

How To Run This Project

Make Sure you have run the article.sql in your mysql

Since the project already use Go Module, I recommend to put the source code in any folder but GOPATH.

Run the Testing

$ make test

Run the Applications

Here is the steps to run it with docker-compose

#move to directory
$ cd workspace

# Clone into YOUR $GOPATH/src
$ git clone https://github.com/bxcodec/go-clean-arch.git

#move to project
$ cd go-clean-arch

# Build the docker image first
$ make docker

# Run the application
$ make run

# check if the containers are running
$ docker ps

# Execute the call
$ curl localhost:9090/articles

# Stop
$ make stop

Tools Used:

In this project, I use some tools listed below. But you can use any simmilar library that have the same purposes. But, well, different library will have different implementation type. Just be creative and use anything that you really need.

Comments
  • Directory Setup Questions

    Directory Setup Questions

    Thank you for the article about clean architecture in Go! :)

    I had a question about how you set up the packages (directories) in your project:

    Question 1 Was there a specific reason that each repository, usecase, and delivery file was packaged under one directory that matched the model name? Why weren't all the repositories under the same directory and the usecases and delivery files the same? (e.g. go-clean-arch/repositories, go-clean-arch/usecases, go-clean-arch/delivery)

    Question 2 Also, why are the models not in the same packages as the repository, usecase, and delivery files?

    Example: The repository interface/implementation, delivery, and use-case files for "author” were under go-clean-arch/author, but the author model was in the go-clean-arch/models directory.

    NOTE: I'm currently trying to clean up my teams Golang project repo and ensure it's scalable for future development, so I'm wondering if the way you set up this repo had a particular reason. :)

    opened by danrix89 5
  • feat: Introduce domain package

    feat: Introduce domain package

    Hello, everyone who reads this and (maybe who also used my proposed architecture in Go).

    Thank you very much for the feedback that I received so far. Just to be honest, I'm very new here in the architecting software worlds. So, I'd rather call it folder structure rather than architecture. As we know, software architecture is not just a single application, but a whole business that architected into one or many applications.

    Actually, for the current version in the master branch (when I made this PR), nothing wrongs. By far, this project structure solved many cases of my projects.

    But, in this recent months, I try several improvements (also with looking at other people's architecture in Go), so now I decide to introduce a domain package.

    In my current structure, we will find something like this:

    models
    ├── article.go
    ├── author.go
    └── errors.go 
    
    article
    ├── delivery
    │   └── http
    │       ├── article_handler.go
    │       └── article_test.go
    ├── mocks
    │   ├── ArticleRepository.go
    │   └── ArticleUsecase.go
    ├── repository //Encapsulated Implementation of Repository Interface
    │   ├── mysql_article.go
    │   └── mysqlarticle_test.go
    ├── repository.go // Repository Interface
    ├── usecase //Encapsulated Implementation of Usecase Interface
    │   ├── articleucase_test.go
    │   └── artilce_ucase.go
    └── usecase.go // Usecase Interface.
    

    So there are will be many packaged module like author, article that contains the implementation and also the contract ArticleUsecase, ArticleRepository, AuthorRepository

    So, just out of curiosity, I tried a new improvement that proposed by Ben Johnson here: https://medium.com/@benbjohnson/standard-package-layout-7cdbc8391fc1 the domain package. But instead of to move it into the root project, I'd rather move it into a single domain, just for the sake consistency with my previous layout that using package models

    So in my previous layout, I used models and now I renamed it to domain then move all the interface contract (Usecase and Repository) into this domain package.

    So it will be more like this:

    domain
    ├── mocks
    │   ├── ArticleRepository.go
    │   ├── AuthorRepository.go
    │   └── ArticleUsecase.go
    ├── article.go
    ├── author.go
    └── errors.go 
    
    article
    ├── delivery
    │   └── http
    │       ├── article_handler.go
    │       └── article_test.go
    ├── repository //Encapsulated Implementation of Repository Interface
    │   └── mysql
    │       ├── mysql_article.go
    │       └── mysqlarticle_test.go
    └── usecase //Encapsulated Implementation of Usecase Interface
        ├── articleucase_test.go
        └── artilce_ucase.go
    

    I don't know yet, is this new layout better than the current layout I used. But, I'll try to use this new layout for my projects. If anything happens, then, this PR will be closed. But if it's good and more comfortable for the developer to use it, then I'll merge this to the branch master. :D


    Anyway, if you're a Golang Engineer too, I'd like to hear your opinion about this new proposed layout :D

    opened by bxcodec 5
  • More than one repository files?

    More than one repository files?

    Hi @bxcodec , thank you for creating this arch. I have a question, should I create multiple repository files to handle multiple tables? For Example I have users and user_addresses tables, and then I create user domain to handle both user and user address. If I have separate Create, Update, Delete function between user and user address, should I create two repository files (user_mysql_repo.go and user_address_mysql_repo.go) or I just create one repository file (user_mysql_repo.go).

    Thanks

    opened by NaufalHSyahputra 4
  • Question: Should we use a pointer as a return type of NewUsecase, NewRepository?

    Question: Should we use a pointer as a return type of NewUsecase, NewRepository?

    In this repo, there are building functios like below(NewUsecase or NewRepository)

    type mysqlArticleRepository struct {
    	Conn *sql.DB
    }
    
    // NewMysqlArticleRepository will create an object that represent the article.Repository interface
    func NewMysqlArticleRepository(Conn *sql.DB) domain.ArticleRepository {
    	return &mysqlArticleRepository{Conn}
    }
    

    As you can see, it returns address using &mysqlArticleRepository which of data type is a pointer. So I think return type should be pointer *domain.ArticleRepository like below

    type mysqlArticleRepository struct {
    	Conn *sql.DB
    }
    
    // NewMysqlArticleRepository will create an object that represent the article.Repository interface
    func NewMysqlArticleRepository(Conn *sql.DB) *domain.ArticleRepository {
    	return &mysqlArticleRepository{Conn}
    }
    

    I want to hear what you guys think about this. Thanks for reading this issue. 😄

    opened by aeharvlee 3
  • How to use a different routing library?

    How to use a different routing library?

    If I want to replace labstack/echo in this implementation with https://github.com/go-chi/chi Where to put the code and make the change? Don't see any interface around delivery and middlewares.

    opened by alok87 3
  • How do you reference ID's

    How do you reference ID's

    In domain/article.go we have

    type Article struct {
    	ID        int64     `json:"id"`
    	Title     string    `json:"title" validate:"required"`
    	Content   string    `json:"content" validate:"required"`
    	Author    Author    `json:"author"`
    	UpdatedAt time.Time `json:"updated_at"`
    	CreatedAt time.Time `json:"created_at"`
    }
    

    Here an Author attribute exists because an Article belongs to an Author

    Going from that logic I attempted to add ArticleStats so I made the following changes:

    in domain/article.go

    type Article struct {
    	.
    	.
    	.
    	ArticleStatistics ArticleStats `json:"article_statistics"`
    }
    

    and added

    in domain/articlestats.go

    type ArticleStats struct {
    	ID      int64   `json:"id"`
    	Article Article `json:"article"`
    	.
    	.
    	.
    }
    

    And I get illegal cycle in declaration of Article + illegal cycle in declaration of ArticleStats

    How is this solved?

    opened by Taz17 2
  • How to handle multiple Repository transactions

    How to handle multiple Repository transactions

    I have read your article and code to help me a lot, but I have a question, do not know how to solve, when a business needs multiple Repository cooperation, and they are a transaction, how to deal with such a situation? And this is the majority of cases, can you add similar examples in the code?

    opened by OC0311 2
  • How to handle shared middleware and support functions?

    How to handle shared middleware and support functions?

    I've been using your go structure for a project I'm working on and I'm hitting a few areas that I'm not quite sure how to solve, at least in a clean architecture way. If we take your directory structure as an example, say we have an http handler for author as well as article. Then say we want to use the same middleware for each handler. How the structure is currently set up is that there's a middleware package within the deliver/http directory for article. Would we have to create the exact same middleware package in author too? Duplicating code is probably not the answer here. Would it be better to create a top level handler/http directory with the middleware in there that can be shared across all entities? How about other utility functions?

    opened by egru 2
  • more simple clean arch

    more simple clean arch

    Hi I develop more simple clean arch

    handlers: any transport layer http web api, grpc, graphql and etc.

    app: Business layer

    storage: Database and caches

    services: external services

    https://github.com/Abdukahhor/swe

    what do you think ?

    opened by alifpay 2
  • Some questions about naming convention.

    Some questions about naming convention.

    First of all, Thank you for your awesome idea 👍

    1. In main.go, Is there any reason to name like this? I can't understand the detail feature of this convention with an underscore in front of the package name such as _articleRepo
    import (
    	_articleHttpDeliver "github.com/bxcodec/go-clean-arch/article/delivery/http"
    	_articleRepo "github.com/bxcodec/go-clean-arch/article/repository"
    	_articleUcase "github.com/bxcodec/go-clean-arch/article/usecase"
    	_authorRepo "github.com/bxcodec/go-clean-arch/author/repository"
    )
    
    1. Could I allow to add the package unrelated with models? (indirectly related?) Like below tree, I just define user.go in model and implement authentication feature in auth package. I wanted to separate auth package from user. Actually, I'm not sure with this Idea.
    .
    ├── auth
    │   ├── delivery
    │   │   └── http
    │   └── usecase
    ├── model
    └── user
        ├── delivery
        │   └── http
        ├── repository
        └── usecase
    

    Thank you.

    opened by yojkim 2
  • Why are you passing context to all layers?

    Why are you passing context to all layers?

    Hi!

    I am composing it with reference to this repository in my project and I am very grateful!

    Why did you pass context to all layers with the following changes? feat: add context #9

    opened by locona 2
  • Question about directory layer

    Question about directory layer

    hi @bxcodec thank for your source

    i got a lot of help

    I want to know why I classified each directory under the domain.

    like

    article
    ├── delivery
    │   └── http
    │       ├── article_handler.go
    │       ├── article_test.go
    │       └── middleware
    │           ├── middleware.go
    │           └── middleware_test.go
    ├── repository
    │   ├── helper.go
    │   └── mysql
    │       ├── mysql_article.go
    │       └── mysqlarticle_test.go
    └── usecase
        ├── article_ucase.go
        └── article_ucase_test.go
    

    to

    article
    ├── article_handler.go
    ├── article_test.go
    ├── article_ucase.go
    ├── article_ucase_test.go
    ├── mysql_article.go
    └── mysqlarticle_test.go
    

    why i think this needs, when developing have to open many folders

    and this sample usefull msa?

    opened by ben-swit 1
  • refactor: The main function and some writes what I think is a better practice

    refactor: The main function and some writes what I think is a better practice

    Thanks for this repo. I have learnt a lot from it.

    I have also tried to modify some of the code to my current knowledge to try to make the whole repository more like a Go project as I know it.

    I look forward to discussing some of the relevant changes with you under this PR.

    ref: uber-go style guide

    opened by uptutu 3
  • Question About Layers

    Question About Layers

    Hi I am developing my own website using this project structure. Currently I need to have a logging package and also use of JWT. For the logging package, is it good idea to put its interface inside domain folder and then implement its methods in adaptors layer? And for JWT, I think it doesn't need interface as it is less probable to be ejected. So where to put its codes like GenerateToken and ValidateToken methods? if there be a folder called pkg and then putting JWT there, it will go from inner layer to outer layer however. Could you please help me how to implements tools like jwt and bcrypt. Also where and how to implement a logging feature. Thanks

    opened by developer2346 0
  • Questions About Whether Necessary To Use Pointer For Usecase

    Questions About Whether Necessary To Use Pointer For Usecase

    Thanks a lot for the repo and it is really informative. However I have two small questions about pointer and value for usecase.

    1. In this scenario, article usecase is using pointer in both constructor and method receiver, is it because of the repository dependency(sqldb) which is also a pointer?
    2. What if I have a simpler usecase which doesn't have dependencies of references, eg: repository and it's just used to do simple stateless calculations without extra pointer dependencies. For these kind of scenarios, may I use copies instead of pointers?

    I would be very appreciated if you could clear some of my doubts.

    opened by fans3210 1
  • Implementation Basic Auth or Oauth 2.0 in go clean arch

    Implementation Basic Auth or Oauth 2.0 in go clean arch

    Hello guys,

    Would you mind to give some example of basic auth or oauth 2.0 implementation in this architecture? Would really appreciate it 🙏🙏

    Many thanks guys!

    opened by bismar88 0
Releases(v2.0.1)
Owner
Iman Tumorang
Software Engineer | Writer | Open Source Enthusiast | Startup Enthusiast
Iman Tumorang
Clean architecture in Go.

go-employee Clean architecture in Go. Based on the learnings from the book Get Your Hands Dirty on Clean Architecture by Tom Hombergs testing requires

RubinThomas 19 Nov 16, 2022
Flamingo Framework and Core Library. Flamingo is a go based framework for pluggable web projects. It is used to build scalable and maintainable (web)applications.

Flamingo Framework Flamingo is a web framework based on Go. It is designed to build pluggable and maintainable web projects. It is production ready, f

Flamingo 343 Jan 5, 2023
Eudore is the core of a golang lightweight web framework.

Eudore eudore是一个golang轻量级web框架核心,可以轻松扩展成一个技术栈专用框架,具有完整框架设计体系。 反馈和交流请加群组:QQ群373278915。 Features 易扩展:主要设计目标、核心全部解耦,接口即为逻辑。 简单:对象语义明确,框架代码量少复杂度低,无依赖库。 易用

null 73 Nov 7, 2022
Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.

Gin Web Framework Gin is a web framework written in Go (Golang). It features a martini-like API with performance that is up to 40 times faster thanks

Gin-Gonic 65.5k Jan 2, 2023
a golang web mvc framework, like asp.net mvc.

goku goku is a Web Mvc Framework for golang, mostly like ASP.NET MVC. doc & api Installation To install goku, simply run go get github.com/QLeelulu/go

QLeelulu 274 Dec 7, 2022
🍐 Elegant Golang REST API Framework

An Elegant Golang Web Framework Goyave is a progressive and accessible web application framework focused on REST APIs, aimed at making backend develop

SystemGlitch 1.2k Jan 4, 2023
Fast and Reliable Golang Web Framework

Gramework The Good Framework Gramework long-term testing stand metrics screenshot made with Gramework Stats Dashboard and metrics middleware What is i

null 374 Dec 18, 2022
Idiomatic HTTP Middleware for Golang

Negroni Notice: This is the library formerly known as github.com/codegangsta/negroni -- Github will automatically redirect requests to this repository

null 7.3k Dec 31, 2022
The web framework for Golang

uAdmin the Golang Web Framework Easy to use, blazing fast and secure. Originally open source by IntegrityNet Solutions and Services For Documentation:

uADMIN 219 Dec 24, 2022
A lightweight MVC framework for Go(Golang)

utron utron is a lightweight MVC framework in Go (Golang) for building fast, scalable and robust database-driven web applications. Features Postgres,

Geofrey Ernest 2.2k Dec 31, 2022
Golang CTF framework and exploit development module

Golang CTF framework and exploit development module

Frank Hübner 17 Dec 18, 2022
Golang Clean Architecture based on Uncle Bob's Clean Architecture and Summer internship in 2021

clean-architecture-api Description This is an example of implemention of Clean Architecture in Golang projects. This project has 4 layer : Infrastruct

daiki sakuma 4 Feb 20, 2022
This is a POC (Proof of Concept) using Hexagonal Architecture, SOLID, DDD, Clean Code, Clean Architecture

Projeto Planetas Star Wars: Esse projeto de trata de uma POC utilizando os conceitos de Clean Arch, Hexagonal Arch, Clean Code, DDD, e SOLID. O princi

Marcelo Martins 0 Feb 10, 2022
Clean-todo - An example of go app with clean architecture

clean-todo An example of go app with clean application Functionality This is a s

SEA AUCA 0 Jan 26, 2022
Flesch-go - Go-based implementation of the Flesch reading ease readability formula module.

flesch-go Go-based implementation of the Flesch reading ease readability formula module. Thanks for the flesch-index project. Installation Run the fol

Afeyer 2 Nov 9, 2022
Clean Architecture using Golang.

Golang Template Description This is an example of implementation of Clean Architecture in Go (Golang) projects. Rule of Clean Architecture by Uncle Bo

Golang Common Packages 78 Nov 1, 2022
Rest API for todoapp written in Golang, using clean architecture, CI/CD

todoapp-backend Rest API for todoapp written in Golang, using Clean Architecture and CI/CD (includes unit tests and integration tests). Using: Web fra

Đạo Phạm 7 Oct 23, 2022
Clean Architecture in Go (Golang) projects-DDD

go-clean-arch Changelog v1: checkout to the v1 branch Proposed on 2017, archived to v1 branch on 2018 Desc: Initial proposal by me. The story can be r

zhangxiaoxin 1 Oct 11, 2021
Clean Architecture template for Golang services

Go Clean template Clean Architecture template for Golang services Overview The purpose of the template is to show: how to organize a project and preve

null 7 Jul 11, 2022
Best simple, lightweight, powerful and really fast Api with Golang (Fiber, REL, Dbmate) PostgreSqL Database and Clean Architecture

GOLANG FIBER API (CLEAN ARCHITECTURE) Best simple, lightweight, powerful and really fast Api with Golang (Fiber, REL, Dbmate) PostgreSqLDatabase using

Elias Champi 3 Sep 2, 2022