Skip to content

Commit

Permalink
Add support modular structure
Browse files Browse the repository at this point in the history
  • Loading branch information
dzungtran committed Jul 20, 2022
1 parent 4227d67 commit 24e2b72
Show file tree
Hide file tree
Showing 91 changed files with 1,970 additions and 1,422 deletions.
27 changes: 13 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,22 @@ Any feedback and pull requests are welcome and highly appreciated. Feel free to
- [x] User Auth functionality (Signup, Login, Forgot Password, Reset Password, 2FA) using [Ory/Kratos](https://github.com/ory/kratos).
- [x] REST API using [labstack/echo](https://github.com/labstack/echo).
- [x] DB Migration using [golang-migrate/migrate](https://github.com/golang-migrate/migrate).
- [x] Modular structure.
- [x] Configs via environmental variables.
- [x] Unit tests.
- [x] Dependency injection using [uber-go/dig](https://github.com/uber-go/dig).
- [x] Role based access control using [Open Policy Agent](https://github.com/open-policy-agent/opa).
- [x] Module generation, quickly create model, usecase, api handler.
- CLI support. try: `make tools` using [spf13/cobra](https://github.com/spf13/cobra).
- [x] CLI support. try: `go run ./tools/mod/ gen` using [spf13/cobra](https://github.com/spf13/cobra).

## Running the project

- Make sure you have docker installed.
- Copy `.env.example` to `.env.docker`
- Add a new line `127.0.0.1 echo-rest.local` to `/etc/hosts` file.
- Run `docker compose up -d`.
- Go to `localhost:8088` to verify if the server works.
- Go to `echo-rest.local:8088` to verify if the API server works.
- Go to `echo-rest.local:4455` to verify if the Kratos works.

## Environment variables

Expand Down Expand Up @@ -88,32 +90,29 @@ Setting your config as Environment Variables is recommended as by 12-Factor App.
├── cmd
│   └── api # Main package of API service
├── config # Application configs struct
├── delivery
│   ├── defines
│   ├── http
│   ├── requests
│   ...
├── docs # Content documentation and PlantUML for charts and diagrams
├── domains
├── infrastructure
├── migrations
│   └── sql # Migration files
├── modules
│ ├── core # Core module, includes apis: users, orgs
│ ├── projects # Demo module generation
│ └── shared # To store common usecases and domains which shared between modules
├── out # Output folder of PlantUML
├── pkg
│   ├── authz # Contents Rego rule files for RBAC
│   ├── constants
│   ├── cue # Contents cue files for data validation
│   ...
│   └── utils # Contents helper functions
├── repositories
│   ├── postgres
│   └── redis
├── tests
── tools
   ├── modtool # Module generation
   ├── routes # Generate routes file for Authorization
   └── scripts # Some helpful bash commands
└── usecases
── tools
   ├── modtool # Module generation
   ├── routes # Generate routes file for Authorization
   └── scripts # Some helpful bash commands
```

## Open source refs
Expand Down
71 changes: 44 additions & 27 deletions cmd/api/di/di.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package di

import (
"github.com/dzungtran/echo-rest-api/config"
httpDelivery "github.com/dzungtran/echo-rest-api/delivery/http"
"github.com/dzungtran/echo-rest-api/infrastructure/datastore"
"github.com/dzungtran/echo-rest-api/modules/core"
"github.com/dzungtran/echo-rest-api/modules/projects"
"github.com/dzungtran/echo-rest-api/pkg/logger"
"github.com/dzungtran/echo-rest-api/pkg/middlewares"
"github.com/dzungtran/echo-rest-api/repositories/postgres"
"github.com/dzungtran/echo-rest-api/usecases"
sqlTools "github.com/dzungtran/echo-rest-api/pkg/sql-tools"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"go.uber.org/dig"
)

Expand All @@ -25,31 +25,48 @@ func BuildDIContainer(
return conf
})

_ = postgres.Inject(container)
_ = usecases.Inject(container)
_ = container.Provide(middlewares.NewMiddlewareManager)
container.Provide(func() *sqlTools.SqlxTransaction {
return sqlTools.NewSqlxTransaction(mdbi)
})

return container
}

func RegisterHandlers(e *echo.Echo, container *dig.Container) error {
return container.Invoke(func(params DIContainerParams) {
e.Use(params.MiddlewareManager.GenerateRequestID())

// Group routes for middlewares
adminGroup := e.Group("/admin",
middleware.CORSWithConfig(params.AppConfig.CORSConfig),
)

hookGroup := e.Group("/hooks",
middleware.CORSWithConfig(params.AppConfig.CORSConfig),
)

// bind api handlers to group
httpDelivery.NewUserHandler(adminGroup, params.MiddlewareManager, params.UserUsecase)
httpDelivery.NewOrgHandler(adminGroup, params.MiddlewareManager, params.OrgUsecase)
httpDelivery.NewKratosHookHandler(hookGroup, params.MiddlewareManager, params.UserUsecase)
// Auto generate
// DO NOT DELETE THIS LINE ABOVE
})
func RegisterModules(e *echo.Echo, container *dig.Container) error {
var err error
mapModules := map[string]core.ModuleInstance{
"core": core.Module,
"projects": projects.Module,
}

gRoot := e.Group("/")
for _, m := range mapModules {
err = m.RegisterRepositories(container)
if err != nil {
logger.Log().Errorf("RegisterRepositories error: %v", err)
return err
}

err = m.RegisterUseCases(container)
if err != nil {
logger.Log().Errorf("RegisterUseCases error: %v", err)
return err
}
}

err = container.Provide(middlewares.NewMiddlewareManager)
if err != nil {
logger.Log().Errorf("RegisterHandlers error: %v", err)
return err
}

for _, m := range mapModules {
err = m.RegisterHandlers(gRoot, container)
if err != nil {
logger.Log().Errorf("RegisterHandlers error: %v", err)
return err
}
}

return err
}
18 changes: 0 additions & 18 deletions cmd/api/di/params.go

This file was deleted.

18 changes: 14 additions & 4 deletions cmd/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func main() {
// init app config
conf, _ := config.InitAppConfig()

logger.InitLog(conf.Environment)
logger.InitWithOptions(logger.WithConfigLevel(conf.LogLevel))
if logger.Log() != nil {
defer logger.Log().Sync()
}
Expand All @@ -31,13 +31,18 @@ func main() {
// Bind default middleware
e.Use(middleware.LoggerWithConfig(config.GetEchoLogConfig(conf)))
e.Use(middleware.Recover())
e.Use(middleware.RequestID())
e.HideBanner = true
// e.HidePort = true
e.Validator = conf.Validator

// Setup infra
mDBInstance := datastore.NewMasterDbInstance(conf.DatabaseURL)
sDBInstance := datastore.NewSlaveDbInstance(conf.DatabaseURL)

if conf.AutoMigrate {
migrations.RunAutoMigrate(mDBInstance.DBX().DB)
migrateDBInstance := datastore.NewMasterDbInstance(conf.DatabaseURL)
migrations.RunAutoMigrate(migrateDBInstance.DBX().DB)
}

// Setup middleware manager
Expand All @@ -59,15 +64,20 @@ func main() {
})
})

err := di.RegisterHandlers(e, container)
err := di.RegisterModules(e, container)
if err != nil {
e.Logger.Fatal(err)
}

// err = di.RegisterHandlers(e, container)
// if err != nil {
// e.Logger.Fatal(err)
// }

// Start server
go func() {
if err := e.Start(":" + conf.AppPort); err != nil && err != http.ErrServerClosed {
e.Logger.Fatal("shutting down the server")
logger.Log().Fatal("shutting down the server")
}
}()

Expand Down
4 changes: 3 additions & 1 deletion config/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type AppConfig struct {
KratosWebhookApiKey string `json:"kratos_webhook_api_key"`
KratosApiEndpoint string `json:"kratos_api_endpoint"`
AutoMigrate bool `json:"auto_migrate"`
LogLevel string `json:"log_level"`
}

type AppValidator struct {
Expand All @@ -39,7 +40,7 @@ func InitAppConfig() (*AppConfig, error) {
currentEnv := "development"
appPort := os.Getenv("PORT")
if appPort == "" {
appPort = "8080"
appPort = "8088"
}

if os.Getenv("ENV") != "" {
Expand All @@ -58,5 +59,6 @@ func InitAppConfig() (*AppConfig, error) {
AutoMigrate: os.Getenv("AUTO_MIGRATE") == "true",
KratosWebhookApiKey: os.Getenv("KRATOS_WEBHOOK_API_KEY"),
KratosApiEndpoint: os.Getenv("KRATOS_API_ENDPOINT"),
LogLevel: os.Getenv("LOG_LEVEL"),
}, nil
}
20 changes: 0 additions & 20 deletions delivery/requests/pass.go

This file was deleted.

23 changes: 0 additions & 23 deletions delivery/requests/user.go

This file was deleted.

13 changes: 0 additions & 13 deletions domains/verifiable.go

This file was deleted.

Loading

0 comments on commit 24e2b72

Please sign in to comment.