From 553095d5ba6f25bbfcdc0e26bde6ed00131fc4ed Mon Sep 17 00:00:00 2001 From: anatolypaw Date: Sun, 11 Aug 2024 22:13:51 +0600 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B2=D0=BE=D0=B4=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D1=80=D1=83=D1=81=D1=81=D0=BA=D0=BE=D0=BC=20=D1=8F?= =?UTF-8?q?=D0=B7=D1=8B=D0=BA=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 50 +++++++- README_RU.md | 325 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 370 insertions(+), 5 deletions(-) create mode 100644 README_RU.md diff --git a/README.md b/README.md index 56a55fc7..082b977b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ ![Go Clean Template](docs/img/logo.svg) # Go Clean template -[πŸ‡¨πŸ‡³δΈ­ζ–‡](README_CN.md) + +[πŸ‡¨πŸ‡³ δΈ­ζ–‡](README_CN.md) +[πŸ‡·πŸ‡Ί RU](README_RU.md) Clean Architecture template for Golang services @@ -11,7 +13,9 @@ Clean Architecture template for Golang services [![codecov](https://codecov.io/gh/evrone/go-clean-template/branch/master/graph/badge.svg?token=XE3E0X3EVQ)](https://codecov.io/gh/evrone/go-clean-template) ## Overview + The purpose of the template is to show: + - how to organize a project and prevent it from turning into spaghetti code - where to store business logic so that it remains independent, clean, and extensible - how not to lose control when a microservice grows @@ -21,13 +25,16 @@ Using the principles of Robert Martin (aka Uncle Bob). [Go-clean-template](https://evrone.com/go-clean-template?utm_source=github&utm_campaign=go-clean-template) is created & supported by [Evrone](https://evrone.com/?utm_source=github&utm_campaign=go-clean-template). ## Content + - [Quick start](#quick-start) - [Project structure](#project-structure) - [Dependency Injection](#dependency-injection) - [Clean Architecture](#clean-architecture) ## Quick start + Local development: + ```sh # Postgres, RabbitMQ $ make compose-up @@ -36,17 +43,21 @@ $ make run ``` Integration tests (can be run in CI): + ```sh # DB, app + migrations, integration tests $ make compose-up-integration-test ``` ## Project structure + ### `cmd/app/main.go` + Configuration and logger initialization. Then the main function "continues" in `internal/app/app.go`. ### `config` + Configuration. First, `config.yml` is read, then environment variables overwrite the yaml config if they match. The config structure is in the `config.go`. The `env-required: true` tag obliges you to specify a value (either in yaml, or in environment variables). @@ -59,15 +70,18 @@ reading the entire config from ENV. It is assumed that default values are in yaml, and security-sensitive variables are defined in ENV. ### `docs` + Swagger documentation. Auto-generated by [swag](https://github.com/swaggo/swag) library. You don't need to correct anything by yourself. ### `integration-test` + Integration tests. They are launched as a separate container, next to the application container. It is convenient to test the Rest API using [go-hit](https://github.com/Eun/go-hit). ### `internal/app` + There is always one _Run_ function in the `app.go` file, which "continues" the _main_ function. This is where all the main objects are created. @@ -89,19 +103,24 @@ $ go run -tags migrate ./cmd/app ``` ### `internal/controller` + Server handler layer (MVC controllers). The template shows 2 servers: + - RPC (RabbitMQ as transport) - REST http (Gin framework) Server routers are written in the same style: + - Handlers are grouped by area of application (by a common basis) - For each group, its own router structure is created, the methods of which process paths - The structure of the business logic is injected into the router structure, which will be called by the handlers #### `internal/controller/http` + Simple REST versioning. For v2, we will need to add the `http/v2` folder with the same content. And in the file `internal/app` add the line: + ```go handler := gin.New() v1.NewRouter(handler, t) @@ -113,11 +132,14 @@ Instead of Gin, you can use any other http framework or even the standard `net/h In `v1/router.go` and above the handler methods, there are comments for generating swagger documentation using [swag](https://github.com/swaggo/swag). ### `internal/entity` + Entities of business logic (models) can be used in any layer. There can also be methods, for example, for validation. ### `internal/usecase` + Business logic. + - Methods are grouped by area of application (on a common basis) - Each group has its own structure - One file - one structure @@ -126,20 +148,25 @@ Repositories, webapi, rpc, and other business logic structures are injected into (see [Dependency Injection](#dependency-injection)). #### `internal/usecase/repo` + A repository is an abstract storage (database) that business logic works with. #### `internal/usecase/webapi` + It is an abstract web API that business logic works with. For example, it could be another microservice that business logic accesses via the REST API. The package name changes depending on the purpose. ### `pkg/rabbitmq` + RabbitMQ RPC pattern: + - There is no routing inside RabbitMQ - Exchange fanout is used, to which 1 exclusive queue is bound, this is the most productive config - Reconnect on the loss of connection ## Dependency Injection + In order to remove the dependence of business logic on external packages, dependency injection is used. For example, through the New constructor, we inject the dependency into the structure of the business logic. @@ -178,23 +205,28 @@ It will also allow us to do auto-generation of mocks (for example with [mockery] > If the new component implements the interface, nothing needs to be changed in the business logic. ## Clean Architecture + ### Key idea + Programmers realize the optimal architecture for an application after most of the code has been written. > A good architecture allows decisions to be delayed to as late as possible. ### The main principle -Dependency Inversion (the same one from SOLID) is the principle of dependency inversion. + +Dependency Inversion (the same one from SOLID) is the principle of dependency injection. The direction of dependencies goes from the outer layer to the inner layer. Due to this, business logic and entities remain independent from other parts of the system. So, the application is divided into 2 layers, internal and external: + 1. **Business logic** (Go standard library). 2. **Tools** (databases, servers, message brokers, any other packages and frameworks). ![Clean Architecture](docs/img/layers-1.png) **The inner layer** with business logic should be clean. It should: + - Not have package imports from the outer layer. - Use only the capabilities of the standard library. - Make calls to the outer layer through the interface (!). @@ -203,6 +235,7 @@ The business logic doesn't know anything about Postgres or a specific web API. Business logic has an interface for working with an _abstract_ database or _abstract_ web API. **The outer layer** has other limitations: + - All components of this layer are unaware of each other's existence. How to call another from one tool? Not directly, only through the inner layer of business logic. - All calls to the inner layer are made through the interface (!). - Data is transferred in a format that is convenient for business logic (`internal/entity`). @@ -217,12 +250,14 @@ The communication between them is carried out through `usecase` (business logic) usecase < repository (Postgres) HTTP < usecase ``` + The symbols > and < show the intersection of layer boundaries through Interfaces. The same is shown in the picture: ![Example](docs/img/example-http-db.png) Or more complex business logic: + ``` HTTP > usecase usecase > repository @@ -237,13 +272,14 @@ Or more complex business logic: ``` ### Layers + ![Example](docs/img/layers-2.png) ### Clean Architecture Terminology + - **Entities** are structures that business logic operates on. They are located in the `internal/entity` folder. In MVC terms, entities are models. - - **Use Cases** is business logic located in `internal/usecase`. The layer with which business logic directly interacts is usually called the _infrastructure_ layer. @@ -251,6 +287,7 @@ These can be repositories `internal/usecase/repo`, external webapi `internal/use In the template, the _infrastructure_ packages are located inside `internal/usecase`. You can choose how to call the entry points as you wish. The options are: + - controller (in our case) - delivery - transport @@ -260,6 +297,7 @@ You can choose how to call the entry points as you wish. The options are: - input ### Additional layers + The classic version of [Clean Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html) was designed for building large monolithic applications and has 4 layers. In the original version, the outer layer is divided into two more, which also have an inversion of dependencies @@ -267,21 +305,23 @@ to each other (directed inward) and communicate through interfaces. The inner layer is also divided into two (with separation of interfaces), in the case of complex logic. -_______________________________ +--- Complex tools can be divided into additional layers. However, you should add layers only if really necessary. ### Alternative approaches + In addition to Clean architecture, _Onion architecture_ and _Hexagonal_ (_Ports and adapters_) are similar to it. Both are based on the principle of Dependency Inversion. _Ports and adapters_ are very close to _Clean Architecture_, the differences are mainly in terminology. - ## Similar projects + - [https://github.com/bxcodec/go-clean-arch](https://github.com/bxcodec/go-clean-arch) - [https://github.com/zhashkevych/courses-backend](https://github.com/zhashkevych/courses-backend) ## Useful links + - [The Clean Architecture article](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html) - [Twelve factors](https://12factor.net/ru/) diff --git a/README_RU.md b/README_RU.md new file mode 100644 index 00000000..139d4164 --- /dev/null +++ b/README_RU.md @@ -0,0 +1,325 @@ +![Go Clean Template](docs/img/logo.svg) + +# Go Чистая АрхитСктура + +Π¨Π°Π±Π»ΠΎΠ½ Чистой АрхитСктурой для ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π½Π° Golang + +[![Go Report Card](https://goreportcard.com/badge/github.com/evrone/go-clean-template)](https://goreportcard.com/report/github.com/evrone/go-clean-template) +[![License](https://img.shields.io/github/license/evrone/go-clean-template.svg)](https://github.com/evrone/go-clean-template/blob/master/LICENSE) +[![Release](https://img.shields.io/github/v/release/evrone/go-clean-template.svg)](https://github.com/evrone/go-clean-template/releases/) +[![codecov](https://codecov.io/gh/evrone/go-clean-template/branch/master/graph/badge.svg?token=XE3E0X3EVQ)](https://codecov.io/gh/evrone/go-clean-template) + +## ΠžΠ±Π·ΠΎΡ€ + +ЦСль этого шаблона - ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΡ‹ Чистой АрхитСктуры Π ΠΎΠ±Π΅Ρ€Ρ‚Π° ΠœΠ°Ρ€Ρ‚ΠΈΠ½Π° (дядюшки Π‘ΠΎΠ±Π°): + +- ΠΊΠ°ΠΊ ΡΡ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ ΠΈ Π½Π΅ Π΄Π°Ρ‚ΡŒ Π΅ΠΌΡƒ ΠΏΡ€Π΅Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒΡΡ Π² спагСтти-ΠΊΠΎΠ΄ +- Π³Π΄Π΅ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ бизнСс-Π»ΠΎΠ³ΠΈΠΊΡƒ, Ρ‡Ρ‚ΠΎ Π±Ρ‹ ΠΎΠ½Π° ΠΎΡΡ‚Π°Π²Π°Π»Π°ΡΡŒ нСзависимой, чистой ΠΈ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΠΎΠΉ +- ΠΊΠ°ΠΊ Π½Π΅ ΠΏΠΎΡ‚Π΅Ρ€ΡΡ‚ΡŒ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒ ΠΏΡ€ΠΈ ростС ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° + +[Go-clean-template](https://evrone.com/go-clean-template?utm_source=github&utm_campaign=go-clean-template) создан ΠΈ поддСрТиваСтся [Evrone](https://evrone.com/?utm_source=github&utm_campaign=go-clean-template). + +## Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΠ΅ + +- [Быстрый старт](#быстрый-старт) +- [Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°](#структура-ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°) +- [Π’Π½Π΅Π΄Ρ€Π΅Π½ΠΈΠ΅ зависимостСй](#Π²Π½Π΅Π΄Ρ€Π΅Π½ΠΈΠ΅-зависимостСй) +- [Чистая АрхитСктура](#чистая-Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°) + +## Быстрый старт + +Π›ΠΎΠΊΠ°Π»ΡŒΠ½Π°Ρ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°: + +```sh +# Postgres, RabbitMQ +$ make compose-up +# Запуск прилоТСния ΠΈ ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΉ +$ make run +``` + +Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Π΅ тСсты (ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использовано с CI): + +```sh +# DB, app + migrations, integration tests +$ make compose-up-integration-test +``` + +## Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° + +### `cmd/app/main.go` + +Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΈ Π»ΠΎΠ³Π³Π΅Ρ€Π°. Π—Π΄Π΅ΡΡŒ вызываСтся основаная Ρ‡Π°ΡΡ‚ΡŒ прилоТСния ΠΈΠ· `internal/app/app.go`. + +### `config` + +ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ. Π‘Π½Π°Ρ‡Π°Π»Π° читаСтся `config.yml`, Π° Π·Π°Ρ‚Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ окруТСния. +ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ окруТСния ΠΈΠΌΠ΅ΡŽΡ‚ больший ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚, Ρ‡Π΅ΠΌ конфигурация ΠΈΠ· yaml Ρ„Π°ΠΉΠ»Π° +ΠΈ ΠΏΡ€ΠΈ совпадСнии ΠΊΠ»ΡŽΡ‡Π°, Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ бСрСтся ΠΈΠ· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… окруТСния. +Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ объявлСна Π² Ρ„Π°ΠΉΠ»Π΅ `config.go`. +Π’Π΅Π³ `env-required: true` ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ. (Π»ΠΈΠ±ΠΎ Π² yaml, Π»ΠΈΠ±ΠΎ Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… срСды). + +Для ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ [cleanenv](https://github.com/ilyakaznacheev/cleanenv). +Она простая ΠΈ соотвСтствуСт всСм нашим трСбования. + +Π§Ρ‚Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΈΠ· yaml Ρ„Π°ΠΉΠ»Π° ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΡ€Π΅Ρ‡ΠΈΡ‚ ΠΈΠ΄Π΅ΠΎΠ»ΠΎΠ³ΠΈΠΈ `Twelve-Factor App`, Π½ΠΎ Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ это Π±ΠΎΠ»Π΅Π΅ ΡƒΠ΄ΠΎΠ±Π½ΠΎ, +Ρ‡Π΅ΠΌ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΠΈΠ· ENV. +ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚ΡΡ, Ρ‡Ρ‚ΠΎ Π² yaml ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ значСния ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, Π° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, Ρ‡ΡƒΠ²ΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΊ бСзопасности +Π·Π°Π΄Π°ΡŽΡ‚ΡΡ Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ENV. + +### `docs` + +ДокумСнтация Swagger. ГСнСрируСтся автоматичСски с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ [swag](https://github.com/swaggo/swag). +Π’Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ Π½ΠΈΡ‡Π΅Π³ΠΎ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ. + +### `integration-test` + +Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Π΅ тСсты. +Они Π·Π°ΠΏΡƒΡΠΊΠ°ΡŽΡ‚ΡΡ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΌ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π΅, рядом с ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΎΠΌ прилоТСния. +Rest API ΡƒΠ΄ΠΎΠ±Π½ΠΎ Ρ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ [go-hit](https://github.com/Eun/go-hit). + +### `internal/app` + +Π—Π΄Π΅ΡΡŒ находится Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½Π° _Run_ функция. Она Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½Π° Π² Ρ„Π°ΠΉΠ»Π΅ `app.go` ΠΈ являСтся логичСским ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ _main_. + +Π—Π΄Π΅ΡΡŒ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ всС основныС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹. +[Π’Π½Π΅Π΄Ρ€Π΅Π½ΠΈΠ΅ ЗависимостСй](#Π²Π½Π΅Π΄Ρ€Π΅Π½ΠΈΠ΅-зависимостСй) происходит Ρ‡Π΅Ρ€Π΅Π· конструктор "New ...". +Π­Ρ‚Π° позволяСт ΡΠ»ΠΎΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, дСлая бизнСс-Π»ΠΎΠ³ΠΈΠΊΡƒ нСзависимой ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ΠΈΡ… слоСв. + +Π”Π°Π»Π΅Π΅, запускаСтся сСрвСр ΠΈ оТидаСтся сигнал Π² _select_ для ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ³ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹. +Если `app.go` стал слишком большим, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚ΡŒ Π΅Π³ΠΎ Π½Π° нСсколько Ρ„Π°ΠΉΠ»ΠΎΠ². + +Если зависимостСй ΠΌΠ½ΠΎΠ³ΠΎ, Ρ‚ΠΎ для удобства ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ [wire](https://github.com/google/wire). + +Π€Π°ΠΉΠ» `migrate.go` ΠΈΡΠΏΠΎΠ»ΡŒΡƒΠ·Π΅Ρ‚ΡΡ для автоматичСской ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΈ Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…. +Он Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡ†ΠΈΡŽ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ ΡƒΠΊΠ°Π·Π°Π½ΠΈΠΈ Ρ‚Π΅Π³Π° _migrate_. +ΠŸΡ€ΠΈΠΌΠ΅Ρ€: + +```sh +$ go run -tags migrate ./cmd/app +``` + +### `internal/controller` + +Π‘Π»ΠΎΠΉ хэндлСров сСрвСра (MVC ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Ρ‹). Π’ шаблонС ΠΏΠΎΠΊΠ°Π·Π°Π½Π° Ρ€Π°Π±ΠΎΡ‚Π° 2Ρ… сСрвСров: + +- RPC (RabbitMQ as transport) +- REST http (Gin framework) + +ΠœΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ‚ΠΎΡ€Ρ‹ http сСрвСра ΠΏΠΈΡˆΡƒΡ‚ΡΡ Π² Π΅Π΄ΠΈΠ½ΠΎΠΌ стилС: + +- Π₯эндлСры ΡΠ³Ρ€ΡƒΠΏΠΏΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΏΠΎ области примСнСния (ΠΏΠΎ ΠΎΠ±Ρ‰Π΅ΠΌΡƒ ΠΊΡ€ΠΈΡ‚Π΅Ρ€ΠΈΡŽ) +- Для ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π³Ρ€ΡƒΠΏΠΏΡ‹ создаСтся свой ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ‚ΠΎΡ€ +- ΠžΠ±ΡŠΠ΅ΠΊΡ‚ бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΈ пСрСдаСтся Π² ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ‚ΠΎΡ€, Ρ‡Ρ‚ΠΎ Π±Ρ‹ Π±Ρ‹Ρ‚ΡŒ доступным Π²Π½ΡƒΡ‚Ρ€ΠΈ хэндлСров + +#### `internal/controller/http/v1` + +Папка, ΠΊΠ°ΠΊ простой способ Π²Π΅Ρ€ΡΠΈΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ REST API. +Для создания вСрсии v2, Π½ΡƒΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΏΠ°ΠΏΠΊΡƒ `http/v2` с Ρ‚Π°ΠΊΠΈΠΌ ΠΆΠ΅ содСрТимым. +Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π² Ρ„Π°ΠΉΠ» `internal/app/app.go` строки: + +```go +handler := gin.New() +v1.NewRouter(handler, t) +v2.NewRouter(handler, t) +``` + +ВмСсто Gin ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ любой Π΄Ρ€ΡƒΠ³ΠΎΠΉ http Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ ΠΈΠ»ΠΈ ΡΡ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½ΡƒΡŽ `net/http` Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ. + +Π’ Ρ„Π°ΠΉΠ»Π΅ `v1/router.go` Π½Π°Π΄ хэндлСром написаны ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ для Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ Ρ‡Π΅Ρ€Π΅Π· swagger [swag](https://github.com/swaggo/swag). + +### `internal/entity` + +Бущности бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΈ (ΠΌΠΎΠ΄Π΅Π»ΠΈ). ΠœΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½Ρ‹ Π² любом слоС. +Π’Π°ΠΊΠΆΠ΅ ΠΎΠ½ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ΡŒ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, для Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ. + +### `internal/usecase` + +БизнСс-Π»ΠΎΠ³ΠΈΠΊΠ°. + +- ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ сгруппированы ΠΏΠΎ области примСнСния (ΠΏΠΎ ΠΎΠ±Ρ‰Π΅ΠΌΡƒ ΠΊΡ€ΠΈΡ‚Π΅Ρ€ΠΈΡŽ) +- Π£ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π³Ρ€ΡƒΠΏΠΏΡ‹ своя ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Π°Ρ структура +- Один Ρ„Π°ΠΉΠ» - ΠΎΠ΄Π½Π° структура + +Π Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ, webapi, rpc ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ структуры ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ Π² слой бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΈ Π² ΡΠ²ΡΠ·ΡƒΡŽΡ‰Π΅ΠΌ Ρ„Π°ΠΉΠ»Π΅ `internal/app/app.go` +(смотритС [Π’Π½Π΅Π΄Ρ€Π΅Π½ΠΈΠ΅ ЗависимостСй](#Π²Π½Π΅Π΄Ρ€Π΅Π½ΠΈΠ΅-зависимостСй)). + +#### `internal/usecase/repo` + +Π Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ β€” это абстрактноС Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ (Π±Π°Π·Π° Π΄Π°Π½Π½Ρ‹Ρ…), с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ взаимодСйствуСт бизнСс-Π»ΠΎΠ³ΠΈΠΊΠ°. + +#### `internal/usecase/webapi` + +Π­Ρ‚ΠΎ абстрактноС web API, с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ взаимодСйствуСт бизнСс-Π»ΠΎΠ³ΠΈΠΊΠ°. +НапримСр, это ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ внСшний микросСрвис, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ бизнСс-Π»ΠΎΠ³ΠΈΠΊΠ° обращаСтся Ρ‡Π΅Ρ€Π΅Π· REST API. +НазваниС ΠΏΠ°ΠΊΠ΅Ρ‚Π° выбираСтся Ρ‚Π°ΠΊΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π±Ρ‹ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ. + +### `pkg/rabbitmq` + +RabbitMQ RPC ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½: + +- Π’Π½ΡƒΡ‚Ρ€ΠΈ RabbitMQ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ†ΠΈΡ +- Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ fanout-ΠΎΠ±ΠΌΠ΅Π½, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ привязана ΠΎΠ΄Π½Π° эксклюзивная ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ - это Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ конфигурация +- ΠŸΠ΅Ρ€Π΅ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈ ΠΏΠΎΡ‚Π΅Ρ€Π΅ соСдинСния + +## Π’Π½Π΅Π΄Ρ€Π΅Π½ΠΈΠ΅ ЗависимостСй + +Для устранСния зависимости бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΈ ΠΎΡ‚ Π²Π½Π΅ΡˆΠ½ΠΈΡ… ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π²Π½Π΅Π΄Ρ€Π΅Π½ΠΈΠ΅ зависимостСй. + +НапримСр, Ρ‡Π΅Ρ€Π΅Π· конструктор "New" внСдряСтся Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ Π² слой бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΈ. +Π­Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ бизнСс-Π»ΠΎΠ³ΠΈΠΊΡƒ нСзависимой ΠΈ пСрСносимой. +ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ интСрфСйса рСпозитория Π½Π΅ внося измСнСния Π² ΠΏΠ°ΠΊΠ΅Ρ‚ бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΈ `usecase`. + +```go +package usecase + +import ( + // Nothing! +) + +type Repository interface { + Get() +} + +type UseCase struct { + repo Repository +} + +func New(r Repository) *UseCase{ + return &UseCase{ + repo: r, + } +} + +func (uc *UseCase) Do() { + uc.repo.Get() +} +``` + +Благодаря Ρ€Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΡŽ Ρ‡Π΅Ρ€Π΅Π· интСрфСйсы ΠΌΠΎΠΆΠ½ΠΎ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠΎΠΊΠΈ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ [mockery](https://github.com/vektra/mockery)) ΠΈ Π»Π΅Π³ΠΊΠΎ ΠΏΠΈΡΠ°Ρ‚ΡŒ ΡŽΠ½ΠΈΡ‚-тСсты. + +> ΠœΡ‹ Π½Π΅ привязаны ΠΊ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΌ рСализациям ΠΈ всСгда ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π½Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ. +> Если Π½ΠΎΠ²Ρ‹ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ интСрфСйс, Ρ‚ΠΎ Π² бизнСс-Π»ΠΎΠ³ΠΈΠΊΠ΅ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΠΌΠ΅Π½ΡΡ‚ΡŒ. + +## Чистая АрхитСктура + +### ΠšΠ»ΡŽΡ‡Π΅Π²Π°Ρ идСя + +ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡΡ‚Ρ‹ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½ΡƒΡŽ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρƒ прилоТСния послС написания основной части ΠΊΠΎΠ΄Π°. + +> Π₯ΠΎΡ€ΠΎΡˆΠ°Ρ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° позволяСт ΠΎΡ‚ΠΊΠ»Ρ‹Π΄Ρ‹Π²Π°Ρ‚ΡŒ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ дольшС. + +### Основной ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ + +Π˜Π½Π²Π΅Ρ€ΡΠΈΡ зависимостСй (Ρ‚Π° ΠΆΠ΅, Ρ‡Ρ‚ΠΎ ΠΈ Π² SOLID) ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΊΠ°ΠΊ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ для внСдрСния зависимостСй. +Зависимости Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Ρ‹ ΠΎΡ‚ внСшнСго слоя ΠΊ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅ΠΌΡƒ. +Благодаря этому бизнСс-Π»ΠΎΠ³ΠΈΠΊΠ° ΠΈ сущности ΠΎΡΡ‚Π°ΡŽΡ‚ΡΡ нСзависимыми ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ΠΈΡ… частСй систСмы. + +НапримСр, ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚ΡŒ Π½Π° Π΄Π²Π° слоя - Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΉ ΠΈ внСшний: + +1. **БизнСс-Π»ΠΎΠ³ΠΈΠΊΠ°** (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, стандартная Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Go). +2. **Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚Ρ‹** (Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…, сСрвСра, Π±Ρ€ΠΎΠΊΠ΅Ρ€Ρ‹ сообщСний ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ΠΈ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠΈ). + +![Чистая Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°](docs/img/layers-1.png) + +**Π’Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΉ слой** с бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ чистым. Он обязан: + +- НС ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ°ΠΊΠ΅Ρ‚Ρ‹ с Π²Π½Π΅ΡˆΠ½ΠΈΡ… слоСв. +- Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΡΡ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½ΡƒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ. +- Π’Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ с внСшними слоями Ρ‡Π΅Ρ€Π΅Π· интСрфСйсы (!). + +БизнСс-Π»ΠΎΠ³ΠΈΠΊΠ° Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Π° Π½ΠΈΡ‡Π΅Π³ΠΎ Π·Π½Π°Ρ‚ΡŒ ΠΎ Postgres ΠΈΠ»ΠΈ ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ web API. +БизнСс-Π»ΠΎΠ³ΠΈΠΊΠ° ΠΈΠΌΠ΅Π΅Ρ‚ интСрфСйс для взаимодСйсвтия с _абстрактной_ Π±Π°Π·ΠΎΠΉ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ»ΠΈ _абстрактным_ web API. + +**Π’Π½Π΅ΡˆΠ½ΠΈΠΉ слой** ΠΈΠΌΠ΅Π΅Ρ‚ ограничСния: + +- ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ этого слоя Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π·Π½Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ ΠΎ Π΄Ρ€ΡƒΠ³Π΅ ΠΈ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²Π°Ρ‚ΡŒ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ. ΠžΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ Π΄Ρ€ΡƒΠ³ ΠΊ Π΄Ρ€ΡƒΠ³Ρƒ происходит Ρ‡Π΅Ρ€Π΅Π· Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΉ слой - слой бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΈ. +- Π’Ρ‹Π·ΠΎΠ²Ρ‹ Π²ΠΎ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΉ слой Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· интСрфСйсы (!). +- Π”Π°Π½Π½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅, ΡƒΠ΄ΠΎΠ±Π½ΠΎΠΌ для бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΈ (структуры хранятся Π² `internal/entity`). + +НапримСр, Π½ΡƒΠΆΠ½ΠΎ ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚ΡŒΡΡ ΠΊ Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· HTTP хэндСра (Π² слоС ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€). +Π‘Π°Π·Π° Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ HTTP находятся Π²ΠΎ внСшнСм слоС. Они Π½Π΅ знаю Π΄Ρ€ΡƒΠ³ ΠΎ Π΄Ρ€ΡƒΠ³Π΅ Π½ΠΈΡ‡Π΅Π³ΠΎ ΠΈ Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ. +ВзаимодСйствиС Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΎΠΈΡΡ…ΠΎΠ΄ΠΈΡ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· слой бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΈ `usecase`: + +``` + HTTP > usecase + usecase > repository (Postgres) + usecase < repository (Postgres) + HTTP < usecase +``` + +Π‘ΠΈΠΌΠ²ΠΎΠ»Ρ‹ > ΠΈ < ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ пСрСсСчСния слоСв Ρ‡Π΅Ρ€Π΅Π· интСрфСйсы ΠΈ направлСния. +Π­Ρ‚ΠΎ ΠΆΠ΅ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π½Π° схСмС: + +![ΠŸΡ€ΠΈΠΌΠ΅Ρ€](docs/img/example-http-db.png) + +ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π±ΠΎΠ»Π΅Π΅ слоТного ΠΏΡƒΡ‚ΠΈ Π΄Π°Π½Π½Ρ‹Ρ…: + +``` + HTTP > usecase + usecase > repository + usecase < repository + usecase > webapi + usecase < webapi + usecase > RPC + usecase < RPC + usecase > repository + usecase < repository + HTTP < usecase +``` + +### Π‘Π»ΠΎΠΈ + +![ΠŸΡ€ΠΈΠΌΠ΅Ρ€](docs/img/layers-2.png) + +### ВСрминология Π² Чистой АрхитСктурС + +- **Entities** (сущности) - это структуры, с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ бизнСс Π»ΠΎΠ³ΠΈΠΊΠ°. + Они Ρ€Π°ΡΠΏΠΎΠ»Π°Π³Π°ΡŽΡ‚ΡΡ Π² ΠΏΠ°ΠΏΠΊΠ΅ `internal/entity`. + Π’ Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΎΠ»ΠΎΠ³ΠΈΠΈ MVC сущности - это ΠΌΠΎΠ΄Π΅Π»ΠΈ. +- **Use Cases** это бизнСс-Π»ΠΎΠ³ΠΈΠΊΠ°. РасполагаСтся Π² ΠΏΠ°ΠΏΠΊΠ΅ `internal/usecase`. + +Π‘Π»ΠΎΠΉ, с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ бизнСс-Π»ΠΎΠ³ΠΈΠΊΠ° взаимодСйствуСт Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ, ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ, называСтся _инфраструктурным_ слоСм. +Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ `internal/usecase/repo`, внСшнСС webapi `internal/usecase/webapi`, любой ΠΏΠ°ΠΊΠ΅Ρ‚ ΠΈΠ»ΠΈ микросСрвис. +Π’ шаблонС ΠΏΠ°ΠΊΠ΅Ρ‚Ρ‹ _infrastructure_ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½Ρ‹ Π²Π½ΡƒΡ‚Ρ€ΠΈ `internal/usecase`. + +Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²Ρ‹Π±ΠΈΡ€Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊ Π½Π°Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ‚ΠΎΡ‡ΠΊΠΈ Π²Ρ…ΠΎΠ΄Π°, ΠΏΠΎ своСму ΡƒΡΠΌΠΎΡ‚Ρ€Π΅Π½ΠΈΡŽ. Π’Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ Ρ‚Π°ΠΊΠΈΠ΅: + +- controller (Π² нашСм случаС) +- delivery +- transport +- gateways +- entrypoints +- primary +- input + +### Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ слои + +Π’ классичСской вСрсии [Чистой АрхитСктуры](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html) для создания Π±ΠΎΠ»ΡŒΡˆΠΈΡ… ΠΌΠΎΠ½ΠΎΠ»ΠΈΡ‚Π½Ρ‹Ρ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΎ 4 слоя. + +Π’ исходной вСрсии внСшний слой дСлится Π½Π° Π΄Π²Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΠΌΠ΅ΡŽΡ‚ ΠΈΠ½Π²Π΅Ρ€ΡΠΈΡŽ зависимостСй Π² Π΄Ρ€ΡƒΠ³ΠΈΠ΅ слои ΠΈ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‚ Ρ‡Π΅Ρ€Π΅Π· интСрфСсы. + +Π’Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΉ слой Ρ‚Π°ΠΊΠΆΠ΅ дСлится Π½Π° Π΄Π²Π° (с использованиСм интСрфСйсов) Π² случаС слоТной Π»ΠΎΠ³ΠΈΠΊΠΈ. + +--- + +Π‘Π»ΠΎΠΆΠ½Ρ‹Π΅ инструмСнты ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π·Π΄Π΅Π»Π΅Π½Ρ‹ Π½Π° Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ слои. +Однако Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ слои слСдуСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Ρ‚ΠΎΠΌ случаС, Ссли это Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ. + +### Π”Ρ€ΡƒΠ³ΠΈΠ΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Ρ‹ + +ΠšΡ€ΠΎΠΌΠ΅ Чистой АрхитСктуры Π΅ΡΡ‚ΡŒ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΏΠΎΠ΄ΠΎΡ…ΠΎΠ΄Ρ‹: + +- Луковая АрхитСктура +- Π“Π΅ΠΊΡΠΎΠ³ΠΎΠ½Π°Π»ΡŒΠ½Π°Ρ (_ΠŸΠΎΡ€Ρ‚Ρ‹ ΠΈ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Ρ‹_ Ρ‚Π°ΠΊΠΆΠ΅ Π½Π° Π½Π΅Ρ‘ ΠΏΠΎΡ…ΠΎΠΆΠ°) + Они ΠΎΠ±Π΅ основаны Π½Π° Π½Π° ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ΅ инвСрсии зависимостСй. + _ΠŸΠΎΡ€Ρ‚Ρ‹ ΠΈ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Ρ‹_ ΠΎΡ‡Π΅Π½ΡŒ ΠΏΠΎΡ…ΠΎΠΆΠΈ Π½Π° _Π§ΠΈΡΡ‚ΡƒΡŽ АрхитСктуру_. Различия Π² основном Π·Π°ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ΡΡ Π² Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΎΠ»ΠΎΠ³ΠΈΠΈ. + +## ΠŸΠΎΡ…ΠΎΠΆΠΈΠ΅ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρ‹ + +- [https://github.com/bxcodec/go-clean-arch](https://github.com/bxcodec/go-clean-arch) +- [https://github.com/zhashkevych/courses-backend](https://github.com/zhashkevych/courses-backend) + +## Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ информация + +- [The Clean Architecture article](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html) +- [Twelve factors](https://12factor.net/ru/)