Go project structures
Tags: go, projectstructure, structure
Published: 2021-04-15 10:30:18

source & credit : thank you **Kat Zień**
[video](https://www.youtube.com/watch?v=Qtk9FFOoT5M&t)
[repository](https://github.com/katzien/go-structure-examples)

## Goals
- Consistent
    เพื่อให้โครงสร้างทุกส่วนของไปในทิศทางเดียวกัน
- Easy to understand
- Easy to change, loosely-coupled
    แก้ไขง่าย โดยไม่กระทบส่วนอื่น ๆ
- East to test
- Structure reflects the design exactly

## Example
### Beer reviewing service
Requirements
1. Users can add a beer
2. Users can add a review for a beer
3. Users can list all beers
4. Users can list all reviews for a selected beer.
5. Option to store data either in memory or JSON file
6. Ability to add some sample data

## Flat structure
📦/
 ┣ 📜data.go
 ┣ 📜handlers.go
 ┣ 📜main.go
 ┣ 📜model.go
 ┣ 📜storage.go
 ┣ 📜storage_json.go
 ┣ 📜storage_mem.go
 ┗ 📜[file name]_test.go

`main.go`
- Get storage [**Requirement 5**]
- Call for routes to get service
- Mock data [**Requirement 6**]
- HTTP server listener

`handlers.go`
- Manage with request (header, body, params,etc...)
- Call data from storage

`model.go`
- Entities struct

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qvp1eexrlbatfhvigxxo.png)
 
___

## Group by function (Layered archetecture)
- presentation / ui
- business logic
- external deps / infrastructure

📦/
 ┣ 📜data.go
 ┣ 📂handlers
 ┃ ┣ 📜beers.go
 ┃ ┗ 📜reviews.go
 ┣ 📂models
 ┃ ┣ 📜beer.go
 ┃ ┣ 📜review.go
 ┃ ┗ 📜storage.go
 ┗ 📂storage
   ┣ 📜json.go
   ┗ 📜memory.go

`main.go`
- Call for routes to get service

`handlers`
- request / response manage
- get storage

`storage`
- database services
  - struct
  - methods [ CRUD ]

### Cons
เสี่ยงต่อการเกิด Circular dependencies สูง เช่น layer models ต้องถูกใช้งานจากทั้ง layer บน และ ล่าง

---

## Group by module
📦/
 ┣ 📜main.go
 ┣ 📂beers
 ┃ ┣ 📜beer.go
 ┃ ┗ 📜handler.go
 ┣ 📂reviews
 ┃ ┣ 📜review.go
 ┃ ┣ 📜handler.go
 ┗ 📂storage
   ┣ 📜json.go
   ┣ 📜data.go
   ┣ 📜memory.go
   ┗ 📜storage.go

### Cons
เสี่ยงต่อการเกิด Circular dependencies เนื่องจาก ข้อมูลมีการเชื่อมโยงกัน [**Requirement 2, 4**]
- Beer ก็ใช้งาน Review 
- Review ก็ใช้งาน Beer

---

## Group by context

### Domain Driven Design
- Estalish your domain and business logic
- Define your bounded contexts, the models within each context and the ubiquitous language
- Catagorising the building blocks of your system

### Building blocks
- Context
  `beer tasting`
- Language 
  `beer`, `review`, `storage`
- Entities
  `Beer`, `Review`
- Value Objects
  `Brewery`, `Author`
- Aggregate
  `Beer Reviewer`
- Service
  `Beer adder / adding`, `Beer lister / listing`, `Review lister`
- Events
  `Beer added`, `Review added`, `Beer already exists`, `Beer not found`
- Repository
  `Beer repository`, `Review repository`

📦/
 ┣ 📂adding
 ┃ ┣ 📜endpoint.go
 ┃ ┗ 📜service.go
 ┣ 📂beers
 ┃ ┣ 📜beer.go
 ┃ ┗ 📜sample_beers.go
 ┣ 📂listing
 ┃ ┣ 📜endpoint.go
 ┃ ┗ 📜service.go
 ┣ 📂reviewing
 ┃ ┣ 📜endpoint.go
 ┃ ┗ 📜service.go
 ┣ 📂reviews
 ┃ ┣ 📜review.go
 ┃ ┗ 📜sample_reviews.go
 ┣ 📂storage
 ┃ ┣ 📜json.go
 ┃ ┣ 📜type.go
 ┃ ┗ 📜memory.go
 ┗ 📜main.go

![mermaid-diagram-20210417094134](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/efp10gowlacl5bzfaq4w.png) 

---

## Hexagonal Architecture

📦/
 ┣ 📂cmd
 ┃ ┣ 📂beer-server
 ┃ ┃ ┗ 📜main.go
 ┃ ┗ 📂sample-data
 ┃   ┗ 📜main.go
 ┗ 📂pkg
   ┣ 📂adding
   ┃ ┣ 📜endpoint.go
   ┃ ┗ 📜service.go
   ┣ 📂beers
   ┃ ┗ 📜beer.go
   ┣ 📂listing
   ┃ ┣ 📜endpoint.go
   ┃ ┗ 📜service.go
   ┣ 📂reviewing
   ┃ ┣ 📜endpoint.go
   ┃ ┗ 📜service.go
   ┣ 📂reviews
   ┃ ┗ 📜review.go
   ┣ 📂storage
   ┃ ┣ 📜json.go
   ┃ ┣ 📜type.go
   ┃ ┗ 📜memory.go
   ┣ 📂http
   ┃ ┣ 📂rest
   ┃ ┃ ┗ 📜handler.go
   ┃ ┣ 📂soap
   ┃ ┗ 📂rpc
   ┣ 📂resources
   ┃ ┗ 📂sample-data
   ┃   ┣ 📜sample_beers.go
   ┃   ┗ 📜sample_reviews.go

`cmd`
- commands to use service
  - use by request http protocal
  - use by using command line

`resources/sample-data`
- seperate sample data to individual folder