Skip to content

skport/golang-cli-architecture

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

golang-cli-architecture

The main objective of this repository is to compose a versatile architecture.

It's a simple Cobra CLI application and displays a summary of the target website.

Clean architecture, testing of command lined, switching production or development environments, and abstraction of data sources through dependency injection (DI). It includes the base elements of any project.

This is published as a record of my Golang learning.

Dependency Module list (Package)

Detail : go.mod

Installation

Create go.sum:

go mod tidy

Usage

go run ./app/cli/main.go summary [Target URL]

Response:

title : [string]
H1 : [string]

Architecture

Keeping the nature of the Cobra code that exposes the cmd as a variable, adding application logic in a form that is easy to separate.

flowchart LR
    subgraph Controller
    id1["cobra (app/cli/cmd)"]
    end
    subgraph Application
    core/app
    end
    subgraph Domain
    core/url
    end
    subgraph DataStore
    core/url/provider
    end
    Controller --- Application
    Application --- Domain
    Application --- DataStore
    Domain --- DataStore
Loading

Class Diagram (core/)

classDiagram
  Url -- App
  Url -- Provider
  Provider -- App
  Provider <|.. WebProvider : Realization
  Provider <|.. InMemDummyProvider : Realization
  class App {
    +CmdSummary()
  }
  class Url {
    -validate()
  }
  class Provider
  <<interface>> Provider
  Provider : +ReadBody()
  class WebProvider {
    +ReadBody()
  }
  class InMemDummyProvider {
    +ReadBody()
  }
Loading

Switching easily data stores

The application depends on a data store, but uses a DI container to ease changing. In the case of this program, the data store is the Web, but a database is typically used.

Initialize DI Container (app/cli/cmd/root.go):

// Initialize DI container
diContainer = *dig.New()
diContainer.Provide(app.NewApp)

// Register UrlProvider to use with Container
// Switch data source external or dummy
if env == "production" {
  diContainer.Provide(url.NewWebProvider)
  return
}
diContainer.Provide(url.NewInMemDummyProvider)

Use Container (app/cli/cmd/summary.go):

// Application Logic
// Create app Instance via DI Container
diContainer.Invoke(
  func(a *app.App) {
    a.CmdSummary(args)
  },
)

Environment

To switch environments, modify the .env file in the root directory as you would in a typical project. If this element is development, the data source is in-memory. (If production, the data source is web.)

development:

APP_ENV=development

production:

APP_ENV=production

If nothing is specified, Switch to development env.

Testing

go test ./app/cli/cmd -v

In the go test command, the environment is always development. This is because the current directory is the directory to be tested, and therefore the .env fails to be retrieved.

ToDo

  • More abstraction

About

A architecture example for Cobra CLI application.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages