Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Contents

원문 : Go project structure best practices

Go Project Structure Best Practices

Go 애플리케이션의 구조는 다소 논쟁적인 주제가 될 수 있다. Go 애플리케이션에 대한 구조는 Golang standards / Project Layout에 잘 정의되어 있다. 어떤 개발자는 참고하는 정도로 이용하지만 어떤 개발자는 반드시 이 구조를 따라야 한다고 주장하기도 한다. 내 입장은 "소프트웨어에서의 규칙은 가능하면 지키려고 하되 얽매일 필요는 없다"이다.

위 문서는 좋은 내용을 담고 있지만 Go 모듈이 도입되면서 수정이 필요하다. 이 문서는 Go 애플리케이션을 개발 할 때 참고 할 수 있는 다양한 구조들을 제시하고 있다.

Flat Structure - 작은 애플리케이션

많은 프로젝트들이 일단 소규모로 시작하다가 (성공할 것 같다거나 참여자가 많아지면)살을 붙여가는 방식으로 규모를 키워간다.

이러한 상황에서는 아래와 같이 간단한 플랫(Flat) 구조로 시작하는게 좋다. 프로젝트 구조를 간단하게 함으로써, 복잡한 구조를 분석하는 오버헤드없이 가능한 빠르게 대상 사용자에게 가치를 제공하는데 집중 할 수 있다. 간단한 구조는 개발자를 끌어모으는데도 도움이 된다.
.
└── applications
    ├── main.go
    ├── main_test.go
    ├── utils.go
    └── utils_test.go
종종 개발자들이 프로젝트의 초기 단계에서 코드베이스를 정리하고 재정렬하는데 많은 시간을 소비하는 것을 보았다. 이는 실제 가치있는 것이 전달되기 전에 개발자 혹은 개발팀내에서의 피드백, 목표 고객과의 피드백 간격이 길어지게 한다.

장점

Flat 구조는 그러니까 하나의 디렉토리에 모든 코드들을 몰아 넣는 구조가 되겠다.
  • Microservices : MSA에서 각 응용 프로그램은 몇 가지 작업에 전문화되는 경우가 많다. 코드의 양이 적고 복잡도가 낮기 때문에 Flat 구조로도 충분하다. 비슷한 이유로 람다(AWS Lambda 같은) 아키텍처에도 적당한 구조다.
  • 작은 툴 과 라이브러리 : CLI 툴과 작은 라이브러리.

참고 프로젝트들

  • tidwall/gjson : 이 프로젝트는 극히 간단한 구조의 프로젝트가 어떻게 성공할 수 있는지를 거의 완벽하게 보여준다. 개발자는 애플리케이션을 사용하려는 사람들이 요구하는 실질적인 가치를 제공하는데 초점을 맞추고 모든 것을 간단하게 유지하고 있다.
  • go-yaml/yaml : 간단한 구조로 필요한 가치를 완벽하게 제공하는 또 다른 프로젝트.

중간규모 크기의 애플리케이션 - 모듈화

프로젝트의 규모가 커지고 복잡성이 증가하면 Flat 구조를 벗어난 구도화된 구조가 필요하다. 효과적인 구조는 프로젝트의 빠른 성장을 돕는다.

블로그 서비스를 위한 REST API를 예로 들어보자. 이 REST API는 유저 등록, 로그인, 로그아웃을 처리하기 위한 사용자 관리 API와 사용자의 컨텐츠를 처리(생성, 수정, 삭제 등)하는 컨텐츠 관리 API그룹으로 나눌 수 있을 것이다.

이제 애플리케이션은 의미별로 컴포넌트를 만들어서 분리하고, 각 컴포넌트에서 공유하는 핵심로직을 관리하기 위한 독립 패키지를 유지하기 위한 구조를 고민해야 한다.

.
└── rest-api
    ├── articles
    │   └── articles.go
    ├── main.go
    ├── user
    │   ├── login.go
    │   ├── registration.go
    │   └── user.go
    └── utils
        └── common_utils.go

참고 프로젝트들

  • google/go-cloud : go-cloud는 다양한 클라우드 서비스 제공자가 제공하는 클라우드 플랫폼에 응용 프로그램을 원할하게 배포 할 수 있도록 도와주는 응용 애플리케이션이다. Azur, GCP, AWS 등 클라우드 서비스 제공자별, postgres, mysql과 같은 주요 애플리케이션별로 디렉토리를 만들어서 코드를 관리하고 있다.
  • hashicorp/consul : consul은 분산환경에서 서비스 디스커버리와 설정을 관리하기 위한 응용 애플리케이션이다. 모듈(주요 기능)단위로 디렉토리를 만들어서 관리하고 있다.
  • ipfs/go-ipfs : Git, BitTorrent와 같은 시스템을 기반으로 만들어진 멋진 P2P파일 시스템이다. 모듈방식으로 프로젝트를 구조화하고 있다.
  • gohugoio/hugo : 정적 웹 사이트를 만들기 위한 훌륭한 툴이다.

성숙한 프로젝트

Hashicorp의 Terraform, Google의 Kubernetes와 같은 대규모 응용 소프트웨어는 $GOPATH가 사용되던 시절에 기본적인 개발이 완료된 프로젝트다. 이런 소프트웨어는 pkg와 같은 폴더를 여전히 사용하고 있다.

이러한 구조는 잘 작동하기는 하지만 Go Module이 널리 보급되면서 현대적인 구조로 마이그레이션되고 있다.