Summary
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.
What is Arch-Go?
Arch-Go is a testing tool that verifies if your Go project adheres to your architectural guidelines.
A little review of 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.
Declarative aproach
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.
Verification rules in Arch-Go
Rules for dependencies between packages:
- Set what dependencies between packages are allowed and what are not allowed.
Rules for packages content:
- Set the allowed content for the package (interfaces, structs, functions and methods).
- Set the restricted content for the package (interfaces, structs, functions and methods).
Cyclic dependencies:
- Allows to check for dependency cycles in selected packages.
Functions properties:
- 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.
Architecture validation using Arch-Go
Installation
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
Creating Dependencies Rules
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"
Running Arch-Go
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
As our project complies with our architectural guidelines, the output should be similar to:
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
In this case, the output from Arch-Go should be similar as follows.
Running Arch-Go as part of a Github Actions Workflow
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.
Conclusion
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.
Top comments (0)