In this article, we'll show what is Arch-Go and how to use it in order to check the architecture of a project in Go.
Arch-Go is a testing tool that verifies if your Go project adheres to your architectural guidelines.
The architectural guidelines of a system defines properties like the following:
- How packages are defined
- How packages interact
- What kind of assets should be part of each package
- Some properties related to specific assets, for example it describes some functions or interfaces properties.
For instance, let's think that you're working on a Rest Service using a layered structure containing the following three packages: presentation, businesslogic and persistence.
- Presentation: it contains our REST handlers.
- Business Logic: it contains the components that encapsulates the business logic of our service.
- Persistence: it contains components to access our persistence services, like a database client.
As we have decided to use a layered architecture, we can find out some dependency rules between its packages:
- The components in presentation package should depend only on components in the businesslogic package.
- The components in businesslogic package should depend only on components in the persistence package.
- Components in persistence package should not depend on any other package.
What happens if a developer includes a dependency that is not allowed?, for example, a handler that depends on a persistence component. Of course, we should detect this violation in a Pull-Request code review, but as this process is manual then is prone to errors, so we can easily get the following result.
What are the consequences of including these dependencies?, in terms of functionalities maybe there will be no impact, but related to system maintenance there are some implications, like:
- Unnecessary coupling between presentation and persistence layers, so changes in persistence probably will have an impact on presentation.
- As our handlers have more dependencies, testing them will require more effort.
- Onboarding of new developers will be more complex, as the explanation of dependencies is an important part of this process.
Arch-Go uses a declarative approach to set the architecture rules, so in order to specify what rules to check we need to setup a YAML file.
The selection of a declarative approach was made thinking in simplify the comprehension of the architectural rules and to help the sharing of these rules between artifacts, products and teams.
- Set what dependencies between packages are allowed and what are not allowed.
- Set the allowed content for the package (interfaces, structs, functions and methods).
- Set the restricted content for the package (interfaces, structs, functions and methods).
- Allows to check for dependency cycles in selected packages.
- Set the maximum number of parameters that functions in a package are allowed to receive.
- Set the maximum number of values that functions in a package are allowed to return.
- Set the maximum number of public functions per file.
- Set the maximum number of lines inside a function.
Arch-Go is currently published as a module, so, in order to install it, you need to execute the
go get command, as follows.
$ go get -u github.com/fdaines/arch-go
For the verification of a successful installation process, you can execute the following command:
$ arch-go -h
Going back to our example service, we can see some dependency rules:
- Components in presentation package should only depends on components in businesslogic package.
- Components in businesslogic package should only depends on components in persistence package.
- Components in persistence package should not depends on any other package.
Those dependency rules, can be described using the Arch-Go YAML schema as follows:
dependenciesRules: - package: "**.presentation" shouldOnlyDependsOn: - "**.businesslogic" - package: "**.businesslogic" shouldOnlyDependsOn: - "**.persistence" shouldNotDependsOn: - "**.presentation" - package: "**.persistence" shouldNotDependsOn: - "**.presentation" - "**.businesslogic"
To run Arch-Go we will use an example project that has the code and rules defined.
$ git clone https://github.com/fdaines/arch-go-sample-project.git $ cd arch-go-sample-project $ arch-go
Of course, we have a code example that violates a dependency rule (the branch is named:
dependency-rule-violation). To check this example, just run in the command line
$ git checkout dependency-rule-violation $ arch-go
To include Arch-Go verification as part of a Github actions workflow, you need to include a YAML file under
github/workflows/, with content as follows:
name: 'arch-go' on: workflow_dispatch: push: branches: - master jobs: Arch-Go: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - uses: actions/setup-go@v2 with: stable: 'false' go-version: '1.15' - name: Install Arch-Go run: go get -u github.com/fdaines/arch-go - name: Run Arch-Go run: arch-go
Then, each time we push into master branch, Github Actions will run this workflow and checks if the code complies with our architectural guidelines.
In this article, we have explored the basics of using Arch-Go to check our projects. Arch-Go simplifies the verification of architectural guidelines improving the quality project for reducing maintenance costs.