Przegląd

To jest podstawowa struktura katalogów dla projektów aplikacji w Go. Nie jest to oficjalnie zdefiniowany standard przez zespół deweloperski języka Go; to powszechnie stosowana struktura katalogów dla projektów społecznościowych w Go.

Jeśli uczysz się Go, tworzysz dowód koncepcji (PoC) lub prosty projekt osobisty, ta struktura projektu jest zbyt skomplikowana. Zamiast tego zacznij od prawdziwie prostego układu (tylko plik main.go i go.mod wystarczą). Gdy Twój projekt ewoluuje, upewnij się, że struktura kodu jest dobra, w przeciwnym razie skończysz z nieporządnym kodem zawierającym wiele ukrytych zależności i globalnego stanu. Gdy do projektu dołącza więcej osób, konieczne staje się bardziej uporządkowane podejście. W tym przypadku ważne jest wprowadzenie powszechnego sposobu zarządzania pakietami/bibliotekami. Gdy masz projekt open-source albo wiesz, że inne projekty importują kod z twojego repozytorium projektu, istotne staje się posiadanie prywatnych (również nazywanych jako internal) pakietów i kodu. Sklonuj repozytorium, zachowaj potrzebne części i usuń resztę! Tylko dlatego, że coś istnieje, nie oznacza, że musisz tego używać. Żaden z tych wzorców nie jest używany w każdym projekcie. Nawet wzorzec vendor nie jest uniwersalny.

Ta struktura projektu jest celowo zaprojektowana jako bardzo ogólna i nie stara się narzucić konkretnej struktury pakietów w Go.

Specyfikacja katalogu projektu Go

Poniżej znajduje się zalecana specyfikacja katalogu projektu 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

Poniżej przedstawiono znaczenia każdego katalogu.

/cmd

Główne aplikacje projektu, czyli punkty wejścia programów. Pliki Go w tym katalogu zazwyczaj generują pliki wykonywalne. W prostym projekcie plik takiego jak /test/main.go może służyć jako punkt wejścia.

Nazwa katalogu dla każdej aplikacji powinna pasować do nazwy pliku wykonywalnego, którego oczekujesz (na przykład /cmd/myapp).

Nie umieszczaj zbyt dużo kodu w katalogu aplikacji. Jeśli uważasz, że kod może zostać zaimportowany i użyty w innych projektach, umieść go w katalogu /pkg. Jeśli kod nie jest wielokrotnego użytku albo nie chcesz, żeby inni go używali, umieść kod w katalogu /internal. Będziesz zaskoczony zachowaniem innych osób, dlatego wyraźnie wyraź swoje intencje!

Zazwyczaj istnieje niewielka funkcja main, która importuje i wywołuje kod z katalogów /internal i /pkg, i nic więcej.

/internal

Prywatny kod aplikacji i bibliotek. To jest kod, którego nie chcesz, aby inni importowali do swoich aplikacji lub bibliotek. Zauważ, że ten wzorzec układu jest narzucany przez sam kompilator Go. Aby uzyskać bardziej szczegółowe informacje, proszę odwołać się do notatek wydania dla Go 1.4. Zauważ, że to nie jest ograniczone do najwyższego poziomu katalogu internal. Możesz mieć wiele katalogów internal na każdym poziomie drzewa projektu.

Możesz wybrać dodanie dodatkowej struktury dla pakietów wewnętrznych, aby rozróżnić między współdzielonym i nie-współdzielonym kodem wewnętrznym. To nie jest wymagane (szczególnie dla mniejszych projektów), ale wizualne przedstawienie intencjonalnego użycia pakietów jest dobrym zwyczajem. Twój rzeczywisty kod aplikacji może być umieszczony w katalogu /internal/app (na przykład /internal/app/myapp), a współdzielony kod dla tych aplikacji w katalogu /internal/pkg (na przykład /internal/pkg/myprivlib).

/pkg

Kod biblioteki, który może być używany przez zewnętrzne aplikacje (na przykład /pkg/mypubliclib). Inne projekty zaimportują te biblioteki i oczekają, że będą działać poprawnie, dlatego dobrze się zastanów, zanim umieścisz tutaj zawartość :-) Zauważ, że katalog internal jest lepszym sposobem, aby zapewnić, że prywatne pakiety nie mogą być importowane, ponieważ jest to narzucone przez samego Go. Katalog /pkg nadal jest dobrym sposobem, aby jednoznacznie przekazać, że kod w tym katalogu jest bezpieczny do użycia przez innych.

Jeśli twój projekt aplikacji jest bardzo mały i wielopoziomowe zagnieżdżanie nie dodaje zbyt dużo wartości, też jest w porządku, jeśli tego nie używasz (chyba że naprawdę chcesz użyć :-)). Gdy projekt staje się wystarczająco duży, a katalog główny staje się bardzo zajęty, rozważ jego używanie (szczególnie jeśli masz wiele komponentów aplikacji nie-GO).

/vendor

