├── .gitignore
├── .idea
├── .gitignore
├── golang-architecture.iml
├── modules.xml
└── vcs.xml
├── factory
├── factory.go
├── go.mod
└── test
│ └── test.go
├── hexagonal-news-api
├── .idea
│ ├── .gitignore
│ ├── hexagonal-news-api.iml
│ ├── modules.xml
│ └── vcs.xml
├── adapter
│ ├── input
│ │ ├── controller
│ │ │ └── news_controller.go
│ │ ├── model
│ │ │ └── request
│ │ │ │ └── news_request.go
│ │ └── routes
│ │ │ └── routes.go
│ └── output
│ │ ├── model
│ │ └── response
│ │ │ └── news_client_response.go
│ │ └── news_http
│ │ └── news_api_client.go
├── application
│ ├── domain
│ │ └── news_domain.go
│ ├── port
│ │ ├── input
│ │ │ └── news_use_case.go
│ │ └── output
│ │ │ └── news_port.go
│ └── service
│ │ └── news_service.go
├── configuration
│ ├── env
│ │ └── get_env.go
│ ├── logger
│ │ └── logger.go
│ ├── rest_err
│ │ └── rest_err.go
│ └── validation
│ │ └── validate.go
├── go.mod
├── go.sum
└── main.go
├── hexagonal
├── .gitignore
├── adapter
│ ├── input
│ │ ├── controller
│ │ │ ├── create_user_controller.go
│ │ │ ├── find_user_controller.go
│ │ │ ├── middlewares
│ │ │ │ └── jwt_middleware.go
│ │ │ └── routes
│ │ │ │ └── routes.go
│ │ ├── converter
│ │ │ └── convert_domain_to_response.go
│ │ └── model
│ │ │ ├── request
│ │ │ └── user_request.go
│ │ │ └── response
│ │ │ └── user_response.go
│ └── output
│ │ ├── converter
│ │ ├── convert_domain_to_entity.go
│ │ └── convert_entity_to_domain.go
│ │ ├── model
│ │ └── entity
│ │ │ └── user_entity.go
│ │ └── repository
│ │ ├── create_user_repository.go
│ │ └── find_user_repository.go
├── application
│ ├── constants
│ │ └── token.go
│ ├── domain
│ │ ├── user_domain.go
│ │ └── user_token_domain.go
│ ├── port
│ │ ├── input
│ │ │ └── users_use_case.go
│ │ └── output
│ │ │ └── user_port.go
│ └── services
│ │ ├── create_user.go
│ │ └── find_user.go
├── configuration
│ ├── database
│ │ └── mongodb
│ │ │ └── mongodb_connection.go
│ ├── logger
│ │ └── logger.go
│ ├── rest_errors
│ │ └── rest_errors.go
│ └── validation
│ │ └── validate.go
├── crud_users.http
├── go.mod
├── go.sum
└── main.go
├── mvc
├── go.mod
├── go.sum
├── main.go
└── src
│ ├── controller
│ ├── user-form.go
│ └── user.go
│ ├── models
│ ├── repository
│ │ └── user.go
│ └── user.go
│ └── views
│ ├── errors.go
│ └── user.go
├── singleton
├── .env
├── go.mod
├── go.sum
└── singleton.go
└── solid
├── dependency-inversion-principle
└── dip.go
├── go.mod
├── interface-segregration-principle
└── main.go
├── liskov-substitution-principle
└── main.go
├── open-closed-principle
├── right_way.go
└── wrong_way.go
└── single-responsibility-principle
├── god_object.go
├── journal.go
├── load_news.go
└── printer.go
/.gitignore:
--------------------------------------------------------------------------------
1 | # Binaries for programs and plugins
2 | *.exe
3 | *.exe~
4 | *.dll
5 | *.so
6 | *.dylib
7 |
8 | # Test binary, built with `go test -c`
9 | *.test
10 |
11 | # Output of the go coverage tool, specifically when used with LiteIDE
12 | *.out
13 |
14 | # Dependency directories (remove the comment below to include it)
15 | # vendor/
16 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/.idea/golang-architecture.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/factory/factory.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/HunCoding/golang-architecture/factory/test"
7 | )
8 |
9 | func main() {
10 | c := test.NovoVeiculo(20)
11 | fmt.Println(c)
12 | }
13 |
--------------------------------------------------------------------------------
/factory/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/HunCoding/golang-architecture/factory
2 |
3 | go 1.18
4 |
--------------------------------------------------------------------------------
/factory/test/test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import "fmt"
4 |
5 | type Veiculo interface {
6 | PrintarQuantidadeRodas()
7 | }
8 |
9 | func NovoVeiculo(qtdRodas int) Veiculo {
10 | if qtdRodas < 0 || qtdRodas > 4 {
11 | return nil
12 | }
13 |
14 | if qtdRodas == 2 {
15 | return &moto{qtdRodas: qtdRodas}
16 | } else if qtdRodas == 4 {
17 | return &carro{qtdRodas: qtdRodas}
18 | }
19 |
20 | return nil
21 | }
22 |
23 | type moto struct {
24 | qtdRodas int
25 | preco float64
26 | }
27 |
28 | func (c *moto) PrintarQuantidadeRodas() {
29 | fmt.Println(c.qtdRodas)
30 | }
31 |
32 | func (c *carro) PrintarQuantidadeRodas() {
33 | fmt.Println(c.qtdRodas)
34 | }
35 |
36 | type carro struct {
37 | qtdRodas int
38 | preco float64
39 | }
40 |
41 | func (c *carro) DefinePreco(preco float64) {
42 | if preco < 5000 || preco > 1000000000 {
43 | fmt.Println("Nao é permitido esse valor")
44 | return
45 | }
46 |
47 | c.preco = preco
48 | }
49 |
50 | func (c *carro) DefineQtdRodas(qtdRodas int) {
51 | if qtdRodas < 0 || qtdRodas > 4 {
52 | fmt.Println("Nao é permitido esse valor")
53 | return
54 | }
55 |
56 | c.qtdRodas = qtdRodas
57 | }
58 |
--------------------------------------------------------------------------------
/hexagonal-news-api/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/hexagonal-news-api/.idea/hexagonal-news-api.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/hexagonal-news-api/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/hexagonal-news-api/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/hexagonal-news-api/adapter/input/controller/news_controller.go:
--------------------------------------------------------------------------------
1 | package controller
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/adapter/input/model/request"
7 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/application/domain"
8 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/application/port/input"
9 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/configuration/logger"
10 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/configuration/validation"
11 | "github.com/gin-gonic/gin"
12 | )
13 |
14 | type newsController struct {
15 | newsUseCase input.NewsUseCase
16 | }
17 |
18 | func NewNewsController(
19 | newsUseCase input.NewsUseCase,
20 | ) *newsController {
21 | return &newsController{newsUseCase}
22 | }
23 |
24 | func (nc *newsController) GetNews(c *gin.Context) {
25 | //q=tesla&from=2023-08-20&apiKey=df969581143d4958a630cb3d0efeaf21
26 | logger.Info("Init GetNews controller api")
27 | newsRequest := request.NewsRequest{}
28 |
29 | if err := c.ShouldBindQuery(&newsRequest); err != nil {
30 | logger.Error("Error trying to validate fields from request", err)
31 | errRest := validation.ValidateUserError(err)
32 | c.JSON(errRest.Code, errRest)
33 | return
34 | }
35 |
36 | newsDomain := domain.NewsReqDomain{
37 | Subject: newsRequest.Subject,
38 | From: newsRequest.From.Format("2006-01-02"),
39 | }
40 |
41 | newsResponseDomain, err := nc.newsUseCase.GetNewsService(newsDomain)
42 | if err != nil {
43 | c.JSON(err.Code, err)
44 | return
45 | }
46 |
47 | c.JSON(http.StatusOK, newsResponseDomain)
48 | }
49 |
--------------------------------------------------------------------------------
/hexagonal-news-api/adapter/input/model/request/news_request.go:
--------------------------------------------------------------------------------
1 | package request
2 |
3 | import "time"
4 |
5 | type NewsRequest struct {
6 | Subject string `form:"subject" binding:"required,min=2" `
7 | From time.Time `form:"from" binding:"required" time_format:"2006-01-02"`
8 | }
9 |
--------------------------------------------------------------------------------
/hexagonal-news-api/adapter/input/routes/routes.go:
--------------------------------------------------------------------------------
1 | package routes
2 |
3 | import (
4 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/adapter/input/controller"
5 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/adapter/output/news_http"
6 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/application/service"
7 | "github.com/gin-gonic/gin"
8 | )
9 |
10 | func InitRoutes(r *gin.Engine) {
11 | newsClient := news_http.NewNewsClient()
12 | newsService := service.NewNewsService(newsClient)
13 | newsController := controller.NewNewsController(newsService)
14 |
15 | r.GET("/news", newsController.GetNews)
16 | }
17 |
--------------------------------------------------------------------------------
/hexagonal-news-api/adapter/output/model/response/news_client_response.go:
--------------------------------------------------------------------------------
1 | package response
2 |
3 | type NewsClientResponse struct {
4 | Status string
5 | TotalResults int64
6 | Articles []ArticleResponse
7 | }
8 |
9 | type ArticleResponse struct {
10 | Source ArticleSourceResponse
11 | Author string
12 | Title string
13 | Description string
14 | URL string
15 | URLToImage string
16 | PublishedAt string
17 | Content string
18 | }
19 |
20 | type ArticleSourceResponse struct {
21 | ID *string
22 | Name string
23 | }
24 |
--------------------------------------------------------------------------------
/hexagonal-news-api/adapter/output/news_http/news_api_client.go:
--------------------------------------------------------------------------------
1 | package news_http
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/adapter/output/model/response"
7 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/application/domain"
8 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/configuration/env"
9 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/configuration/rest_err"
10 | "github.com/go-resty/resty/v2"
11 | "github.com/jinzhu/copier"
12 | )
13 |
14 | type newsClient struct{}
15 |
16 | func NewNewsClient() *newsClient {
17 | client = resty.New().SetBaseURL("https://newsapi.org/v2")
18 | return &newsClient{}
19 | }
20 |
21 | var (
22 | client *resty.Client
23 | )
24 |
25 | func (nc *newsClient) GetNewsPort(
26 | newsDomain domain.NewsReqDomain) (*domain.NewsDomain, *rest_err.RestErr) {
27 |
28 | newsResponse := &response.NewsClientResponse{}
29 |
30 | _, err := client.R().
31 | SetQueryParams(map[string]string{
32 | "q": newsDomain.Subject,
33 | "from": newsDomain.From,
34 | "apiKey": env.GetNewsTokenAPI(),
35 | }).
36 | SetResult(newsResponse).
37 | Get("/everything")
38 |
39 | fmt.Println(err)
40 | if err != nil {
41 | return nil, rest_err.NewInternalServerError("Error trying to call NewsAPI with params")
42 | }
43 |
44 | newsResponseDomain := &domain.NewsDomain{}
45 | copier.Copy(newsResponseDomain, newsResponse)
46 |
47 | return newsResponseDomain, nil
48 | }
49 |
--------------------------------------------------------------------------------
/hexagonal-news-api/application/domain/news_domain.go:
--------------------------------------------------------------------------------
1 | package domain
2 |
3 | type NewsReqDomain struct {
4 | Subject string
5 | From string
6 | }
7 |
8 | type NewsDomain struct {
9 | Status string
10 | TotalResults string
11 | Articles []Article
12 | }
13 |
14 | type Article struct {
15 | Source ArticleSourceResponse
16 | Author string
17 | Title string
18 | Description string
19 | URL string
20 | URLToImage string
21 | PublishedAt string
22 | Content string
23 | }
24 |
25 | type ArticleSourceResponse struct {
26 | ID *string
27 | Name string
28 | }
29 |
--------------------------------------------------------------------------------
/hexagonal-news-api/application/port/input/news_use_case.go:
--------------------------------------------------------------------------------
1 | package input
2 |
3 | import (
4 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/application/domain"
5 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/configuration/rest_err"
6 | )
7 |
8 | type NewsUseCase interface {
9 | GetNewsService(
10 | domain.NewsReqDomain,
11 | ) (*domain.NewsDomain, *rest_err.RestErr)
12 | }
13 |
--------------------------------------------------------------------------------
/hexagonal-news-api/application/port/output/news_port.go:
--------------------------------------------------------------------------------
1 | package output
2 |
3 | import (
4 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/application/domain"
5 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/configuration/rest_err"
6 | )
7 |
8 | type NewsPort interface {
9 | GetNewsPort(domain.NewsReqDomain) (*domain.NewsDomain, *rest_err.RestErr)
10 | }
11 |
--------------------------------------------------------------------------------
/hexagonal-news-api/application/service/news_service.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/application/domain"
7 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/application/port/output"
8 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/configuration/logger"
9 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/configuration/rest_err"
10 | )
11 |
12 | type newsService struct {
13 | newsPort output.NewsPort
14 | }
15 |
16 | func NewNewsService(newsPort output.NewsPort) *newsService {
17 | return &newsService{newsPort}
18 | }
19 |
20 | func (ns *newsService) GetNewsService(
21 | newsDomain domain.NewsReqDomain,
22 | ) (*domain.NewsDomain, *rest_err.RestErr) {
23 | logger.Info(
24 | fmt.Sprintf("Init getNewsService function, subject=%s, from=%s",
25 | newsDomain.Subject, newsDomain.From))
26 |
27 | newsDomainResponse, err := ns.newsPort.GetNewsPort(newsDomain)
28 | return newsDomainResponse, err
29 | }
30 |
--------------------------------------------------------------------------------
/hexagonal-news-api/configuration/env/get_env.go:
--------------------------------------------------------------------------------
1 | package env
2 |
3 | import "os"
4 |
5 | func GetNewsTokenAPI() string {
6 | return os.Getenv("NEWS_API_KEY")
7 | }
8 |
--------------------------------------------------------------------------------
/hexagonal-news-api/configuration/logger/logger.go:
--------------------------------------------------------------------------------
1 | package logger
2 |
3 | import (
4 | "os"
5 | "strings"
6 |
7 | "go.uber.org/zap"
8 | "go.uber.org/zap/zapcore"
9 | )
10 |
11 | var (
12 | log *zap.Logger
13 |
14 | LOG_OUTPUT = "LOG_OUTPUT"
15 | LOG_LEVEL = "LOG_LEVEL"
16 | )
17 |
18 | func init() {
19 | logConfig := zap.Config{
20 | OutputPaths: []string{getOutputLogs()},
21 | Level: zap.NewAtomicLevelAt(getLevelLogs()),
22 | Encoding: "json",
23 | EncoderConfig: zapcore.EncoderConfig{
24 | LevelKey: "level",
25 | TimeKey: "time",
26 | MessageKey: "message",
27 | EncodeTime: zapcore.ISO8601TimeEncoder,
28 | EncodeLevel: zapcore.LowercaseLevelEncoder,
29 | EncodeCaller: zapcore.ShortCallerEncoder,
30 | },
31 | }
32 |
33 | log, _ = logConfig.Build()
34 | }
35 |
36 | func Info(message string, tags ...zap.Field) {
37 | log.Info(message, tags...)
38 | log.Sync()
39 | }
40 |
41 | func Error(message string, err error, tags ...zap.Field) {
42 | tags = append(tags, zap.NamedError("error", err))
43 | log.Info(message, tags...)
44 | log.Sync()
45 | }
46 |
47 | func getOutputLogs() string {
48 | output := strings.ToLower(strings.TrimSpace(os.Getenv(LOG_OUTPUT)))
49 | if output == "" {
50 | return "stdout"
51 | }
52 |
53 | return output
54 | }
55 |
56 | func getLevelLogs() zapcore.Level {
57 | switch strings.ToLower(strings.TrimSpace(os.Getenv(LOG_LEVEL))) {
58 | case "info":
59 | return zapcore.InfoLevel
60 | case "error":
61 | return zapcore.ErrorLevel
62 | case "debug":
63 | return zapcore.DebugLevel
64 | default:
65 | return zapcore.InfoLevel
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/hexagonal-news-api/configuration/rest_err/rest_err.go:
--------------------------------------------------------------------------------
1 | package rest_err
2 |
3 | import "net/http"
4 |
5 | type RestErr struct {
6 | Message string `json:"message"`
7 | Err string `json:"error"`
8 | Code int `json:"code"`
9 | Causes []Causes `json:"causes"`
10 | }
11 |
12 | type Causes struct {
13 | Field string `json:"field"`
14 | Message string `json:"message"`
15 | }
16 |
17 | func (r *RestErr) Error() string {
18 | return r.Message
19 | }
20 |
21 | func NewRestErr(message, err string, code int, causes []Causes) *RestErr {
22 | return &RestErr{
23 | Message: message,
24 | Err: err,
25 | Code: code,
26 | Causes: causes,
27 | }
28 | }
29 |
30 | func NewBadRequestError(message string) *RestErr {
31 | return &RestErr{
32 | Message: message,
33 | Err: "bad_request",
34 | Code: http.StatusBadRequest,
35 | }
36 | }
37 |
38 | func NewUnauthorizedRequestError(message string) *RestErr {
39 | return &RestErr{
40 | Message: message,
41 | Err: "unauthorized",
42 | Code: http.StatusUnauthorized,
43 | }
44 | }
45 |
46 | func NewBadRequestValidationError(message string, causes []Causes) *RestErr {
47 | return &RestErr{
48 | Message: message,
49 | Err: "bad_request",
50 | Code: http.StatusBadRequest,
51 | Causes: causes,
52 | }
53 | }
54 |
55 | func NewInternalServerError(message string) *RestErr {
56 | return &RestErr{
57 | Message: message,
58 | Err: "internal_server_error",
59 | Code: http.StatusInternalServerError,
60 | }
61 | }
62 |
63 | func NewNotFoundError(message string) *RestErr {
64 | return &RestErr{
65 | Message: message,
66 | Err: "not_found",
67 | Code: http.StatusNotFound,
68 | }
69 | }
70 |
71 | func NewForbiddenError(message string) *RestErr {
72 | return &RestErr{
73 | Message: message,
74 | Err: "forbidden",
75 | Code: http.StatusForbidden,
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/hexagonal-news-api/configuration/validation/validate.go:
--------------------------------------------------------------------------------
1 | package validation
2 |
3 | import (
4 | "encoding/json"
5 | "errors"
6 |
7 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/configuration/rest_err"
8 | "github.com/gin-gonic/gin/binding"
9 | "github.com/go-playground/locales/en"
10 | ut "github.com/go-playground/universal-translator"
11 | "github.com/go-playground/validator/v10"
12 |
13 | en_translation "github.com/go-playground/validator/v10/translations/en"
14 | )
15 |
16 | var (
17 | Validate = validator.New()
18 | transl ut.Translator
19 | )
20 |
21 | func init() {
22 | if val, ok := binding.Validator.Engine().(*validator.Validate); ok {
23 | en := en.New()
24 | unt := ut.New(en, en)
25 | transl, _ = unt.GetTranslator("en")
26 | en_translation.RegisterDefaultTranslations(val, transl)
27 | }
28 | }
29 |
30 | func ValidateUserError(
31 | validation_err error,
32 | ) *rest_err.RestErr {
33 |
34 | var jsonErr *json.UnmarshalTypeError
35 | var jsonValidationError validator.ValidationErrors
36 |
37 | if errors.As(validation_err, &jsonErr) {
38 | return rest_err.NewBadRequestError("Invalid field type")
39 | } else if errors.As(validation_err, &jsonValidationError) {
40 | errorsCauses := []rest_err.Causes{}
41 |
42 | for _, e := range validation_err.(validator.ValidationErrors) {
43 | cause := rest_err.Causes{
44 | Message: e.Translate(transl),
45 | Field: e.Field(),
46 | }
47 |
48 | errorsCauses = append(errorsCauses, cause)
49 | }
50 |
51 | return rest_err.NewBadRequestValidationError("Some fields are invalid", errorsCauses)
52 | } else {
53 | return rest_err.NewBadRequestError("Error trying to convert fields")
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/hexagonal-news-api/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/HunCoding/golang-architecture/hexagonal-news-api
2 |
3 | go 1.20
4 |
5 | require (
6 | github.com/gin-gonic/gin v1.9.1
7 | go.uber.org/zap v1.26.0
8 | )
9 |
10 | require github.com/joho/godotenv v1.5.1 // indirect
11 |
12 | require (
13 | github.com/bytedance/sonic v1.9.1 // indirect
14 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
15 | github.com/gabriel-vasile/mimetype v1.4.2 // indirect
16 | github.com/gin-contrib/sse v0.1.0 // indirect
17 | github.com/go-playground/locales v0.14.1 // indirect
18 | github.com/go-playground/universal-translator v0.18.1 // indirect
19 | github.com/go-playground/validator/v10 v10.14.0 // indirect
20 | github.com/go-resty/resty/v2 v2.8.0
21 | github.com/goccy/go-json v0.10.2 // indirect
22 | github.com/jinzhu/copier v0.4.0
23 | github.com/json-iterator/go v1.1.12 // indirect
24 | github.com/klauspost/cpuid/v2 v2.2.4 // indirect
25 | github.com/leodido/go-urn v1.2.4 // indirect
26 | github.com/mattn/go-isatty v0.0.19 // indirect
27 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
28 | github.com/modern-go/reflect2 v1.0.2 // indirect
29 | github.com/pelletier/go-toml/v2 v2.0.8 // indirect
30 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
31 | github.com/ugorji/go/codec v1.2.11 // indirect
32 | go.uber.org/multierr v1.10.0 // indirect
33 | golang.org/x/arch v0.3.0 // indirect
34 | golang.org/x/crypto v0.13.0 // indirect
35 | golang.org/x/net v0.15.0 // indirect
36 | golang.org/x/sys v0.12.0 // indirect
37 | golang.org/x/text v0.13.0 // indirect
38 | google.golang.org/protobuf v1.30.0 // indirect
39 | gopkg.in/yaml.v3 v3.0.1 // indirect
40 | )
41 |
--------------------------------------------------------------------------------
/hexagonal-news-api/go.sum:
--------------------------------------------------------------------------------
1 | github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
2 | github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
3 | github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
4 | github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
5 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
6 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
7 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
8 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
9 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
10 | github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
11 | github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
12 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
13 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
14 | github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
15 | github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
16 | github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
17 | github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
18 | github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
19 | github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
20 | github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
21 | github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
22 | github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
23 | github.com/go-resty/resty/v2 v2.8.0 h1:J29d0JFWwSWrDCysnOK/YjsPMLQTx0TvgJEHVGvf2L8=
24 | github.com/go-resty/resty/v2 v2.8.0/go.mod h1:UCui0cMHekLrSntoMyofdSTaPpinlRHFtPpizuyDW2w=
25 | github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
26 | github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
27 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
28 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
29 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
30 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
31 | github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
32 | github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
33 | github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
34 | github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
35 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
36 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
37 | github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
38 | github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
39 | github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
40 | github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
41 | github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
42 | github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
43 | github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
44 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
45 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
46 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
47 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
48 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
49 | github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
50 | github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
51 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
52 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
53 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
54 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
55 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
56 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
57 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
58 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
59 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
60 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
61 | github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
62 | github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
63 | github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
64 | github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
65 | github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
66 | github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
67 | github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
68 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
69 | go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
70 | go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
71 | go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
72 | go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
73 | go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
74 | golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
75 | golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
76 | golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
77 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
78 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
79 | golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
80 | golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
81 | golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
82 | golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
83 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
84 | golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
85 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
86 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
87 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
88 | golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
89 | golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
90 | golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
91 | golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
92 | golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
93 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
94 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
95 | golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
96 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
97 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
98 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
99 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
100 | golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
101 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
102 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
103 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
104 | golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
105 | golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
106 | golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
107 | golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
108 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
109 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
110 | golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
111 | golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
112 | golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
113 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
114 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
115 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
116 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
117 | golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
118 | golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
119 | golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
120 | golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
121 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
122 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
123 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
124 | golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
125 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
126 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
127 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
128 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
129 | google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
130 | google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
131 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
132 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
133 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
134 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
135 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
136 | rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
137 |
--------------------------------------------------------------------------------
/hexagonal-news-api/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/adapter/input/routes"
5 | "github.com/HunCoding/golang-architecture/hexagonal-news-api/configuration/logger"
6 | "github.com/gin-gonic/gin"
7 | "github.com/joho/godotenv"
8 | )
9 |
10 | func main() {
11 | godotenv.Load()
12 | logger.Info("About to start application")
13 | router := gin.Default()
14 |
15 | routes.InitRoutes(router)
16 |
17 | if err := router.Run(":8080"); err != nil {
18 | logger.Error("Error trying to init application on port 8080", err)
19 | return
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/hexagonal/.gitignore:
--------------------------------------------------------------------------------
1 | # Binaries for programs and plugins
2 | *.exe
3 | *.exe~
4 | *.dll
5 | *.so
6 | *.dylib
7 |
8 | # Test binary, built with `go test -c`
9 | *.test
10 |
11 | .idea
12 | .env
13 |
14 | # Output of the go coverage tool, specifically when used with LiteIDE
15 | *.out
16 |
17 | # Dependency directories (remove the comment below to include it)
18 | # vendor/
--------------------------------------------------------------------------------
/hexagonal/adapter/input/controller/create_user_controller.go:
--------------------------------------------------------------------------------
1 | package controller
2 |
3 | import (
4 | "hexagonal/adapter/input/converter"
5 | "hexagonal/adapter/input/model/request"
6 | "hexagonal/application/domain"
7 | "hexagonal/application/port/input"
8 | "hexagonal/configuration/logger"
9 | "hexagonal/configuration/validation"
10 | "net/http"
11 |
12 | "github.com/gin-gonic/gin"
13 | "go.uber.org/zap"
14 | )
15 |
16 | func NewUserControllerInterface(
17 | serviceInterface input.UserDomainService,
18 | ) UserControllerInterface {
19 | return &userControllerInterface{
20 | service: serviceInterface,
21 | }
22 | }
23 |
24 | type UserControllerInterface interface {
25 | FindUserByID(c *gin.Context)
26 | FindUserByEmail(c *gin.Context)
27 |
28 | CreateUser(c *gin.Context)
29 | }
30 |
31 | type userControllerInterface struct {
32 | service input.UserDomainService
33 | }
34 |
35 | func (uc *userControllerInterface) CreateUser(c *gin.Context) {
36 | logger.Info("Init CreateUser controller",
37 | zap.String("journey", "createUser"),
38 | )
39 | var userRequest request.UserRequest
40 |
41 | if err := c.ShouldBindJSON(&userRequest); err != nil {
42 | logger.Error("Error trying to validate user info", err,
43 | zap.String("journey", "createUser"))
44 | errRest := validation.ValidateUserError(err)
45 |
46 | c.JSON(errRest.Code, errRest)
47 | return
48 | }
49 |
50 | userDomain := domain.UserDomain{
51 | Email: userRequest.Email,
52 | Password: userRequest.Password,
53 | Name: userRequest.Name,
54 | Age: userRequest.Age,
55 | }
56 | domainResult, err := uc.service.CreateUserServices(userDomain)
57 | if err != nil {
58 | logger.Error(
59 | "Error trying to call CreateUser service",
60 | err,
61 | zap.String("journey", "createUser"))
62 | c.JSON(err.Code, err)
63 | return
64 | }
65 |
66 | logger.Info(
67 | "CreateUser controller executed successfully",
68 | zap.String("userId", domainResult.Id),
69 | zap.String("journey", "createUser"))
70 |
71 | c.JSON(http.StatusOK, converter.ConvertDomainToResponse(
72 | domainResult,
73 | ))
74 | }
75 |
--------------------------------------------------------------------------------
/hexagonal/adapter/input/controller/find_user_controller.go:
--------------------------------------------------------------------------------
1 | package controller
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | "go.mongodb.org/mongo-driver/bson/primitive"
6 | "go.uber.org/zap"
7 | "hexagonal/adapter/input/converter"
8 | "hexagonal/configuration/logger"
9 | "hexagonal/configuration/rest_errors"
10 | "net/http"
11 | "net/mail"
12 | )
13 |
14 | func (uc *userControllerInterface) FindUserByID(c *gin.Context) {
15 | logger.Info("Init findUserByID controller",
16 | zap.String("journey", "findUserByID"),
17 | )
18 |
19 | userId := c.Param("userId")
20 |
21 | if _, err := primitive.ObjectIDFromHex(userId); err != nil {
22 | logger.Error("Error trying to validate userId",
23 | err,
24 | zap.String("journey", "findUserByID"),
25 | )
26 | errorMessage := rest_errors.NewBadRequestError(
27 | "UserID is not a valid id",
28 | )
29 |
30 | c.JSON(errorMessage.Code, errorMessage)
31 | return
32 | }
33 |
34 | userDomain, err := uc.service.FindUserByIDServices(userId)
35 | if err != nil {
36 | logger.Error("Error trying to call findUserByID services",
37 | err,
38 | zap.String("journey", "findUserByID"),
39 | )
40 | c.JSON(err.Code, err)
41 | return
42 | }
43 |
44 | logger.Info("FindUserByID controller executed successfully",
45 | zap.String("journey", "findUserByID"),
46 | )
47 | c.JSON(http.StatusOK, converter.ConvertDomainToResponse(
48 | userDomain,
49 | ))
50 | }
51 |
52 | func (uc *userControllerInterface) FindUserByEmail(c *gin.Context) {
53 | logger.Info("Init findUserByEmail controller",
54 | zap.String("journey", "findUserByEmail"),
55 | )
56 |
57 | userEmail := c.Param("userEmail")
58 |
59 | if _, err := mail.ParseAddress(userEmail); err != nil {
60 | logger.Error("Error trying to validate userEmail",
61 | err,
62 | zap.String("journey", "findUserByEmail"),
63 | )
64 | errorMessage := rest_errors.NewBadRequestError(
65 | "UserEmail is not a valid email",
66 | )
67 |
68 | c.JSON(errorMessage.Code, errorMessage)
69 | return
70 | }
71 |
72 | userDomain, err := uc.service.FindUserByEmailServices(userEmail)
73 | if err != nil {
74 | logger.Error("Error trying to call findUserByEmail services",
75 | err,
76 | zap.String("journey", "findUserByEmail"),
77 | )
78 | c.JSON(err.Code, err)
79 | return
80 | }
81 |
82 | logger.Info("findUserByEmail controller executed successfully",
83 | zap.String("journey", "findUserByEmail"),
84 | )
85 | c.JSON(http.StatusOK, converter.ConvertDomainToResponse(
86 | userDomain,
87 | ))
88 | }
89 |
--------------------------------------------------------------------------------
/hexagonal/adapter/input/controller/middlewares/jwt_middleware.go:
--------------------------------------------------------------------------------
1 | package middlewares
2 |
3 | import (
4 | "fmt"
5 | "github.com/gin-gonic/gin"
6 | "github.com/golang-jwt/jwt"
7 | "hexagonal/application/constants"
8 | "hexagonal/application/domain"
9 | "hexagonal/configuration/logger"
10 | "hexagonal/configuration/rest_errors"
11 | "os"
12 | "strings"
13 | )
14 |
15 | func VerifyTokenMiddleware(c *gin.Context) {
16 | secret := os.Getenv(constants.JWT_SECRET_KEY)
17 | tokenValue := RemoveBearerPrefix(c.Request.Header.Get("Authorization"))
18 |
19 | token, err := jwt.Parse(tokenValue, func(token *jwt.Token) (interface{}, error) {
20 | if _, ok := token.Method.(*jwt.SigningMethodHMAC); ok {
21 | return []byte(secret), nil
22 | }
23 |
24 | return nil, rest_errors.NewBadRequestError("invalid token")
25 | })
26 | if err != nil {
27 | errRest := rest_errors.NewUnauthorizedRequestError("invalid token")
28 | c.JSON(errRest.Code, errRest)
29 | c.Abort()
30 | return
31 | }
32 |
33 | claims, ok := token.Claims.(jwt.MapClaims)
34 | if !ok || !token.Valid {
35 | errRest := rest_errors.NewUnauthorizedRequestError("invalid token")
36 | c.JSON(errRest.Code, errRest)
37 | c.Abort()
38 | return
39 | }
40 |
41 | userDomain := domain.UserDomain{
42 | Id: claims["id"].(string),
43 | Email: claims["email"].(string),
44 | Name: claims["name"].(string),
45 | Age: int8(claims["age"].(float64)),
46 | }
47 | logger.Info(fmt.Sprintf("User authenticated: %#v", userDomain))
48 | }
49 |
50 | func RemoveBearerPrefix(token string) string {
51 | if strings.HasPrefix(token, "Bearer ") {
52 | token = strings.TrimPrefix("Bearer ", token)
53 | }
54 |
55 | return token
56 | }
57 |
--------------------------------------------------------------------------------
/hexagonal/adapter/input/controller/routes/routes.go:
--------------------------------------------------------------------------------
1 | package routes
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | "hexagonal/adapter/input/controller"
6 | "hexagonal/adapter/input/controller/middlewares"
7 | )
8 |
9 | func InitRoutes(
10 | r *gin.RouterGroup,
11 | userController controller.UserControllerInterface) {
12 |
13 | r.GET("/getUserById/:userId", middlewares.VerifyTokenMiddleware, userController.FindUserByID)
14 | r.GET("/getUserByEmail/:userEmail", middlewares.VerifyTokenMiddleware, userController.FindUserByEmail)
15 | r.POST("/createUser", userController.CreateUser)
16 | }
17 |
--------------------------------------------------------------------------------
/hexagonal/adapter/input/converter/convert_domain_to_response.go:
--------------------------------------------------------------------------------
1 | package converter
2 |
3 | import (
4 | "hexagonal/adapter/input/model/response"
5 | "hexagonal/application/domain"
6 | )
7 |
8 | func ConvertDomainToResponse(
9 | userDomain *domain.UserDomain,
10 | ) response.UserResponse {
11 | return response.UserResponse{
12 | ID: userDomain.Id,
13 | Email: userDomain.Email,
14 | Name: userDomain.Name,
15 | Age: userDomain.Age,
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/hexagonal/adapter/input/model/request/user_request.go:
--------------------------------------------------------------------------------
1 | package request
2 |
3 | type UserRequest struct {
4 | Email string `json:"email" binding:"required,email"`
5 | Password string `json:"password" binding:"required,min=6,containsany=!@#$%*"`
6 | Name string `json:"name" binding:"required,min=4,max=100"`
7 | Age int8 `json:"age" binding:"required,min=1,max=140"`
8 | }
9 |
10 | type UserUpdateRequest struct {
11 | Name string `json:"name" binding:"omitempty,min=4,max=100"`
12 | Age int8 `json:"age" binding:"omitempty,min=1,max=140"`
13 | }
14 |
--------------------------------------------------------------------------------
/hexagonal/adapter/input/model/response/user_response.go:
--------------------------------------------------------------------------------
1 | package response
2 |
3 | type UserResponse struct {
4 | ID string `json:"id"`
5 | Email string `json:"email"`
6 | Name string `json:"name"`
7 | Age int8 `json:"age"`
8 | }
9 |
--------------------------------------------------------------------------------
/hexagonal/adapter/output/converter/convert_domain_to_entity.go:
--------------------------------------------------------------------------------
1 | package converter
2 |
3 | import (
4 | "hexagonal/adapter/output/model/entity"
5 | "hexagonal/application/domain"
6 | )
7 |
8 | func ConvertDomainToEntity(
9 | domain domain.UserDomain,
10 | ) *entity.UserEntity {
11 | return &entity.UserEntity{
12 | Email: domain.Email,
13 | Password: domain.Password,
14 | Name: domain.Name,
15 | Age: domain.Age,
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/hexagonal/adapter/output/converter/convert_entity_to_domain.go:
--------------------------------------------------------------------------------
1 | package converter
2 |
3 | import (
4 | "hexagonal/adapter/output/model/entity"
5 | "hexagonal/application/domain"
6 | )
7 |
8 | func ConvertEntityToDomain(
9 | entity entity.UserEntity,
10 | ) *domain.UserDomain {
11 | domainConverted := &domain.UserDomain{
12 | Email: entity.Email,
13 | Password: entity.Password,
14 | Name: entity.Name,
15 | Age: entity.Age,
16 | }
17 |
18 | domainConverted.Id = entity.ID.Hex()
19 | return domainConverted
20 | }
21 |
--------------------------------------------------------------------------------
/hexagonal/adapter/output/model/entity/user_entity.go:
--------------------------------------------------------------------------------
1 | package entity
2 |
3 | import "go.mongodb.org/mongo-driver/bson/primitive"
4 |
5 | type UserEntity struct {
6 | ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
7 | Email string `bson:"email,omitempty"`
8 | Password string `bson:"password,omitempty"`
9 | Name string `bson:"name,omitempty"`
10 | Age int8 `bson:"age,omitempty"`
11 | }
12 |
--------------------------------------------------------------------------------
/hexagonal/adapter/output/repository/create_user_repository.go:
--------------------------------------------------------------------------------
1 | package repository
2 |
3 | import (
4 | "context"
5 | "go.mongodb.org/mongo-driver/mongo"
6 | "hexagonal/adapter/output/converter"
7 | "hexagonal/application/domain"
8 | "hexagonal/application/port/output"
9 | "hexagonal/configuration/logger"
10 | "hexagonal/configuration/rest_errors"
11 | "os"
12 |
13 | "go.mongodb.org/mongo-driver/bson/primitive"
14 | "go.uber.org/zap"
15 | )
16 |
17 | const (
18 | MONGODB_USER_DB = "MONGODB_USER_DB"
19 | )
20 |
21 | func NewUserRepository(
22 | database *mongo.Database,
23 | ) output.UserPort {
24 | return &userRepository{
25 | database,
26 | }
27 | }
28 |
29 | type userRepository struct {
30 | databaseConnection *mongo.Database
31 | }
32 |
33 | func (ur *userRepository) CreateUser(
34 | userDomain domain.UserDomain,
35 | ) (*domain.UserDomain, *rest_errors.RestErr) {
36 | logger.Info("Init createUser repository",
37 | zap.String("journey", "createUser"))
38 |
39 | collection_name := os.Getenv(MONGODB_USER_DB)
40 |
41 | collection := ur.databaseConnection.Collection(collection_name)
42 |
43 | value := converter.ConvertDomainToEntity(userDomain)
44 |
45 | result, err := collection.InsertOne(context.Background(), value)
46 | if err != nil {
47 | logger.Error("Error trying to create user",
48 | err,
49 | zap.String("journey", "createUser"))
50 | return nil, rest_errors.NewInternalServerError(err.Error())
51 | }
52 |
53 | value.ID = result.InsertedID.(primitive.ObjectID)
54 |
55 | logger.Info(
56 | "CreateUser repository executed successfully",
57 | zap.String("userId", value.ID.Hex()),
58 | zap.String("journey", "createUser"))
59 |
60 | return converter.ConvertEntityToDomain(*value), nil
61 | }
62 |
--------------------------------------------------------------------------------
/hexagonal/adapter/output/repository/find_user_repository.go:
--------------------------------------------------------------------------------
1 | package repository
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "hexagonal/adapter/output/converter"
7 | "hexagonal/adapter/output/model/entity"
8 | "hexagonal/application/domain"
9 | "hexagonal/configuration/logger"
10 | "hexagonal/configuration/rest_errors"
11 | "os"
12 |
13 | "go.mongodb.org/mongo-driver/bson"
14 | "go.mongodb.org/mongo-driver/bson/primitive"
15 | "go.mongodb.org/mongo-driver/mongo"
16 | "go.uber.org/zap"
17 | )
18 |
19 | func (ur *userRepository) FindUserByEmail(
20 | email string,
21 | ) (*domain.UserDomain, *rest_errors.RestErr) {
22 | logger.Info("Init findUserByEmail repository",
23 | zap.String("journey", "findUserByEmail"))
24 |
25 | collection_name := os.Getenv(MONGODB_USER_DB)
26 | collection := ur.databaseConnection.Collection(collection_name)
27 |
28 | userEntity := &entity.UserEntity{}
29 |
30 | filter := bson.D{{Key: "email", Value: email}}
31 | err := collection.FindOne(
32 | context.Background(),
33 | filter,
34 | ).Decode(userEntity)
35 |
36 | if err != nil {
37 | if err == mongo.ErrNoDocuments {
38 | errorMessage := fmt.Sprintf(
39 | "User not found with this email: %s", email)
40 | logger.Error(errorMessage,
41 | err,
42 | zap.String("journey", "findUserByEmail"))
43 |
44 | return nil, rest_errors.NewNotFoundError(errorMessage)
45 | }
46 | errorMessage := "Error trying to find user by email"
47 | logger.Error(errorMessage,
48 | err,
49 | zap.String("journey", "findUserByEmail"))
50 |
51 | return nil, rest_errors.NewInternalServerError(errorMessage)
52 | }
53 |
54 | logger.Info("FindUserByEmail repository executed successfully",
55 | zap.String("journey", "findUserByEmail"),
56 | zap.String("email", email),
57 | zap.String("userId", userEntity.ID.Hex()))
58 | return converter.ConvertEntityToDomain(*userEntity), nil
59 | }
60 |
61 | func (ur *userRepository) FindUserByID(
62 | id string,
63 | ) (*domain.UserDomain, *rest_errors.RestErr) {
64 | logger.Info("Init findUserByID repository",
65 | zap.String("journey", "findUserByID"))
66 |
67 | collection_name := os.Getenv(MONGODB_USER_DB)
68 | collection := ur.databaseConnection.Collection(collection_name)
69 |
70 | userEntity := &entity.UserEntity{}
71 |
72 | objectId, _ := primitive.ObjectIDFromHex(id)
73 | filter := bson.D{{Key: "_id", Value: objectId}}
74 | err := collection.FindOne(
75 | context.Background(),
76 | filter,
77 | ).Decode(userEntity)
78 |
79 | if err != nil {
80 | if err == mongo.ErrNoDocuments {
81 | errorMessage := fmt.Sprintf(
82 | "User not found with this ID: %s", id)
83 | logger.Error(errorMessage,
84 | err,
85 | zap.String("journey", "findUserByID"))
86 |
87 | return nil, rest_errors.NewNotFoundError(errorMessage)
88 | }
89 | errorMessage := "Error trying to find user by ID"
90 | logger.Error(errorMessage,
91 | err,
92 | zap.String("journey", "findUserByID"))
93 |
94 | return nil, rest_errors.NewInternalServerError(errorMessage)
95 | }
96 |
97 | logger.Info("FindUserByID repository executed successfully",
98 | zap.String("journey", "findUserByID"),
99 | zap.String("userId", userEntity.ID.Hex()))
100 | return converter.ConvertEntityToDomain(*userEntity), nil
101 | }
102 |
--------------------------------------------------------------------------------
/hexagonal/application/constants/token.go:
--------------------------------------------------------------------------------
1 | package constants
2 |
3 | var (
4 | JWT_SECRET_KEY = "JWT_SECRET_KEY"
5 | )
6 |
--------------------------------------------------------------------------------
/hexagonal/application/domain/user_domain.go:
--------------------------------------------------------------------------------
1 | package domain
2 |
3 | import (
4 | "crypto/md5"
5 | "encoding/hex"
6 | )
7 |
8 | type UserDomain struct {
9 | Id string
10 | Email string
11 | Password string
12 | Name string
13 | Age int8
14 | }
15 |
16 | func (ud *UserDomain) EncryptPassword() {
17 | hash := md5.New()
18 | defer hash.Reset()
19 | hash.Write([]byte(ud.Password))
20 | ud.Password = hex.EncodeToString(hash.Sum(nil))
21 | }
22 |
--------------------------------------------------------------------------------
/hexagonal/application/domain/user_token_domain.go:
--------------------------------------------------------------------------------
1 | package domain
2 |
3 | import (
4 | "fmt"
5 | "github.com/golang-jwt/jwt"
6 | "hexagonal/application/constants"
7 | "hexagonal/configuration/rest_errors"
8 | "os"
9 | "time"
10 | )
11 |
12 | func (ud *UserDomain) GenerateToken() (string, *rest_errors.RestErr) {
13 | secret := os.Getenv(constants.JWT_SECRET_KEY)
14 |
15 | claims := jwt.MapClaims{
16 | "id": ud.Id,
17 | "email": ud.Email,
18 | "name": ud.Name,
19 | "age": ud.Age,
20 | "exp": time.Now().Add(time.Hour * 24).Unix(),
21 | }
22 |
23 | token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
24 |
25 | tokenString, err := token.SignedString([]byte(secret))
26 | if err != nil {
27 | return "", rest_errors.NewInternalServerError(
28 | fmt.Sprintf("error trying to generate jwt token, err=%s", err.Error()))
29 | }
30 |
31 | return tokenString, nil
32 | }
33 |
--------------------------------------------------------------------------------
/hexagonal/application/port/input/users_use_case.go:
--------------------------------------------------------------------------------
1 | package input
2 |
3 | import (
4 | "hexagonal/application/domain"
5 | "hexagonal/configuration/rest_errors"
6 | )
7 |
8 | type UserDomainService interface {
9 | CreateUserServices(domain.UserDomain) (
10 | *domain.UserDomain, *rest_errors.RestErr)
11 | FindUserByIDServices(
12 | id string,
13 | ) (*domain.UserDomain, *rest_errors.RestErr)
14 | FindUserByEmailServices(
15 | email string,
16 | ) (*domain.UserDomain, *rest_errors.RestErr)
17 | }
18 |
--------------------------------------------------------------------------------
/hexagonal/application/port/output/user_port.go:
--------------------------------------------------------------------------------
1 | package output
2 |
3 | import (
4 | "hexagonal/application/domain"
5 | "hexagonal/configuration/rest_errors"
6 | )
7 |
8 | type UserPort interface {
9 | CreateUser(
10 | userDomain domain.UserDomain,
11 | ) (*domain.UserDomain, *rest_errors.RestErr)
12 |
13 | FindUserByEmail(
14 | email string,
15 | ) (*domain.UserDomain, *rest_errors.RestErr)
16 | FindUserByID(
17 | id string,
18 | ) (*domain.UserDomain, *rest_errors.RestErr)
19 | }
20 |
--------------------------------------------------------------------------------
/hexagonal/application/services/create_user.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import (
4 | "go.uber.org/zap"
5 | "hexagonal/application/domain"
6 | "hexagonal/application/port/input"
7 | "hexagonal/application/port/output"
8 | "hexagonal/configuration/logger"
9 | "hexagonal/configuration/rest_errors"
10 | )
11 |
12 | func NewUserDomainService(
13 | userRepository output.UserPort) input.UserDomainService {
14 | return &userDomainService{
15 | userRepository,
16 | }
17 | }
18 |
19 | type userDomainService struct {
20 | repository output.UserPort
21 | }
22 |
23 | func (ud *userDomainService) CreateUserServices(
24 | userDomain domain.UserDomain,
25 | ) (*domain.UserDomain, *rest_errors.RestErr) {
26 |
27 | logger.Info("Init createUser model.",
28 | zap.String("journey", "createUser"))
29 |
30 | user, _ := ud.FindUserByEmailServices(userDomain.Email)
31 | if user != nil {
32 | return nil, rest_errors.NewBadRequestError("Email is already registered in another account")
33 | }
34 |
35 | userDomain.EncryptPassword()
36 | userDomainRepository, err := ud.repository.CreateUser(userDomain)
37 | if err != nil {
38 | logger.Error("Error trying to call repository",
39 | err,
40 | zap.String("journey", "createUser"))
41 | return nil, err
42 | }
43 |
44 | logger.Info(
45 | "CreateUser service executed successfully",
46 | zap.String("userId", userDomainRepository.Id),
47 | zap.String("journey", "createUser"))
48 | return userDomainRepository, nil
49 | }
50 |
--------------------------------------------------------------------------------
/hexagonal/application/services/find_user.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import (
4 | "go.uber.org/zap"
5 | "hexagonal/application/domain"
6 | "hexagonal/configuration/logger"
7 | "hexagonal/configuration/rest_errors"
8 | )
9 |
10 | func (ud *userDomainService) FindUserByIDServices(
11 | id string,
12 | ) (*domain.UserDomain, *rest_errors.RestErr) {
13 | logger.Info("Init findUserByID services.",
14 | zap.String("journey", "findUserById"))
15 |
16 | return ud.repository.FindUserByID(id)
17 | }
18 |
19 | func (ud *userDomainService) FindUserByEmailServices(
20 | email string,
21 | ) (*domain.UserDomain, *rest_errors.RestErr) {
22 | logger.Info("Init findUserByEmail services.",
23 | zap.String("journey", "findUserById"))
24 |
25 | return ud.repository.FindUserByEmail(email)
26 | }
27 |
--------------------------------------------------------------------------------
/hexagonal/configuration/database/mongodb/mongodb_connection.go:
--------------------------------------------------------------------------------
1 | package mongodb
2 |
3 | import (
4 | "context"
5 | "os"
6 |
7 | "go.mongodb.org/mongo-driver/mongo"
8 | "go.mongodb.org/mongo-driver/mongo/options"
9 | )
10 |
11 | var (
12 | MONGODB_URL = "MONGODB_URL"
13 | MONGODB_USER_DB = "MONGODB_USER_DB"
14 | )
15 |
16 | func NewMongoDBConnection(
17 | ctx context.Context,
18 | ) (*mongo.Database, error) {
19 | mongodb_uri := os.Getenv(MONGODB_URL)
20 | mongodb_database := os.Getenv(MONGODB_USER_DB)
21 |
22 | client, err := mongo.Connect(
23 | ctx,
24 | options.Client().ApplyURI(mongodb_uri))
25 | if err != nil {
26 | return nil, err
27 | }
28 |
29 | if err := client.Ping(ctx, nil); err != nil {
30 | return nil, err
31 | }
32 |
33 | return client.Database(mongodb_database), nil
34 | }
35 |
--------------------------------------------------------------------------------
/hexagonal/configuration/logger/logger.go:
--------------------------------------------------------------------------------
1 | package logger
2 |
3 | import (
4 | "os"
5 | "strings"
6 |
7 | "go.uber.org/zap"
8 | "go.uber.org/zap/zapcore"
9 | )
10 |
11 | var (
12 | log *zap.Logger
13 |
14 | LOG_OUTPUT = "LOG_OUTPUT"
15 | LOG_LEVEL = "LOG_LEVEL"
16 | )
17 |
18 | func init() {
19 | logConfig := zap.Config{
20 | OutputPaths: []string{getOutputLogs()},
21 | Level: zap.NewAtomicLevelAt(getLevelLogs()),
22 | Encoding: "json",
23 | EncoderConfig: zapcore.EncoderConfig{
24 | LevelKey: "level",
25 | TimeKey: "time",
26 | MessageKey: "message",
27 | EncodeTime: zapcore.ISO8601TimeEncoder,
28 | EncodeLevel: zapcore.LowercaseLevelEncoder,
29 | EncodeCaller: zapcore.ShortCallerEncoder,
30 | },
31 | }
32 |
33 | log, _ = logConfig.Build()
34 | }
35 |
36 | func Info(message string, tags ...zap.Field) {
37 | log.Info(message, tags...)
38 | errSync := log.Sync()
39 | if errSync != nil {
40 | return
41 | }
42 | }
43 |
44 | func Error(message string, err error, tags ...zap.Field) {
45 | tags = append(tags, zap.NamedError("error", err))
46 | log.Info(message, tags...)
47 | errSync := log.Sync()
48 | if errSync != nil {
49 | return
50 | }
51 | }
52 |
53 | func getOutputLogs() string {
54 | output := strings.ToLower(strings.TrimSpace(os.Getenv(LOG_OUTPUT)))
55 | if output == "" {
56 | return "stdout"
57 | }
58 |
59 | return output
60 | }
61 |
62 | func getLevelLogs() zapcore.Level {
63 | switch strings.ToLower(strings.TrimSpace(os.Getenv(LOG_LEVEL))) {
64 | case "info":
65 | return zapcore.InfoLevel
66 | case "error":
67 | return zapcore.ErrorLevel
68 | case "debug":
69 | return zapcore.DebugLevel
70 | default:
71 | return zapcore.InfoLevel
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/hexagonal/configuration/rest_errors/rest_errors.go:
--------------------------------------------------------------------------------
1 | package rest_errors
2 |
3 | import "net/http"
4 |
5 | type RestErr struct {
6 | Message string `json:"message"`
7 | Err string `json:"error"`
8 | Code int `json:"code"`
9 | Causes []Causes `json:"causes"`
10 | }
11 |
12 | type Causes struct {
13 | Field string `json:"field"`
14 | Message string `json:"message"`
15 | }
16 |
17 | func (r *RestErr) Error() string {
18 | return r.Message
19 | }
20 |
21 | func NewBadRequestError(message string) *RestErr {
22 | return &RestErr{
23 | Message: message,
24 | Err: "bad_request",
25 | Code: http.StatusBadRequest,
26 | }
27 | }
28 |
29 | func NewUnauthorizedRequestError(message string) *RestErr {
30 | return &RestErr{
31 | Message: message,
32 | Err: "unauthorized",
33 | Code: http.StatusUnauthorized,
34 | }
35 | }
36 |
37 | func NewBadRequestValidationError(message string, causes []Causes) *RestErr {
38 | return &RestErr{
39 | Message: message,
40 | Err: "bad_request",
41 | Code: http.StatusBadRequest,
42 | Causes: causes,
43 | }
44 | }
45 |
46 | func NewInternalServerError(message string) *RestErr {
47 | return &RestErr{
48 | Message: message,
49 | Err: "internal_server_error",
50 | Code: http.StatusInternalServerError,
51 | }
52 | }
53 |
54 | func NewNotFoundError(message string) *RestErr {
55 | return &RestErr{
56 | Message: message,
57 | Err: "not_found",
58 | Code: http.StatusNotFound,
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/hexagonal/configuration/validation/validate.go:
--------------------------------------------------------------------------------
1 | package validation
2 |
3 | import (
4 | "encoding/json"
5 | "errors"
6 | "hexagonal/configuration/rest_errors"
7 |
8 | "github.com/gin-gonic/gin/binding"
9 | "github.com/go-playground/locales/en"
10 | ut "github.com/go-playground/universal-translator"
11 | "github.com/go-playground/validator/v10"
12 |
13 | en_translation "github.com/go-playground/validator/v10/translations/en"
14 | )
15 |
16 | var (
17 | transl ut.Translator
18 | )
19 |
20 | func init() {
21 | if val, ok := binding.Validator.Engine().(*validator.Validate); ok {
22 | enTranslator := en.New()
23 | unt := ut.New(enTranslator, enTranslator)
24 | transl, _ = unt.GetTranslator("en")
25 | err := en_translation.RegisterDefaultTranslations(val, transl)
26 | if err != nil {
27 | return
28 | }
29 | }
30 | }
31 |
32 | func ValidateUserError(
33 | validation_err error,
34 | ) *rest_errors.RestErr {
35 |
36 | var jsonErr *json.UnmarshalTypeError
37 | var jsonValidationError validator.ValidationErrors
38 |
39 | if errors.As(validation_err, &jsonErr) {
40 | return rest_errors.NewBadRequestError("Invalid field type")
41 | } else if errors.As(validation_err, &jsonValidationError) {
42 | errorsCauses := []rest_errors.Causes{}
43 |
44 | for _, e := range validation_err.(validator.ValidationErrors) {
45 | cause := rest_errors.Causes{
46 | Message: e.Translate(transl),
47 | Field: e.Field(),
48 | }
49 |
50 | errorsCauses = append(errorsCauses, cause)
51 | }
52 |
53 | return rest_errors.NewBadRequestValidationError("Some fields are invalid", errorsCauses)
54 | } else {
55 | return rest_errors.NewBadRequestError("Error trying to convert fields")
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/hexagonal/crud_users.http:
--------------------------------------------------------------------------------
1 | // Buscar usuário no banco de dados por email
2 | GET http://localhost:8080/getUserByEmail/huncoding@gmail.com
3 | Accept: application/json
4 | Authorization:
5 | ###
6 |
7 | // Buscar usuário no banco de dados por email
8 | GET http://localhost:8080/getUserById/647b3fc9c5be50a5f2e48008
9 | Accept: application/json
10 | Authorization:
11 | ###
12 |
13 | // Criar um usuario dentro do banco de dados
14 | POST http://localhost:8080/createUser
15 | Content-Type: application/json
16 |
17 | {
18 | "email": "huncoding@gmail.com",
19 | "age": 20,
20 | "password": "huncoding#!@!dwdw",
21 | "name": "Huncoding"
22 | }
23 | ###
24 |
25 | // Atualiza um usuario já criado dentro do banco de dados
26 | PUT http://localhost:8080/updateUser/6423852a15cd25e0b80f8535
27 | Content-Type: application/json
28 |
29 | {
30 | "email": "otavio20313131@test.com",
31 | "age": 90
32 | }
33 | ###
34 |
35 | // Apaga um usuário do banco de dados dado um userId
36 | DELETE http://localhost:8080/deleteUser/6423852a15cd25e0b80f8535
37 | Accept: application/json
38 | ###
39 |
40 | // Realiza o login do usuário com email e senha
41 | POST http://localhost:8080/login
42 | Content-Type: application/json
43 |
44 | {
45 | "email": "huncoding@gmail.com",
46 | "password": "huncoding#!@!dwdw"
47 | }
48 | ###
--------------------------------------------------------------------------------
/hexagonal/go.mod:
--------------------------------------------------------------------------------
1 | module hexagonal
2 |
3 | go 1.19
4 |
5 | require (
6 | github.com/gin-gonic/gin v1.9.1
7 | github.com/go-playground/locales v0.14.1
8 | github.com/go-playground/universal-translator v0.18.1
9 | github.com/go-playground/validator/v10 v10.14.0
10 | github.com/golang-jwt/jwt v3.2.2+incompatible
11 | github.com/joho/godotenv v1.5.1
12 | go.mongodb.org/mongo-driver v1.11.7
13 | go.uber.org/zap v1.24.0
14 | )
15 |
16 | require (
17 | github.com/bytedance/sonic v1.9.1 // indirect
18 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
19 | github.com/gabriel-vasile/mimetype v1.4.2 // indirect
20 | github.com/gin-contrib/sse v0.1.0 // indirect
21 | github.com/goccy/go-json v0.10.2 // indirect
22 | github.com/golang/snappy v0.0.1 // indirect
23 | github.com/json-iterator/go v1.1.12 // indirect
24 | github.com/klauspost/compress v1.13.6 // indirect
25 | github.com/klauspost/cpuid/v2 v2.2.4 // indirect
26 | github.com/leodido/go-urn v1.2.4 // indirect
27 | github.com/mattn/go-isatty v0.0.19 // indirect
28 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
29 | github.com/modern-go/reflect2 v1.0.2 // indirect
30 | github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
31 | github.com/pelletier/go-toml/v2 v2.0.8 // indirect
32 | github.com/pkg/errors v0.9.1 // indirect
33 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
34 | github.com/ugorji/go/codec v1.2.11 // indirect
35 | github.com/xdg-go/pbkdf2 v1.0.0 // indirect
36 | github.com/xdg-go/scram v1.1.1 // indirect
37 | github.com/xdg-go/stringprep v1.0.3 // indirect
38 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
39 | go.uber.org/atomic v1.7.0 // indirect
40 | go.uber.org/multierr v1.6.0 // indirect
41 | golang.org/x/arch v0.3.0 // indirect
42 | golang.org/x/crypto v0.9.0 // indirect
43 | golang.org/x/net v0.10.0 // indirect
44 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
45 | golang.org/x/sys v0.8.0 // indirect
46 | golang.org/x/text v0.9.0 // indirect
47 | google.golang.org/protobuf v1.30.0 // indirect
48 | gopkg.in/yaml.v3 v3.0.1 // indirect
49 | )
50 |
--------------------------------------------------------------------------------
/hexagonal/go.sum:
--------------------------------------------------------------------------------
1 | github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
2 | github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
3 | github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
4 | github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
5 | github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
6 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
7 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
8 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
10 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
11 | github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
12 | github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
13 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
14 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
15 | github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
16 | github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
17 | github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
18 | github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
19 | github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
20 | github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
21 | github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
22 | github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
23 | github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
24 | github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
25 | github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
26 | github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
27 | github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
28 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
29 | github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
30 | github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
31 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
32 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
33 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
34 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
35 | github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
36 | github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
37 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
38 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
39 | github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
40 | github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
41 | github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
42 | github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
43 | github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
44 | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
45 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
46 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
47 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
48 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
49 | github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
50 | github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
51 | github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
52 | github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
53 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
54 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
55 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
56 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
57 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
58 | github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
59 | github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
60 | github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
61 | github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
62 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
63 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
64 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
65 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
66 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
67 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
68 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
69 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
70 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
71 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
72 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
73 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
74 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
75 | github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
76 | github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
77 | github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
78 | github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
79 | github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
80 | github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
81 | github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
82 | github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
83 | github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
84 | github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
85 | github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
86 | github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E=
87 | github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
88 | github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs=
89 | github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
90 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
91 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
92 | go.mongodb.org/mongo-driver v1.11.7 h1:LIwYxASDLGUg/8wOhgOOZhX8tQa/9tgZPgzZoVqJvcs=
93 | go.mongodb.org/mongo-driver v1.11.7/go.mod h1:G9TgswdsWjX4tmDA5zfs2+6AEPpYJwqblyjsfuh8oXY=
94 | go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
95 | go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
96 | go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
97 | go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
98 | go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
99 | go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
100 | go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
101 | golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
102 | golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
103 | golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
104 | golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
105 | golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
106 | golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
107 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
108 | golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
109 | golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
110 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
111 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
112 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
113 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
114 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
115 | golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
116 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
117 | golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
118 | golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
119 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
120 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
121 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
122 | golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
123 | golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
124 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
125 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
126 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
127 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
128 | google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
129 | google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
130 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
131 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
132 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
133 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
134 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
135 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
136 | rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
137 |
--------------------------------------------------------------------------------
/hexagonal/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "github.com/gin-gonic/gin"
6 | "github.com/joho/godotenv"
7 | "go.mongodb.org/mongo-driver/mongo"
8 | "hexagonal/adapter/input/controller"
9 | "hexagonal/adapter/input/controller/routes"
10 | "hexagonal/adapter/output/repository"
11 | service "hexagonal/application/services"
12 | "hexagonal/configuration/database/mongodb"
13 | "hexagonal/configuration/logger"
14 | "log"
15 | )
16 |
17 | func main() {
18 | logger.Info("About to start user application")
19 |
20 | err := godotenv.Load()
21 | if err != nil {
22 | log.Fatal("Error loading .env file")
23 | return
24 | }
25 |
26 | database, err := mongodb.NewMongoDBConnection(context.Background())
27 | if err != nil {
28 | log.Fatalf(
29 | "Error trying to connect to database, error=%s \n",
30 | err.Error())
31 | return
32 | }
33 |
34 | userController := initDependencies(database)
35 |
36 | router := gin.Default()
37 | routes.InitRoutes(&router.RouterGroup, userController)
38 |
39 | if err := router.Run(":8080"); err != nil {
40 | log.Fatal(err)
41 | }
42 | }
43 |
44 | func initDependencies(
45 | database *mongo.Database,
46 | ) controller.UserControllerInterface {
47 | userRepo := repository.NewUserRepository(database)
48 | userService := service.NewUserDomainService(userRepo)
49 | return controller.NewUserControllerInterface(userService)
50 | }
51 |
--------------------------------------------------------------------------------
/mvc/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/HunCoding/golang-architecture/mvc
2 |
3 | go 1.18
4 |
5 | require (
6 | github.com/gin-gonic/gin v1.8.1
7 | go.mongodb.org/mongo-driver v1.10.1
8 | )
9 |
10 | require (
11 | github.com/gin-contrib/sse v0.1.0 // indirect
12 | github.com/go-playground/locales v0.14.0 // indirect
13 | github.com/go-playground/universal-translator v0.18.0 // indirect
14 | github.com/go-playground/validator/v10 v10.10.0 // indirect
15 | github.com/goccy/go-json v0.9.7 // indirect
16 | github.com/golang/snappy v0.0.1 // indirect
17 | github.com/json-iterator/go v1.1.12 // indirect
18 | github.com/klauspost/compress v1.13.6 // indirect
19 | github.com/leodido/go-urn v1.2.1 // indirect
20 | github.com/mattn/go-isatty v0.0.14 // indirect
21 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
22 | github.com/modern-go/reflect2 v1.0.2 // indirect
23 | github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
24 | github.com/pelletier/go-toml/v2 v2.0.1 // indirect
25 | github.com/pkg/errors v0.9.1 // indirect
26 | github.com/ugorji/go/codec v1.2.7 // indirect
27 | github.com/xdg-go/pbkdf2 v1.0.0 // indirect
28 | github.com/xdg-go/scram v1.1.1 // indirect
29 | github.com/xdg-go/stringprep v1.0.3 // indirect
30 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
31 | golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
32 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
33 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
34 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect
35 | golang.org/x/text v0.3.7 // indirect
36 | google.golang.org/protobuf v1.28.0 // indirect
37 | gopkg.in/yaml.v2 v2.4.0 // indirect
38 | )
39 |
--------------------------------------------------------------------------------
/mvc/go.sum:
--------------------------------------------------------------------------------
1 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
4 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
6 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
7 | github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
8 | github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
9 | github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
10 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
11 | github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
12 | github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
13 | github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
14 | github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
15 | github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0=
16 | github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
17 | github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM=
18 | github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
19 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
20 | github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
21 | github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
22 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
23 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
24 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
25 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
26 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
27 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
28 | github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
29 | github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
30 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
31 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
32 | github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
33 | github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
34 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
35 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
36 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
37 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
38 | github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
39 | github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
40 | github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
41 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
42 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
43 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
44 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
45 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
46 | github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
47 | github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
48 | github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU=
49 | github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
50 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
51 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
52 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
53 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
54 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
55 | github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
56 | github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
57 | github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
58 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
59 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
60 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
61 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
62 | github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
63 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
64 | github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
65 | github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
66 | github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
67 | github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
68 | github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
69 | github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
70 | github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
71 | github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E=
72 | github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
73 | github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs=
74 | github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
75 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
76 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
77 | go.mongodb.org/mongo-driver v1.10.1 h1:NujsPveKwHaWuKUer/ceo9DzEe7HIj1SlJ6uvXZG0S4=
78 | go.mongodb.org/mongo-driver v1.10.1/go.mod h1:z4XpeoU6w+9Vht+jAFyLgVrD+jGSQQe0+CBWFHNiHt8=
79 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
80 | golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
81 | golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
82 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
83 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
84 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
85 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
86 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
87 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
88 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
89 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
90 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
91 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 h1:siQdpVirKtzPhKl3lZWozZraCFObP8S1v6PRp0bLrtU=
92 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
93 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
94 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
95 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
96 | golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
97 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
98 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
99 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
100 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
101 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
102 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
103 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
104 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
105 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
106 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
107 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
108 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
109 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
110 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
111 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
112 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
113 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
114 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
115 |
--------------------------------------------------------------------------------
/mvc/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/HunCoding/golang-architecture/mvc/src/controller"
5 | "github.com/HunCoding/golang-architecture/mvc/src/controller/repository"
6 | "github.com/gin-gonic/gin"
7 | "go.mongodb.org/mongo-driver/mongo"
8 | )
9 |
10 | func main() {
11 | client, _ := mongo.NewClient()
12 | repo := repository.NewUserRepository(client)
13 | control := controller.NewUserController(repo)
14 |
15 | router := gin.Default()
16 |
17 | router.POST("/user", control.CreateUser)
18 |
19 | router.Run(":9090")
20 | }
21 |
--------------------------------------------------------------------------------
/mvc/src/controller/user-form.go:
--------------------------------------------------------------------------------
1 | package controller
2 |
3 | import "github.com/HunCoding/golang-architecture/mvc/src/models"
4 |
5 | type UserForm struct {
6 | Email string `json:"email" binding:"required"`
7 | Name string `json:"name" binding:"required"`
8 | Age int `json:"age" binding:"required"`
9 | Password string `json:"password" binding:"required"`
10 | }
11 |
12 | func (uf *UserForm) ConvertInputUserToUserEntity() *models.User {
13 | return &models.User{
14 | Email: uf.Email,
15 | Name: uf.Name,
16 | Age: uf.Age,
17 | Password: uf.Password,
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/mvc/src/controller/user.go:
--------------------------------------------------------------------------------
1 | package controller
2 |
3 | import (
4 | "fmt"
5 | "net/http"
6 |
7 | "github.com/HunCoding/golang-architecture/mvc/src/models/repository"
8 | "github.com/HunCoding/golang-architecture/mvc/src/views"
9 | "github.com/gin-gonic/gin"
10 | )
11 |
12 | func NewUserController(
13 | userRepository repository.UserRepository,
14 | ) UserControllerInterface {
15 | return &userController{userRepository}
16 | }
17 |
18 | type UserControllerInterface interface {
19 | CreateUser(c *gin.Context)
20 | }
21 |
22 | type userController struct {
23 | userRepository repository.UserRepository
24 | }
25 |
26 | func (uc *userController) CreateUser(c *gin.Context) {
27 | user := UserForm{}
28 |
29 | if err := c.ShouldBindJSON(&user); err != nil {
30 | errPerso := views.ParseError(
31 | fmt.Sprintf("Error trying to parse user, error=%s", err),
32 | http.StatusBadRequest,
33 | )
34 |
35 | c.JSON(errPerso.ErrorCode, errPerso)
36 | }
37 |
38 | userModel := user.ConvertInputUserToUserEntity()
39 | createdUser, err := uc.userRepository.CreateUser(userModel)
40 | if err != nil {
41 | errPerso := views.ParseError(
42 | fmt.Sprintf("Error trying to create user, error=%s", err),
43 | http.StatusInternalServerError,
44 | )
45 |
46 | c.JSON(errPerso.ErrorCode, errPerso)
47 | }
48 |
49 | c.JSON(http.StatusOK, views.ConvertUserIntoView(createdUser))
50 | }
51 |
--------------------------------------------------------------------------------
/mvc/src/models/repository/user.go:
--------------------------------------------------------------------------------
1 | package repository
2 |
3 | import (
4 | "github.com/HunCoding/golang-architecture/mvc/src/models"
5 | "go.mongodb.org/mongo-driver/mongo"
6 | )
7 |
8 | func NewUserRepository(
9 | mongodbClient *mongo.Client,
10 | ) UserRepository {
11 | return &userRepository{mongodbClient}
12 | }
13 |
14 | type UserRepository interface {
15 | CreateUser(user *models.User) (*models.User, error)
16 | }
17 |
18 | type userRepository struct {
19 | mongodbClient *mongo.Client
20 | }
21 |
22 | func (ur *userRepository) CreateUser(user *models.User) (*models.User, error) {
23 | //TODO: Implement mongodb user insert
24 | return nil, nil
25 | }
26 |
--------------------------------------------------------------------------------
/mvc/src/models/user.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | type User struct {
4 | Email string `bson:"email"`
5 | Name string `bson:"name"`
6 | Age int `bson:"age"`
7 | Password string `bson:"password"`
8 | }
9 |
10 | func (u *User) VerifyEmail() {
11 | // TODO: Enviar email para o usuario verificando o email dele
12 | }
13 |
14 | func (u *User) CheckDuplicateEmail() {
15 | // TODO: Verificar se o email ja nao existe no banco de dados
16 | }
17 |
--------------------------------------------------------------------------------
/mvc/src/views/errors.go:
--------------------------------------------------------------------------------
1 | package views
2 |
3 | type ErrorView struct {
4 | Message string `json:"message"`
5 | ErrorCode int `json:"errorCode"`
6 | }
7 |
8 | func ParseError(
9 | message string,
10 | errorCode int,
11 | ) *ErrorView {
12 | return &ErrorView{
13 | message, errorCode,
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/mvc/src/views/user.go:
--------------------------------------------------------------------------------
1 | package views
2 |
3 | import "github.com/HunCoding/golang-architecture/mvc/src/models"
4 |
5 | type User struct {
6 | Email string `json:"email"`
7 | Name string `json:"name"`
8 | Age int `json:"age"`
9 | }
10 |
11 | func ConvertUserIntoView(user *models.User) *User {
12 | return &User{
13 | Email: user.Email,
14 | Name: user.Name,
15 | Age: user.Age,
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/singleton/.env:
--------------------------------------------------------------------------------
1 | CAPITALS=TESTE1,TESTE2,TESTE3
--------------------------------------------------------------------------------
/singleton/go.mod:
--------------------------------------------------------------------------------
1 | module singleton
2 |
3 | go 1.19
4 |
5 | require github.com/joho/godotenv v1.5.1 // indirect
6 |
--------------------------------------------------------------------------------
/singleton/go.sum:
--------------------------------------------------------------------------------
1 | github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
2 | github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
3 |
--------------------------------------------------------------------------------
/singleton/singleton.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "github.com/joho/godotenv"
6 | "os"
7 | "strings"
8 | "sync"
9 | )
10 |
11 | type singletonDatabase struct {
12 | capital []string
13 | }
14 |
15 | func (sd *singletonDatabase) GetCapitals() []string {
16 | return sd.capital
17 | }
18 |
19 | var once sync.Once
20 | var instance *singletonDatabase
21 |
22 | func NewSingletonDatabase() *singletonDatabase {
23 | godotenv.Load(".env")
24 | capitals := strings.Split(os.Getenv("CAPITALS"), ",")
25 | once.Do(func() {
26 | db := singletonDatabase{capitals}
27 | fmt.Println("Iniciou a variavel")
28 | instance = &db
29 | })
30 | fmt.Println(&instance)
31 | return instance
32 | }
33 |
34 | func main() {
35 | fmt.Println(NewSingletonDatabase(), NewSingletonDatabase())
36 | }
37 |
--------------------------------------------------------------------------------
/solid/dependency-inversion-principle/dip.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math/rand"
6 | "strconv"
7 | )
8 |
9 | type UserRepository interface {
10 | InsertUser(user_id string, name string) *User
11 | GetUserByID(user_id string) *User
12 | }
13 |
14 | type mysqlRepository struct{}
15 | type mongodbRepository struct{}
16 |
17 | func (m *mongodbRepository) InsertUser(user_id string, name string) *User {
18 | panic("not implemented") // TODO: Implement
19 | }
20 |
21 | func (m *mongodbRepository) GetUserByID(user_id string) *User {
22 | panic("not implemented") // TODO: Implement
23 | }
24 |
25 | type userServices struct {
26 | repo UserRepository
27 | }
28 |
29 | func (m *mysqlRepository) InsertUser(user_id string, name string) *User {
30 | user := User{user_id, name}
31 | inMemoUsers[user_id] = user
32 | return &user
33 | }
34 |
35 | func (m *mysqlRepository) GetUserByID(user_id string) *User {
36 | user, ok := inMemoUsers[user_id]
37 | if !ok {
38 | return nil
39 | }
40 |
41 | return &user
42 | }
43 |
44 | var (
45 | inMemoUsers map[string]User
46 | )
47 |
48 | func init() {
49 | inMemoUsers = make(map[string]User)
50 | }
51 |
52 | type User struct {
53 | id string
54 | name string
55 | }
56 |
57 | func main() {
58 | mongodbRepo := &mongodbRepository{}
59 |
60 | services := &userServices{mongodbRepo}
61 |
62 | name := "HunCoding"
63 | user_inserted := services.InsertUserServices(name)
64 | fmt.Printf("User inserted: %#v \n", user_inserted)
65 |
66 | user_returned := services.GetUserByIDServices(user_inserted.id)
67 | fmt.Printf("User returned from get: %#v \n", user_returned)
68 | }
69 |
70 | // Alto nivel
71 | func (s *userServices) GetUserByIDServices(user_id string) *User {
72 | return s.repo.GetUserByID(user_id)
73 | }
74 |
75 | // Alto nivel
76 | func (s *userServices) InsertUserServices(name string) *User {
77 | user_id := strconv.Itoa(rand.Intn(100000))
78 |
79 | return s.repo.InsertUser(user_id, name)
80 | }
81 |
--------------------------------------------------------------------------------
/solid/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/HunCoding/golang-architecture/solid
2 |
3 | go 1.18
4 |
--------------------------------------------------------------------------------
/solid/interface-segregration-principle/main.go:
--------------------------------------------------------------------------------
1 | package interfacesegregrationprinciple
2 |
3 | type Trabalho interface {
4 | Entrar()
5 |
6 | ComecarATrabalhar()
7 |
8 | ContinuarATrabalhar()
9 |
10 | Sair()
11 | }
12 |
13 | type HumanoTasks interface {
14 | Trabalho
15 |
16 | PausaProCafe()
17 |
18 | Almocar()
19 | }
20 |
21 | type RoboTasks interface {
22 | Trabalho
23 |
24 | VerificarOleo()
25 |
26 | CarregarBateria()
27 | }
28 |
29 | type Robo struct{}
30 |
31 | type Humano struct{}
32 |
--------------------------------------------------------------------------------
/solid/liskov-substitution-principle/main.go:
--------------------------------------------------------------------------------
1 | package liskovsubstitutionprinciple
2 |
3 | type Area interface {
4 | GetArea() float64
5 | }
6 |
7 | type RetanguloType interface {
8 | Area
9 |
10 | GetWidth() float64
11 | GetHeight() float64
12 |
13 | SetWidth(width float64)
14 | SetHeight(height float64)
15 | }
16 |
17 | type QuadradoType interface {
18 | Area
19 |
20 | SetSize(size float64)
21 | GetSize() float64
22 | }
23 |
24 | func (r *Quadrado) GetArea() float64 {
25 | return r.size * r.size
26 | }
27 |
28 | func (r *Quadrado) SetSize(size float64) {
29 | r.size = size
30 | }
31 |
32 | func (r *Quadrado) GetSize() float64 {
33 | return r.size
34 | }
35 |
36 | type Quadrado struct {
37 | size float64
38 | }
39 |
40 | type Retangulo struct {
41 | width, height float64
42 | }
43 |
44 | func (r *Retangulo) GetArea() float64 {
45 | return r.width * r.height
46 | }
47 |
48 | func (r *Retangulo) GetWidth() float64 {
49 | return r.width
50 | }
51 |
52 | func (r *Retangulo) GetHeight() float64 {
53 | panic("not implemented") // TODO: Implement
54 | }
55 |
56 | func (r *Retangulo) SetWidth(width float64) {
57 | panic("not implemented") // TODO: Implement
58 | }
59 |
60 | func (r *Retangulo) SetHeight(height float64) {
61 | panic("not implemented") // TODO: Implement
62 | }
63 |
--------------------------------------------------------------------------------
/solid/open-closed-principle/right_way.go:
--------------------------------------------------------------------------------
1 | package singleresponsibility
2 |
3 | type FuncPJ struct{}
4 | type FuncCLT struct{}
5 | type FuncEstagiario struct{}
6 |
7 | type Funcionario interface {
8 | CalcularSalario() float64
9 | }
10 |
11 | func main() {
12 | funcionario := &FuncPJ{}
13 | funcionario.CalcularSalario()
14 |
15 | stag := &FuncEstagiario{}
16 | stag.CalcularSalario()
17 |
18 | FolhaDePagamento(stag)
19 | }
20 |
21 | func (f *FuncPJ) CalcularSalario() float64 {
22 | //Calcular salario
23 | return 0.0
24 | }
25 |
26 | func (f *FuncCLT) CalcularSalario() float64 {
27 | //Calcular salario + beneficios
28 | return 0.0
29 | }
30 |
31 | func (f *FuncEstagiario) CalcularSalario() float64 {
32 | //Calcular bolsa auxilio
33 | return 0.0
34 | }
35 |
36 | func FolhaDePagamento(funcionario Funcionario) float64 {
37 | return funcionario.CalcularSalario()
38 | }
39 |
--------------------------------------------------------------------------------
/solid/open-closed-principle/wrong_way.go:
--------------------------------------------------------------------------------
1 | package singleresponsibility
2 |
3 | import "reflect"
4 |
5 | type FuncionarioCLT struct{}
6 | type FuncionarioPJ struct{}
7 | type Estagiario struct{}
8 |
9 | func FolhaDePag[TipoFuncionario FuncionarioCLT | Estagiario | FuncionarioPJ](funcionario TipoFuncionario) float64 {
10 |
11 | if reflect.TypeOf(FuncionarioCLT{}) == reflect.TypeOf(funcionario) {
12 |
13 | //Calcular salario + beneficios
14 | return 0.0
15 |
16 | } else if reflect.TypeOf(FuncionarioPJ{}) == reflect.TypeOf(funcionario) {
17 |
18 | // Calcular salario do PJ
19 | return 0.0
20 |
21 | } else {
22 |
23 | //Calcular bolsa auxilio do estagiario
24 | return 0.0
25 |
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/solid/single-responsibility-principle/god_object.go:
--------------------------------------------------------------------------------
1 | package singleresponsibilityprinciple
2 |
3 | import (
4 | "io/ioutil"
5 | "net/url"
6 | "strings"
7 | )
8 |
9 | type Journal struct {
10 | News []string
11 | }
12 |
13 | func (j *Journal) String() string {
14 | return strings.Join(j.News, "\n")
15 | }
16 |
17 | func (j *Journal) AddNews(news string) {
18 | //...
19 | }
20 |
21 | func (j *Journal) RemoveNews(news string) {
22 | //...
23 | }
24 |
25 | func (j *Journal) UpdateNews(news string) {
26 | //...
27 | }
28 |
29 | func (j *Journal) DeleteNews(news string) {
30 | //...
31 | }
32 |
33 | func (j *Journal) PrintNews(filename string, news string) {
34 | _ = ioutil.WriteFile(filename, []byte(j.String()), 0644)
35 | }
36 |
37 | func (j *Journal) LoadNewsFromFile(filename string) {
38 | //...
39 | }
40 |
41 | func (j *Journal) LoadNewsFromWeb(website *url.URL) {
42 | //...
43 | }
44 |
--------------------------------------------------------------------------------
/solid/single-responsibility-principle/journal.go:
--------------------------------------------------------------------------------
1 | package singleresponsibilityprinciple
2 |
3 | import "strings"
4 |
5 | type JournalClassic struct {
6 | News []string
7 | }
8 |
9 | func (j *JournalClassic) String() string {
10 | return strings.Join(j.News, "\n")
11 | }
12 |
13 | func (j *JournalClassic) AddNews(news string) {
14 | //...
15 | }
16 |
17 | func (j *JournalClassic) RemoveNews(news string) {
18 | //...
19 | }
20 |
21 | func (j *JournalClassic) UpdateNews(news string) {
22 | //...
23 | }
24 |
25 | func (j *JournalClassic) DeleteNews(news string) {
26 | //...
27 | }
28 |
--------------------------------------------------------------------------------
/solid/single-responsibility-principle/load_news.go:
--------------------------------------------------------------------------------
1 | package singleresponsibilityprinciple
2 |
3 | import "net/url"
4 |
5 | func LoadNewsFromFile(filename string) {
6 | //...
7 | }
8 |
9 | func LoadNewsFromWeb(website *url.URL) {
10 | //...
11 | }
12 |
--------------------------------------------------------------------------------
/solid/single-responsibility-principle/printer.go:
--------------------------------------------------------------------------------
1 | package singleresponsibilityprinciple
2 |
3 | import (
4 | "io/ioutil"
5 | )
6 |
7 | func PrintNews(filename string, journal JournalClassic) {
8 | _ = ioutil.WriteFile(filename, []byte(journal.String()), 0644)
9 | }
10 |
--------------------------------------------------------------------------------