Code Monkey home page Code Monkey logo

go-clean-echo's Introduction

Go Echo Simple API with Clean Architecture

Build & Unit Test

๐Ÿค“ About this repo

This is a sample of Web API built by Go (Echo) according to Clean architecture.
But I have to say that I'm not a backend specialist nor of Go, so Clean architecture here could be wrong or missing essential concepts. (I'm sorry in that case)

This sample consists of 4 layers, "Models", "Stores", "Services(Logic)" and "Handlers(Framework)", although naming might differ in other samples. Each layer only concerns/handles its inside layer, not the other way around. This makes it super easy to replace each layer. (also good for testing)

clean architecture

What you might find helpful in this repo.


๐Ÿ‘Ÿ How to run

Install.

git clone [email protected]:zett-8/go-clean-echo.git

cd go-clean-echo

Download dependencies.

go mod download

Fill out auth0 config to run with JWT authentication. Or simply disable JWT middleware

// configs/auth0.go
var Auth0Config = Auth0ConfigType{
    Domain:             "****",
    ClientID:           "****",
    Audience:           []string{"****"},
    Issuer:             "****",
    SignatureAlgorithm: validator.RS256,
    CacheDuration:      15 * time.Minute,
}

// or 

// handlers/handlers.go
func SetApi(e *echo.Echo, h *Handlers, m echo.MiddlewareFunc) {
    g := e.Group("/api/v1")
    g.Use(m) // <- Comment out this line
}

Run docker.

docker-compose up

๐ŸŒฑ Tips

Use multi-stage build

Using multistage build reduces the size of the docker image.

ARG PORT=8888

# Base image for local development. Use 'air' for hot reload.
FROM golang:1.18-alpine as base

ARG PORT
ENV PORT=$PORT
ENV GO_ENV=development

WORKDIR /go/app/base

COPY go.mod .
COPY go.sum .

RUN apk add build-base
RUN go mod download
RUN go install github.com/cosmtrek/air@latest

COPY . .


# The image for build. Set CGO_ENABLE=0 not to build unnecessary binary.
FROM golang:1.18-alpine as builder

ARG PORT
ENV PORT=$PORT

WORKDIR /go/app/builder

COPY --from=base /go/app/base /go/app/builder

RUN CGO_ENABLED=0 go build -o main -ldflags "-s -w"


# The final image to run 
FROM gcr.io/distroless/static-debian11 as production

ARG PORT
ENV PORT=$PORT

WORKDIR /go/app/src

COPY --from=builder /go/app/builder/main /go/app/src/main

EXPOSE $PORT

CMD ["/go/app/src/main"]

Use "Air" for hot reload

We used to have other reloaders such as realize. But it seems no longer be developed or maintained, so I recommend to use "air"

cosmtrek/air.

Mock a unit for testing

Here is one example to mock "service" for "handler" test.

Let's say this is the service to mock.

// services/services.go
type Services struct {
    AuthorService
    BookService
}

func New(s *stores.Stores) *Services {
    return &Services{
        AuthorService: &authorService{s.AuthorStore},
        BookService:   &bookService{s.BookStore},
    }
}

// services/author.go
type (
    AuthorService interface {
        GetAuthors() ([]models.Author, error)
        DeleteAuthor(id int) error
    }

    authorService struct {
        store stores.AuthorStore
    }
)

func (s *AuthorServiceContext) GetAuthors() ([]models.Author, error) {
	r, err := s.store.Get()
	return r, err
}

func (s *AuthorServiceContext) DeleteAuthor(id int) error {
	err := s.store.DeleteById(id)
	return err
}

And in /handlers/author_test.go. Declare Mock struct.

// handlers/author_test.go
type MockAuthorService struct {
	services.AuthorService
	MockGetAuthors       func() ([]models.Author, error)
	MockDeleteAuthorById func(id int) error
}

func (m *MockAuthorService) GetAuthors() ([]models.Author, error) {
	return m.MockGetAuthors()
}

func (m *MockAuthorService) DeleteAuthor(id int) error {
	return m.MockDeleteAuthorById(id)
}

Then use it as mockService.

// handlers/author_test.go
func TestGetAuthorsSuccessCase(t *testing.T) {
    s := &MockAuthorService{
        MockGetAuthors: func () ([]models.Author, error) {
            var r []models.Author
            return r, nil
        },
    }
    
    mockService := &services.Services{AuthorService: s}
    
    e := Echo()
    h := New(mockService)
}

๐Ÿ“ƒ API Document (Swagger)

http://localhost:8888/swagger/index.html

โœ… Testing

make test

๐Ÿ’œ References

bxcodec/go-clean-arch
onakrainikoff/echo-rest-api
satishbabariya/go-echo-auth0-middleware
xesina/golang-echo-realworld-example-app

go-clean-echo's People

Contributors

zett-8 avatar

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.