이 글에서 나오는 이야기는 그저 3명이서 프로젝트를 개발한는 과정을, 고민등을 한풀이 하는 공간으로 어떠한 문제가 있었고, 이를 해결하기 위해 어떠한 과정을 겪었는지를 나열하는 공간으로 정확하지 않는 정보일 수 있습니다.
이 글의 목적은, 제가 지금까지 겪은 고민점들을 문서화한 다음 앞으로 비슷한 고민을 겪을때 참고하기 위한 것입니다. 참고로 이번이 GoLang을 사용한 첫 프로젝트입니다.. 완전 입문자.. ㅠ
https://www.youtube.com/watch?v=75X_eBW0mog
- Golang 도입, 그리고 4년 간의 기록 - 변규현, 당근마켓 | GopherCon Korea 2023
이런 영상이 있었는데 더 흥미를 끌게 되었습니다.
여기서 장점과 단점을 정리를 해주셨는데 간단하게 본다면
- 컴파일 속도 가 빠르고 효율적이다
- 빠른 애플리케이션 시작 시간, 재시작이 필요한 경우 빠르게 복구가 가능하다
- GC(Garbage Collection)가 있어서 높은 성능을 유지하면서 코드 관리가 용이하다
- 멀티코어 CPU를 잘 활용 할 수 있다,
- Goroutine + Channel- 언어 표현이 단순하다
- 애플리케이션 프로파일링, 메트릭 수집 등 표준 라이브러리에 포함되어 있어서 서비스 운영에 필요한 세부 모니털이과 성능 튜닝에 용이하다
- 에러처리가 번거롭다
- GC는 대규모 힙을 가진 시스템에서는 성능저하를 일으킬 수 있다
- 다른 언어 대비 Generic 사용이 제한적이다
- 표준화된 개발 방법론이 서비스 개발에 강제되지 않았다. 사람에 따라 코드 작성 방식이 다를 수 있다
Golang 도입, 그리고 4년 간의 기록 - 변규현, 당근마켓 | GopherCon Korea 2023 => 링크
이 부분을 보니 GoLang의 Garbage Collection에 대해서 좀 자세하게 알아볼 필요를 느꼈습니다 (한번 정리해서 올려볼게용). 물론 제가 뭐 트래픽이 아직 얼마나 나올지도 몰라 대규모 힙을 가질 것 같지는 않아서 크게 단점으로 다가오지는 않았고 그저 장점에 크게 집중을 하게 되었습니다.
https://www.youtube.com/watch?v=zdMuLvK0pNg&t=3116s
에서도 변규현님의

가 올라왔는데 아.. 프로젝트 시작하기 전에 이영상이 올라왔다면 참 좋았겠다는 생각을 하였습니다. 정말 도움이 많이 됩니다.
아무튼 GoLang에 흥미가 생기게 되었고 이로 프로젝트를 만들어 보겠다는 생각을 하게 되었습니다. 어떠한 프로젝트 구조로 해야하는가에 대해서 여러 검색을 해보았는데 대부분 그냥 스프링에서 했던 controller, service, repository, domain뭐 이렇게 나눠서 하는 곳이 많더라고요.
그런데 GoLang에서의 유연한 프로젝트 구조를 사용해보고 싶었고 저희는 간단하게 프로젝트 구조를 나누어서 스프링에서 만들던것처럼 완벽한 계층적? 구조로 하는것이 아니라 conf, internal(db, repository, handler, pkg), middleware, router등의 구조로 나누어서 진행을 해보았습니다

일단 간단한 프로젝트 구조는 짰는데
에 대한 여러 고민이 있었습니다.
찾아보니 많은 예시들은 순수 GoLang으로 만든 예제가 많았고 Framework에 대한 호불호도 좀 갈리는 것 같았습니다.
심지어 Framework도 Gin, Fiber, Echo등 하나의 프레임워크를 주로 사용하는 것이 아닌 여러가지를 사용한 것 같았습니다.

여기서 여러 비교를 진행하고 현재의 리소스를 확인해보았을때 그저 두명의 백엔드가 빠르게 개발과 배포를 진행을 해야했으므로 Framework를 사용하기로 결정을 하였습니다. 또한 그중에서 가장 Github Star가 많은 Gin을 사용하게 되었습니다.
기존 Java, Spring을 쓸때면 그냥 Domain위에다가 @Entity랑 여러 어노테이션을 붙여주면 알아서 foreign key까지 싹다 사용할 수 있었는데 Go에서 잘만든 ORM은 없다고 하더라고요. gorm, ent, sqlboiler등 다양하게 알아보았는데 장단점이 다 있는 것 같았습니다. 하지만 아예 사용하지 않는것은 너무 힘들것 같아서 가장 사용하기 쉽다는 SQL Boiler를 사용하기로 결정을 하였습니다.

[mysql]
dbname = dbname
host = host
port = port
user = user
pass = password
sslmode = "false"
blacklist = [
"*.created_at",
"*.updated_at",
]
뭐 이런식으로 toml하나 만들고 이것을 기반으로
sqlboiler --wipe --no-tests --no-auto-timestamps -p mysql -o ./internal/~~~~
뭐 이런식으로 적용하면 잘 적용이 되더라고요! 물론 이번 기회에 순수 쿼리 작성을 진짜 많이하게 되었습니다.. (sql 배우기 오히려 좋아~)

진짜 스웨거는 너무 슬펐습니다. 스프링부트에서는 진짜 Config만들고, implementation하나 진행해주면 알아서 스웨거를 만들어주었는데 GoLang에서는
// GetRecommendation godoc
// @Summary 줄거리
// @Description 설명
// @Tags 태그
// @Accept json
// @Produce json
// @Success 200 {object} pkg.BaseResponseStruct{data=nil} "성공"
// @Router {path} [get]
// @Router {path} [get]
// @Security BearerAuth
각 함수위에다가 이렇게 달아주어야지 되더라고요.. 하고
swag init -g ./main.go -o ./docs
뭐 이런식으로 실행을 하면 스웨거 파일이 docs에 잘 만들어졌습니다.

한번씩 다운로드해서 리뷰 남겨주시면 감사하겠습니다~~
사실은 정말 간단한 내용인데도 저 언어, 프레임워크, ORM, Swagger등을 정하는데도 꽤 시간이 오래 걸렸습니다. 이게 뭐하나 좀 강하게 정해진게 있으면 참 좋겠다는 생각을 하였습니다..