개요

이것은 Go 애플리케이션 프로젝트의 기본 레이아웃입니다. 이것은 Go 코어 개발 팀에 의해 공식으로 정의된 표준이 아니며, 공동체 Go 프로젝트에서 흔히 사용되는 디렉토리 레이아웃입니다.

Go를 배우거나 컨셉 증명(PoC)이나 간단한 개인 프로젝트를 만드는 경우에는 이 프로젝트 레이아웃이 너무 복잡합니다. 대신, 정말 간단한 레이아웃(단순히main.go파일과 go.mod만 있는 것)으로 시작해보세요. 프로젝트가 진화할수록 코드 구조가 좋은지 확인해야 합니다. 그렇지 않으면 숨겨진 종속성과 전역 상태가 많은 엉망진창인 코드가 될 것입니다. 프로젝트에 더 많은 사람들이 참여하면 보다 구조화된 방법이 필요합니다. 이 경우에는 패키지/라이브러리를 관리하는 일반적인 방법을 도입하는 것이 중요합니다. 오픈 소스 프로젝트가 있거나 다른 프로젝트가 귀하의 프로젝트 리포지토리에서 코드를 가져온다는 것을 알 때는 개인(또는internal) 패키지와 코드를 가지는 것이 중요합니다. 리포지토리를 복제하고 필요한 부분을 유지하고 나머지는 삭제하세요! 그것이 존재한다고 해서 모두 사용할 필요는 없습니다. 이러한 패턴 중 하나도 모든 프로젝트에 사용되는 것은 아닙니다. 심지어 vendor 패턴도 일반적이지 않습니다.

이 프로젝트 레이아웃은 의도적으로 매우 일반적으로 설계되었으며 특정한 Go 패키지 구조를 강요하려고 하지 않습니다.

Go 프로젝트 디렉토리 명세

아래는 권장하는 Go 프로젝트 디렉토리 명세입니다.

.
├── go.mod
├── api
├── assets
├── build
├── cmd
├── configs
├── deployments
├── docs
├── examples
├── githooks
├── go.mod
├── init
├── internal
├── pkg
├── scripts
├── test
├── third_party
├── tools
├── vendor
├── web
└── website

각 디렉토리의 의미는 아래에서 설명합니다.

/cmd

프로젝트의 주 애플리케이션, 즉 프로그램의 진입점입니다. 이 디렉토리의 Go 파일은 일반적으로 실행 가능한 파일을 생성합니다. 간단한 프로젝트에서 /test/main.go와 같은 파일이 진입점으로 사용될 수 있습니다.

각 애플리케이션 디렉토리의 이름은 원하는 실행 파일의 이름과 일치해야 합니다(예:/cmd/myapp).

애플리케이션 디렉토리에 너무 많은 코드를 넣지 마세요. 코드를 다른 프로젝트에서 가져와 사용할 수 있다고 생각된다면/pkg 디렉토리에 위치시키세요. 코드가 재사용 가능하지 않거나 다른 사람들이 재사용하지 않기를 원한다면 코드를/internal 디렉토리에 위치시키세요. 다른 사람들의 행동에 놀라게 될 것이므로 의도를 명확히 표현하세요!

일반적으로main 함수가 있어/internal/pkg 디렉토리에서 코드를 가져와 호출하며, 그 외에는 아무 것도 없습니다.

/internal

비공개 애플리케이션 및 라이브러리 코드입니다. 이것은 다른 사람이 그들의 애플리케이션이나 라이브러리로 가져가기를 원치 않는 코드입니다. 이 레이아웃 패턴은 Go 컴파일러에 의해 강제됩니다. 자세한 내용은 Go 1.4의 릴리스 노트를 참조하세요. internal 디렉토리가 최상위 수준에 제한되지는 않으며, 프로젝트 트리의 어느 수준에서든지 여러 개의internal 디렉토리를 가질 수 있습니다.

내부 패키지와 비공유 내부 코드를 구별하기 위해 내부 패키지에 몇 가지 추가 구조를 추가할 수 있습니다. 이것은 필요하지 않습니다(특히 작은 프로젝트의 경우), 하지만 패키지의 의도된 사용을 시각적으로 보여주는 것은 좋은 실천입니다. 실제 응용 프로그램 코드를/internal/app(예:/internal/app/myapp) 디렉토리에 놓을 수 있으며, 이러한 응용 프로그램을 위한 공유 코드를/internal/pkg(예:/internal/pkg/myprivlib) 디렉토리에 놓을 수 있습니다.

/pkg

외부 애플리케이션이 사용할 수 있는 라이브러리 코드(예:/pkg/mypubliclib)입니다. 다른 프로젝트가 이러한 라이브러리를 가져와 제대로 작동하기를 기대하므로 여기에 내용을 넣기 전에 신중하게 생각하세요 :-)internal 디렉토리가 비공개 패키지를 가져올 수 없도록 하는 더 나은 방법인데, 이것은 Go에 의해 강제됩니다. 그럼에도 불구하고/pkg 디렉토리는 이 디렉토리의 코드가 다른 사람이 사용해도 안전하다는 것을 명시적으로 전달하는 좋은 방법입니다.

당신의 응용 프로그램 프로젝트가 매우 작고 다중 수준의 중첩이 큰 가치를 추가하지 않는다면 사용하지 않는 것도 괜찮습니다(당신이 정말로 사용하길 원하지 않는 이상 :-)). 프로젝트가 충분히 커지고 루트 디렉토리가 매우 바쁘다면(특히 많은 비-Go 응용 구성 요소가 있는 경우) 사용해보세요.

