Code Monkey home page Code Monkey logo

ca-microservices-go's People

Contributors

dependabot[bot] avatar marcos-wz avatar maritza05 avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

ca-microservices-go's Issues

Apply the GO style to the project's directory layout.

The go modules suggest putting the packages at the top/root level as much as possible.

Advantages:

  • Encapsulate each package-specific logic
  • Isolated: keeps dependencies logic/maintenance within the package's scope and avoids importing circle issues
  • Focus on the Dependency injection pattern
  • Ready for implementation of the SOLID principles
  • Maintainable code
  • Simple, readable layout.

Implement Http Server

Implement Http Server

  • Chi router
  • Router(mux)
  • Server Management through Make statements

Implement Controller Layer

Implement the following controllers based on the Echo framework

  • Health Check
  • User

Additionally, implement unit testing

Database multi-driver support

Implement some of the most used DBMS on the market. The following are some of the proposals in higher priority order:

  • PostgreSQL(pq/pgx)
  • MySQL: requires deployment implementation
  • SQL-Server: windows SQL server requires deployment implementation
  • MongoDB: requires deployment implementation
  • Datastore(GCP)
  • CSV
  • SQLite

Repository Refinement

In the initial version, we only got a basic and functional version of the repository, so it is necessary to refine all its components.

To be refined:

  • Implement DTOs as arguments and responses
  • Change the ID type to use UUID
  • Added Pgx-Pool support to the driver
  • Mocking and Integration tests
  • Handling error. Remember to configure the specific response in the controller error handler.
  • Naming conventions
  • Remove boilerplate code
  • Performance
  • Best practices

Miltiple Web Framework support

Implement the most used frameworks on the market

  • Echo: requires deployment implementation
  • Gin: requires deployment implementation

Configs - Refinement

Wondering if it might be useful to retrieve the configuration by json or yaml files.

Implement PostgreSQL service for Github Actions

Create the test job in the CI workflow with PostgreSQL service support.

The following additional tasks must be addressed:

  • Implement testing for the migrations tool
  • Implement testing for the PostgreSQL driver
  • Implement testing for the repository layer
  • Implement testing for the app layer

Implement Service

Implement the Service component on the following layers:

  • Domain(definition)
  • Service(implementation)

Also, please make sure to cover 100% of the testing.

Add PostgreSQL support

Add PostgreSQL database driver.

Changes:

  • Added initial PostgreSQL containerized environment
  • Implemented the infrastructure driver into the application
  • Refactored PostgreSQL config entity definition
  • Added Unit test

Optional: add PgAdmin support(PostgreSQL Web-GUI)

Migrate to Alpine based images

Migrate the deployment environment to Alpine-based images. The following infrastructure components must be migrated:

  • GO Official docker image
  • PostgreSQL Official docker image

Implement Repository

Implement the Repository component on the following layers:

  • Domain(definition)
  • Infraestructure(implementation)

Also, please make sure to cover 100% of the testing.

Controller Refinement

In the initial version, we only got a basic and functional version of the controller, so it is necessary to refine all its components.

To be refined:

  • Add comments to exported functions and special logic.
  • Fix naming conventions
  • Removed Boilerplate code
  • Improve unit Testing
  • Follow best practices

Service Refinement

In the initial version, we only got a basic and functional version of the service, so it is necessary to refine all its components.

To be refined:

  • Validate active user is set to TRUE on responses(include test cases)
  • Implement DTO UserResponse in the Find function.
  • Testing
  • Handling error. Remember to configure the specific response in the controller error handler.
  • Naming conventions
  • Remove boilerplate code
  • Performance
  • Best practices

Issues to be fixed:

  • Deleting a not existent user returns true
  • It's not able to authenticate the user due to always returns invalid password error.

Improve Documentation

Improve Documentation about the following process and components.

  • Makefile: describe the make statements in the README file and make help target/statement

Create the base project structure

This issue is to discuss the best project structure following a hexagonal architecture.

