# Архитектура сервиса/микросервиса на Golang ## Основа: ``` ├── cmd - Основные приложения проекта ├── deployments - Директория для деплоя сервиса ├── docs - Директория с документацией ├── internal - Директория с внутренним кодом приложения ├── migrations - Директория с миграциями изменений БД ├── pkg - Директория с общими пакетами приложения - пакеты общие между доменами выносим в common, общее в рамках домена - в pkg ├── proto - Директория с описанием прототипа интерфейса gRPC ├── tests - Директория с тестами проекта (integration/e2e) ├── .dockerignore - Файл для перечисления игнорирования докером файлов/директорий ├── .gitignore - Файл для перечисления игнорирования гитом файлов/директорий ├── .gitlab-ci.yml - Файл настройки Gitlab CI ├── .golangci.yaml - Файл настройки линтера для Golang -- убрать, вынести в общий репозиторий, в хуки ├── .mockery.yaml - Файл настройки пакета mockery для генерации моков на Golang -- либо заменяем мокери, либо мок имиспользуем для внешних зависимостей или пустых сервисов ├── .buf.gen.yaml - https://buf.build/docs/configuration/v1/buf-gen-yaml ├── .buf.work.yaml - https://buf.build/docs/configuration/v1/buf-work-yaml/ ├── .buf.yaml - https://buf.build/docs/configuration/v1/buf-yaml/ -- proto2swagger не используем ├── go.mod - Корень управления зависимостями в GoLang ├── go.sum - Файл содержащий хеши для нескольких версий модуля ├── Makefile - Набор команд -- заменить на go-task ├── README.md - Общий файл документации (путеводитель) ``` ## Структура `/cmd`: ``` ├── [app name] - Название приложения (app) -- уходим от пракки некольких сервисов в одном репозитории, поэтому подкаталог делать не надо │ ├── main.go - Точка входа в приложение │ ├── Dockerfile - Файл контейнеризации сервиса -- проверить возможность скопировать из корня проекта ``` ## Структура `/docs`: ``` ├── [group] - Группа документации │ ├── README.md - Файл документации ├── openapi.yaml - Файл описания REST документации в формате OpenAPI (swagger) ``` ## Структура `/internal`: Здесь хранится внутренний код приложения и библиотек. Это код, который не должен быть применен в других приложениях и библиотеках. Стоит отметить, что этот шаблон использования internal навязан самим компилятором Golang. Ознакомьтесь с release notes Go 1.4. Также, вы вольны использовать internal директорию на разных уровнях своего проекта. ``` ├── app - Пакет приложения │ ├── [app name].go - Приложение ├── errors - Пакет для обработки и создания ошибок приложения (желательно вынести в pkg) -- 2 common, вынести как категоризатор ошибок и действий о них ├── initialize - Пакет для инициализации модулей (контроллеров, репозиториев, клиентов) ├── adapters - Данная директория хранит адаптеры для взаимодействия с внешними сервисами │ ├── client - Пакет клиента для взаимодействия с другими приложениями (REST, gRPC) │ │ ├── [name].go - Сам клиент ├── repository - Директория репозиториев для взаимодействия с базой данных -- если есть набор отдельных баз, то делаем отдельные подкаталоги │ ├── [name].go - Файл репозитория (user.go) ├── controller - Директория контроллеров │ ├── [name] - Директория контроллера │ │ ├── mocks - Директория, которая хранит сгенерированные моки для контроллера │ │ ├── [name].go - Сам контроллер. Хранит в себе обработчики внешних запросов │ │ ├── [name]_test.go - Файл тестов для контроллера ├── models - Пакет моделей данных │ ├── [name].go - Файл структур, которые относятся к определённой модели (user.go) ├── proto - Директория, содержащая сгенерированные proto файлы ├── server - Пакет хранящий инициализации серверов (http/tcp/grpc) -- 2 common │ ├── [name].go - Файл инициализации сервера (http/tcp/grpc) ├── services - Пакет слоя бизнес логики ├── utils - Пакет внутренних функций/утилит приложения - не больше одного уровня вложенности │ ├── [name].go - Утилита │ ├── [name]_test.go - Тесты утилиты ├── worker - Пакет, для запуска и инициализации воркеров │ ├── [name] - Пакет воркера │ │ ├── mocks - Пакет, содержащий сегенированные моки для воркера │ │ ├── [name].go - Файл воркера │ │ ├── [name]_test.go - Файл тестов воркера │ ├── run.go - Файл запуска воркеров ``` config? app ## Структура `/pkg`: Код библиотек, пригодных для использования в сторонних приложениях. (например, `/pkg/mypubliclib`). Другие проекты будут импортировать эти библиотеки, ожидая их автономной работы, поэтому стоит подумать дважды, прежде чем класть сюда какой-нибудь код. Использование директории `internal` - более оптимальный способ не дать импортировать внутренние пакеты, потому что это обеспечит сам `Golang`. Директория `/pkg` - всё еще хороший путь дать понять, что код в этой директории могут безопасно использовать другие. Код из директории `/pkg` желательно в будущем выносить в отдельный репозиторий общих пакетов. ``` ├── utils - Пакет утилит, доступные разным приложениям │ ├── [name].go - Утилита ``` ## Тесты: В каждом пакете присутствует файл, хранящий выполняемый код, рядом с этим файлом должен находится файл тестов, которые будет содержать имя этого файла и постфикс `_test`. ``` │ controller - Директория контроллеров │ ├── [name] - Пакет контроллера │ │ ├── mocks - Пакет сгенерированных моков для тестов контроллера │ │ ├── [name].go - Сам контроллер │ │ ├── [name]_test.go - Файл тестов контроллера ├── utils - Пакет внутренних функций/утилит приложения │ ├── [name].go - Утилита │ ├── [name]_test.go - Файл тестов утилиты ```