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.

Issues
  • 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
  • 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
  • How do we implement Bulk Update in this design pattern?

    How do we implement Bulk Update in this design pattern?

    Hi, May I know if there's a way for me to use any ORM update method without fetching the models first, right now from what I can see, the current pattern only allows the repository to update a single model. Is there any pattern that allows updating a single model and bulk update in one repository? image Thank you

    opened by akmalhazim 1
  • 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
  • Creating different insert operation method vs creating single insert method and reuse in usecase?

    Creating different insert operation method vs creating single insert method and reuse in usecase?

    Hello, Sorry for too many questions. I've been studying this architecture lately and came up across this question?

    Is it better to create a single Create() method in repository layer and have many usecase methods that creates the entity or having different method for Create() operation in repository layer for so every usecase that requires a Create() method could have it's own dedicated method for creating the entity?

    Appreciate your feedback. Thank you and have a nice day ahead.

    opened by akmalhazim 2
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 Aug 3, 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 306 Aug 4, 2022
Eudore is the core of a golang lightweight web framework.

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

null 72 Jul 30, 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 61.7k Aug 8, 2022
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 275 May 24, 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.1k Aug 4, 2022
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 367 Jul 13, 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.2k Aug 4, 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 194 Aug 6, 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 Aug 3, 2022
Golang CTF framework and exploit development module

Golang CTF framework and exploit development module

Frank Hübner 12 Aug 5, 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 1 Jan 2, 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 Jul 17, 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 5 Jan 14, 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 2 May 20, 2022
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

Gabe Hoban 0 Nov 30, 2021
Clean Architecture With Golang

Clean Architecture With Golang When init a new project go mod init github.com/samuelterra22/clean-architecture-go Run testes go test ./... Generate a

Samuel Terra 2 Aug 2, 2022
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

Mada Satya Bayu Ambika 4 Dec 23, 2021
Implement clean-architecture sample by golang

Implement clean-architecture sample by golang

null 2 Feb 17, 2022
API em Golang utilizando clean architecture

Clean Arch in Go Read about Clean Architecture Build make Run tests make te

Marcos 1 Dec 23, 2021
An example of implementation of Clean Architecture in Golang

Golang Template Description This is an example of implementation of Clean Archit

Emirhan 0 Dec 29, 2021
Implementation of clean architecture in golang with gin-gonic & gorm

Boilerplate API Boilerplate API template includes all the common packages and setup used for API development in this Company. Development Copy .env.ex

null 10 Feb 15, 2022
REST api using fiber framework written in golang and using firebase ecosystem to authentication, storage and firestore as a db and use clean architecture as base

Backend API Example FiberGo Framework Docs : https://github.com/gofiber Info This application using firebase ecosystem Firebase Auth Cloud Storage Fir

Atilla Pehlivan 3 May 31, 2022
Onion-Layer-Golang - A web application boilerplate built with go and clean architecture

go-clean-architecture-web-application-boilerplate A web application boilerplate

Endy Gigih Pratama 1 May 4, 2022