Initial API project with Go
Tags: go, webdev
Published: 2022-01-27 10:22:39

## เกริ่นนำ
เนื่องจากช่วงนี้ผมได้มาเริ่มต้นโปรเจค API ด้วย Golang บ่อย
ผมเลยขอบันทึกไว้กันลืม

## Stack
1) Golang
2) [Go Fiber](https://docs.gofiber.io)
3) [Gorm](https://gorm.io)
4) PostgreSQL

## Steps
1) สร้าง Folder สำหรับที่อยู่ของโปรเจค
```bash
$ mkdir demo
$ cd demo
```

2) สร้าง go mod file
```bash
$ go mod init github.com/mossnana/demo
```

3) สร้าง Folders / Files ที่เก็บ source code
```bash
$ mkdir cmd
$ mkdir internal
$ mkdir pkg
```
** Folder **
- cmd
  ไว้วางโฟรเดอร์ที่มีไฟล์ main.go สำหรับโปรแกรมต่าง ๆ เช่น
    - server ตัว run web server
    - migrator ตัว migrate db
- internal
  ไว้ใส่ไฟล์ที่เก็บ logic ที่เกี่ยวข้องกับตัว api นี้ ที่มีความเฉพาะตัวของ api นี้
- pkg
  ไว้เก็บไฟล์ที่ไว้ต่อกับโปรแกรมนอก เช่น function ต่อ database ๆลๆ

4) สร้าง Folders / Files ที่ไว้ run
`Dockerfile`
```Dockerfile
FROM golang:latest
WORKDIR /app
COPY . .

RUN go mod tidy
RUN go get github.com/githubnemo/CompileDaemon
RUN go build -o bin/migrator ./cmd/migrator

CMD CompileDaemon --build="go build -o bin/server ./cmd/server" --command="./bin/server"
```
* CompileDaemon ใช้เป็นตัว auto restart เมื่อ code เปลี่ยน

`docker-compose.yml`
```yaml
version: "3.5"

services:
  demo_service:
    container_name: demo_service
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./:/app
    restart: always
    ports:
      - "3000:3000"
    networks:
      - demo_net
    env_file:
      - ./.env

  brij_db:
    container_name: brij_db
    image: postgres:14
    volumes:
      - "demo_db_data:/var/lib/postgresql/data"
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_USER=demo
      - POSTGRES_PASSWORD=demopassword
      - POSTGRES_DB=demo
    networks:
      - demo_net

networks:
  demo_net:
    external: false

volumes:
  demo_db_data:
    external: false
```

`Makefile`
```Makefile
build:
	docker-compose up -d --build

start:
	docker-compose up -d

migrate:
	docker exec -it demo_service /app/bin/migrator

stop:
	docker-compose down
```

Project tree
```
.
├── cmd/
│   ├── demo/
│   │   └── main.go
│   └── migrator/
│       └── main.go
├── internal/
│   ├── model/
│   │   ├── sale.go
│   │   ├── purchase.go
│   │   └── account.go
│   ├── repository/
│   │   ├── sale.go
│   │   ├── purchase.go
│   │   └── account.go
│   ├── service/
│   │   ├── sale/
│   │   │   ├── v1/
│   │   │   │   ├── create.go
│   │   │   │   ├── read.go
│   │   │   │   ├── update.go
│   │   │   │   └── delete.go
│   │   │   └── v2/
│   │   │       ├── create.go
│   │   │       ├── read.go
│   │   │       ├── update.go
│   │   │       └── delete.go
│   │   └── ...
│   ├── handler/
│   │   └── sale/
│   │       ├── v1/
│   │       │   ├── create.go
│   │       │   ├── read.go
│   │       │   ├── update.go
│   │       │   └── delete.go
│   │       ├── v2/
│   │       │   ├── create.go
│   │       │   ├── read.go
│   │       │   ├── update.go
│   │       │   └── delete.go
│   │       └── ...
│   └── route/
│       ├── sale.go
│       ├── purchase.go
│       └── account.go
├── pkg/
│   ├── auth/
│   │   └── auth.go
│   └── gorm/
│       ├── driver.go
│       └── migrate.go
├── Dockerfile
├── docker-compose.yml
└── Makefile
```

## การ Build
```bash
go build -o bin/{{ชื่อแอปใน main}} ./cmd/{{ชื่อแอปใน main}}
```