Git Product home page Git Product logo

clean-architecture-go's Introduction

Clean Architecture in Go

This old repository doesn't represent what I'm using nowadays. In 2023, I am using and recommending what my colleagues and I have described in this post

Build Status

Clean Architecture sample

Post

https://medium.com/@eminetto/clean-architecture-using-golang-b63587aa5e3f

Build

make

Run tests

make test

API requests

Add a bookmark

curl -X "POST" "http://localhost:8080/v1/bookmark" \
     -H 'Content-Type: application/json' \
     -H 'Accept: application/json' \
     -d $'{
  "tags": [
    "git",
    "social"
  ],
  "name": "Github",
  "description": "Github site",
  "link": "http://github.com"
}'

Search a bookmark

curl "http://localhost:8080/v1/bookmark?name=github" \
     -H 'Content-Type: application/json' \
     -H 'Accept: application/json'

Show all bookmarks

curl "http://localhost:8080/v1/bookmark" \
     -H 'Content-Type: application/json' \
     -H 'Accept: application/json'

CMD

Search for a bookmark

./bin/search github

clean-architecture-go's People

Contributors

eminetto avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

clean-architecture-go's Issues

Doubts using gqlgen for graphql endpoint

@eminetto thanks for your project.

https://github.com/bxcodec/go-clean-arch is a similar one and I opened a PR (bxcodec/go-clean-arch#39) for understand how to use https://github.com/99designs/gqlgen with Clean Architecture.

Is gqlgen in this case just a "third party" delivery layer?

I don't know if I'm doing this well: I'm using just graphql dir in root!

Because - as you can see - code is generated I can just inject usecases in main.go for the graphql.Resolver{}:

e.POST("graphql", echo.WrapHandler(handler.GraphQL(graphql.NewExecutableSchema(graphql.Config{Resolvers: &graphql.Resolver{
    ArticleUsecase: au,
    // <--- other usecases here --->
}}))))

and I use that usecases in resolver.go:

func (r *queryResolver) Articles(ctx context.Context) ([]*models.Article, error) {
	articles, _, err := r.ArticleUsecase.Fetch(ctx, "cursor", 1) // <--- example values because I don't want to change Usecase now
	return articles, err
}

What do you think about?

  1. Am I respecting the principles of "clean architecture"?

  2. Is there a more elegant solution?


A more extensive example of gqlgen in action can be found here: https://github.com/oshalygin/gqlgen-pg-todo-example.
As you can see he's injecting db *pg.DB in main.go file for

Resolvers: &resolvers.Resolver{
	DB: db,
}

Make command fails to compile

Hi

The make command as defined in your docs fails to work. We get a very cryptic and strange message saying it can't find the package main.go in any of the normal paths.

After debugging there seems to be a bug in your Makefile at the top you define a default BOOKMARK_ENV variable that is set to dev by default. Later on in your recipes you use a CODENATION_ENV variable that is never set. This is causing the error. Changing BOOKMARK_ENV to CODENATION_ENV at the top of the Makefile fixed the issue.

Multi-tenancy logic related to repository, usecase or handler layer?

@eminetto thanks for your amazing work! Go is just a hobby for me and I'm having fun. I'm learning a lot from your project.

I'm trying to understand if multi-tenancy column/table based is something to be "included", if it is "related to" the repository, service or handler level.

Example

Adding tenant.go model like this:

package entity

type Tenant struct {
	ID   int64  `json:"id"`
	Name string `json:"name"`
}

to other models like this:

package entity

import "time"

type Bookmark struct {
	ID          ID        `json:"id"`
	TenantID    int64     `json:"tenant_id"` // <--- here
	Tenant      *Tenant   // <--- here
	Name        string    `json:"name"`
	Description string    `json:"description"`
	Link        string    `json:"link"`
	Tags        []string  `json:"tags"`
	Favorite    bool      `json:"favorite"`
	CreatedAt   time.Time `json:"created_at"`
}

Let's talk for example of the Store() method:

Question

Let's say my tenant_id is a field of a User struct in context on every request (authenticated by a third party middleware).

Where do you think I should do something like below? In handler, service or repository?

tenantID := GetTenantIDFromUserInContext()
article.TenantID = tenantID

Doubts about fetch queries

Today, before I discover the amazing "clean architecture", I'm using a where clause in my SQL queries (go-pg/pg#1179), like this:

// Used as: "q.Apply(FilterByTenant(ctx))"
func FilterByTenant(ctx context.Context) func(q *orm.Query) (*orm.Query, error) {
	user := ctx.Value(auth.CTXKeyUser).(*models.User)
	return func(q *orm.Query) (*orm.Query, error) {
		q = q.Where("tenant_id = ?", user.TenantID)
		return q, nil
	}
}

I think maybe the concept of FilterByTenant in the service layer is an unnecessary repetition and should belong to lower levels like repositories?

But I also think that the main multi-tenancy logic does not change with the change of possible repository types (Postgres, Mysql, Mongo, microservices).

What do you think about it?

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.