Zależności aplikacji (ręcznie zarządzane lub za pomocą preferowanego narzędzia do zarządzania zależnościami, takiego jak wbudowana funkcja Go Modules). Polecenie go mod vendor stworzy dla ciebie katalog /vendor. Zauważ, że jeśli nie korzystasz z domyślnej wersji Go 1.14, możesz potrzebować dodać flagę -mod=vendor do polecenia go build.

Jeśli budujesz bibliotekę, proszę nie commituj swoich zależności aplikacji.

Katalogi aplikacji usługowej

/api

Specyfikacje OpenAPI/Swagger, pliki schematu JSON, pliki definicji protokołu oraz katalogi protokołu API.

Katalogi aplikacji internetowej

/web

Specyficzne komponenty dla aplikacji internetowych: zasoby statycznej strony internetowej, szablony po stronie serwera oraz aplikacje jednostronne (SPA).

Ogólne katalogi aplikacji

/configs

Szablony plików konfiguracyjnych lub domyślne konfiguracje.

Umieść tutaj pliki szablonów confd lub consul-template.

/init

Inicjowanie systemu (systemd, upstart, sysv) oraz konfiguracje menedżera procesów/demonów (runit, supervisord).

/scripts

Skrypty do różnych operacji związanych z budową, instalacją, analizą i innymi.

/build

Pakowanie i ciągła integracja.

Umieść konfiguracje i skrypty pakietów chmury (AMI), kontenerów (Docker), systemu operacyjnego (deb, rpm, pkg) w katalogu /build/package.

Umieść konfiguracje i skrypty ciągłej integracji (travis, circle, drone) w katalogu /build/ci. Proszę zauważyć, że niektóre narzędzia ciągłej integracji (takie jak Travis CI) są bardzo specyficzne co do lokalizacji swoich plików konfiguracyjnych. Spróbuj umieścić pliki konfiguracyjne w katalogu /build/ci i użyj linków do połączenia ich z oczekiwaną lokalizacją przez narzędzia ciągłej integracji (jeśli to możliwe).

/deployments

Konfiguracje wdrożeń i szablony dla IaaS, PaaS, systemu oraz orchestracji kontenera (docker-compose, kubernetes/helm, terraform). Proszę zauważyć, że w niektórych repozytoriach (szczególnie dla aplikacji wdrażanych za pomocą Kubernetes), ten katalog nazywa się /deploy.

/test

Inne zewnętrzne aplikacje testowe i dane testowe. Zorganizuj katalog /test w taki sposób, który odpowiada twoim potrzebom. W przypadku większych projektów, sensowne jest zorganizowanie danych w podkatalogach. Na przykład, możesz utworzyć katalogi /test/data lub /test/testdata wewnątrz /test, aby Go zignorował ich zawartość. Proszę zauważyć, że Go również ignoruje katalogi lub pliki zaczynające się od "." lub "_", co zapewnia większą elastyczność w nazewnictwie katalogów z danymi testowymi.

Pozostałe katalogi

/docs

Dokumentacja projektu i użytkownika (oprócz dokumentów godoc, które generujesz).

/tools

Narzędzia wspierające ten projekt. Proszę zauważyć, że te narzędzia mogą importować kod z katalogów /pkg i /internal.

/examples

Przykłady aplikacji i/lub publicznych bibliotek.

/third_party

Zewnętrzne narzędzia pomocnicze, kod forka oraz inne narzędzia publiczne stron trzecich (np. Swagger UI).

/githooks

Haki Git.

/assets

Dodatkowe zasoby (obrazy, logo itp.) dostarczone w repozytorium.

/website

Lokalizacja do przechowywania danych strony internetowej projektu, jeśli nie korzystasz z GitHub Pages.

/src

Niektóre projekty Go mogą mieć katalog src, ale jest to zazwyczaj spowodowane tym, że deweloperzy pochodzą z świata Javy, gdzie jest to powszechny wzorzec. Jeśli to możliwie, spróbuj unikać tego Java-podobnego wzorca. Naprawdę nie chcesz, aby twój kod Go lub projekt wyglądał jak Java :-)

Nie myl katalogu /src na poziomie projektu z katalogiem /src używanym dla przestrzeni roboczej Go, opisanym w Jak pisać kod w Go. Zmienna środowiskowa $GOPATH wskazuje na twoją (bieżącą) przestrzeń roboczą (domyślnie, na systemach nie-Windows wskazuje na katalog $HOME/go). Ta przestrzeń robocza obejmuje katalogi na najwyższym poziomie: /pkg, /bin oraz /src. Twój rzeczywisty projekt będzie podkatalogiem w katalogu /src, więc jeśli twój projekt ma katalog /src, ścieżka projektu będzie wyglądać tak: /some/path/to/workspace/src/your_project/src/your_code.go. Proszę zauważyć, że od wersji Go 1.11 twój projekt może być umieszczony poza GOPATH, ale to nie oznacza, że korzystanie z tego układu jest dobrym pomysłem.