First approach

  • Follows first the “who you are” and then “what is your type” pattern.
  • Clearly shows what is the domain of the project, eg. you can see at first sight that the project is about movies.
  • Having a project whose directories are named according to the hexagonal architecture (eg. ports, application and adapters) could be confusing, especially for engineers who aren’t completely familiar with the architecture, this approach goes for clear and simple names so that the project structure still can be understood without requiring previous knowledge of the hexagonal architecture.
  • Easy to locate where something goes and where to look for it, eg. if you’re looking for things related to the movie entity just go to the “movies” folder.
  • We have separate repositories focused on the entities and their use cases preventing us from having one big repository through which we access all entities. This way is more decoupled to the point that we can have entities stored in separate databases.
            
                    .
                ├── core (src) /
                │   ├── movies/
                │   │   ├── infraestructure/
                │   │   │   ├── postgresql_movie_repository.go
                │   │   │   ├── http_handlers.go
                │   │   │   └── tests/
                │   │   │       └── (unit test here)
                │   │   ├── use_cases(services/application)/
                │   │   │   ├── add_movie.go
                │   │   │   ├── remove_movie.go
                │   │   │   ├── requests */
                │   │   │   │   └── add_movie_request.go
                │   │   │   └── tests/
                │   │   │       └── (unit test here)
                │   │   └── domain/
                │   │       ├── movie.go
                │   │       ├── movies_repository.go (interface for repositories)
                │   │       └── tests/
                │   │           └── (integration tests here)
                │   └── users/
                │       ├── infraestructure/
                │       │   ├── postgresql_user_repository.go
                │       │   ├── http_handlers.go
                │       │   └── tests
                │       ├── use_cases(services/application)/
                │       │   ├── add_user.go
                │       │   ├── remove_user.go
                │       │   ├── search_user.go
                │       │   ├── requests */
                │       │   │   └── add_user_request.go
                │       │   └── tests
                │       └── domain/
                │           ├── user.go
                │           └── user_repository.go (interface for repositories)
                ├── rest_api/
                │   └── routes.go (we setup the routes here)
                ├── main.go
                ├── dockerfile
                └── Makefile

Here the directories requests and responses in “usecases” are optional, they are suggested because we could define the DTOs (data transfer objects) we need them when an entity of a use case needs a complex input that isn’t defined a domain entity:

  • The input is not a complete domain entity or of a simple type (like a single ID).
  • If it's complex enough it could require validation
  • Thus in the request folder we could have the structs that could contain the input for a use case and would also be the perfect place to make input validations this way we don’t need to define input validations inside the use cases.
  • They don’t need to be defined in a separate file or folder they also could be defined in the same file as the usecase.

For example, you can find users with this necessity, source reddit

Yeah that is exactly what I was doing, until I faced this situation where I have a complex query that doesn't return any domain model, because the query involves lots of join between tables, so the object it is returning doesn't represent a unique domain model but multiple ones. So I need the data layer to return a complex object that doesn't represent pure DB entity, that's why I need a DTO.

An example of the use of DTOs can be found at this repo so a request would look like this in go:

 package dto
            
import (
      "github.com/ashishjuyal/banking-lib/errs"
      "strings"
)
            
 type NewAccountRequest struct {
         CustomerId  string  `json:"customer_id"`
          AccountType string  `json:"account_type"`
          Amount      float64 `json:"amount"`
}
            
func (r NewAccountRequest) Validate() *errs.AppError {
         if r.Amount < 5000 {
            return errs.NewValidationError("To open a new account you need to deposit atleast 5000.00")
          }
          if strings.ToLower(r.AccountType) != "saving" && strings.ToLower(r.AccountType) != "checking" {
            return errs.NewValidationError("Account type should be checking or saving")
          }
         return nil
}

We could also have a response directory to define the output of the use cases in case that they could be complex structs different from the domains. Also they could be defined in the same file as the use case.

package dto
            
type NewAccountResponse struct {
    AccountId string `json:"account_id"`
}

A video of this structure can be found at this youtube video

Second approach

This could be another approach, with this structure the first obvious thing is that we have a project that follows the hexagonal architecture, ins’t my favorite given the obscurity of some folder names (you’ll need to explain the complete architecture in the README for team members that don’t have the complete context).

            .
            ├── .env
            ├── go.mod
            ├── go.sum
            ├── internal/
            │   ├── core/
            │   │   ├── domain/
            │   │   │   ├── movies.go
            │   │   │   └── users.go
            │   │   ├── ports/
            │   │   │   ├── movies_repository.go
            │   │   │   └── users_repository.go
            │   │   └── services/
            │   │       ├── movies.go
            │   │       └── users.go
            │   └── adapters/
            │       ├── http_handlers/
            │       │   ├── movies_handler.go
            │       │   └── users_handler.go
            │       ├── repository/
            │       │   └── postgres/
            │       │       ├── users_repository.go
            │       │       └── movies_repository.go
            │       └── tests
            └── rest_api/
                └── main.go

We could also apply the use of DTOs for validation creating requests and responses folder or just define them in the file for each service.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.