/vendor

애플리케이션 종속성(수동으로 관리하거나 내장된 Go Modules 기능과 같은 선호하는 종속성 관리 도구를 사용)을 의존합니다. go mod vendor 명령어는 /vendor 디렉터리를 생성합니다. 기본으로 활성화되어 있지 않은 Go 1.14 버전을 사용하는 경우 go build 명령어에 -mod=vendor 플래그를 추가해야 합니다.

라이브러리를 작성하는 경우 애플리케이션 종속성을 커밋하지 마십시오.

서비스 애플리케이션 디렉터리

/api

OpenAPI/Swagger 명세, JSON 스키마 파일, 프로토콜 정의 파일, API 프로토콜 디렉터리입니다.

웹 애플리케이션 디렉터리

/web

웹 애플리케이션을 위한 특정 구성요소: 정적 웹사이트 자산, 서버 측 템플릿, 단일 페이지 애플리케이션(SPA)이 포함됩니다.

일반적 애플리케이션 디렉터리

/configs

구성 파일 템플릿 또는 기본 구성이 포함됩니다.

여기에는 confd 또는 consul-template 템플릿 파일을 배치합니다.

/init

시스템 초기화(systemd, upstart, sysv) 및 프로세스 관리자/데몬(runit, supervisord) 구성이 여기에 있습니다.

/scripts

빌드, 설치, 분석 및 기타 운영을 위한 스크립트가 포함됩니다.

/build

패키징 및 지속적 통합이 이루어집니다.

클라우드 (AMI), 컨테이너 (Docker), 운영 체제 (deb, rpm, pkg) 패키지 구성 및 스크립트는 /build/package 디렉터리에 배치합니다.

지속적 통합 (travis, circle, drone) 구성 및 스크립트는 /build/ci 디렉터리에 배치합니다. 특정 지속적 통합 도구(예: Travis CI)는 구성 파일의 위치에 대해 매우 구체적입니다. 가능하다면 구성 파일을 /build/ci 디렉터리에 배치하고 지속적 통합 도구가 기대하는 위치로 연결하는 링크를 사용해야 합니다.

/deployments

IaaS, PaaS, 시스템 및 컨테이너 오케스트레이션(docker-compose, kubernetes/helm, terraform)을 위한 배포 구성 및 템플릿이 여기에 있습니다. 일부 저장소(특히 Kubernetes를 사용하여 배포된 애플리케이션인 경우)에서는 이 디렉터리가 /deploy로 명명될 수 있습니다.

/test

다른 외부 테스트 애플리케이션과 테스트 데이터가 있습니다. /test 디렉터리를 필요에 맞게 구성하십시오. 대형 프로젝트의 경우 데이터를 하위 디렉토리로 구성하는 것이 합리적입니다. 예를 들어 /test/data 또는 /test/testdata 디렉터리를 만들어 Go가 내용을 무시하게 할 수 있습니다. Go는 또한 "." 또는 "_"로 시작하는 디렉터리나 파일을 무시하므로 테스트 데이터 디렉터리의 이름을 지을 때 큰 유연성을 제공합니다.

기타 디렉터리

/docs

설계 및 사용자 문서(생성하는 godoc 문서 이외).

/tools

프로젝트에 대한 지원 도구입니다. 이러한 도구는 /pkg/internal 디렉터리에서 코드를 가져올 수 있습니다.

/examples

애플리케이션 및/또는 공개 라이브러리에 대한 예제가 포함됩니다.

/third_party

외부 보조 도구, 포크된 코드 및 기타 제3자 유틸리티 도구(예: Swagger UI)가 여기에 있습니다.

/githooks

Git 후크가 포함됩니다.

/assets

저장소와 함께 제공되는 추가 자산(이미지, 로고 등)이 있습니다.

/website

GitHub Pages를 사용하지 않는 경우 프로젝트 웹사이트 데이터를 저장하는 위치입니다.

/src

일부 Go 프로젝트에는 src 폴더가 있을 수 있지만, 이는 일반적으로 Java 세계에서 온 개발자들 때문입니다. 가능하다면 이러한 Java와 유사한 패턴을 채용하지 않도록 하십시오. Go 코드나 프로젝트가 Java와 비슷하게 보이기를 원하지 않을 것입니다 :-)

프로젝트 수준의 /src 디렉터리를 Go 작업 공간에 사용되는 /src 디렉터리와 혼동하면 안 됩니다. $GOPATH 환경 변수는 (현재) 작업 공간을 가리킵니다(기본적으로 Windows 시스템에서는 $HOME/go 디렉터리를 가리킵니다). 이 작업 공간에는 최상위 레벨 /pkg, /bin, /src 디렉터리가 포함됩니다. 실제 프로젝트는 /src 디렉터리의 하위 디렉터리에 있을 것이므로, 프로젝트에 /src 디렉터리가 있는 경우 프로젝트 경로는 다음과 같이 보일 것입니다: /some/path/to/workspace/src/your_project/src/your_code.go. Go 1.11부터 프로젝트는 GOPATH 바깥에 위치할 수 있지만, 이 레이아웃 패턴을 사용하는 것이 좋은 아이디어라는 뜻은 아닙니다.