Even when developing in Python, the design may be based on a layered architecture. At that time, you may want to check the direction of dependence.
project_root/
├ infrastructure/
│ └ db
├ interface/
│ └ controllers
├ application/
│ └ service
└ domain/
└ entity
As an example, consider the above package configuration.
Suppose you define the direction of the dependency in the form infrastructure-> interface-> application-> domain
.
You can easily fix it by using import-linter to automatically check for imports that break the rules during development.
Sample repository is available. See here for the entire source code.
$ pip install import-linter
Define the layer definition and dependency direction with setup.cfg
or .importlinter
.
First, define the layer in the [importlinter]
section.
[importlinter]
root_packages =
infrastructure
interface
application
domain
type = layers
is a rule setting for layered architecture.
The direction of dependence is expressed in the order of layers.
[importlinter:contract:1]
name = layered architecture contract
type = layers
layers =
infrastructure
interface
application
domain
There are various options (https://github.com/seddonym/import-linter/tree/master/docs) that allow you to configure flexible rules.
For example, if you want to limit the import of flask packages to a specific layer, you can enable include_external_packages
and define it with type = forbidden
as shown below.
[importlinter]
root_packages =
infrastructure
interface
application
domain
include_external_packages = True
[importlinter:contract:2]
name = Do not use `flask` outside the interface layer.
type = forbidden
source_modules =
infrastructure
application
domain
forbidden_modules =
flask
After completing the rule settings, check with the following command.
$ lint-imports
pipenv run lintfix ✘ 1 main ✚ ✱ ◼
Skipped 2 files
=============
Import Linter
=============
---------
Contracts
---------
Analyzed 14 files, 15 dependencies.
-----------------------------------
Layered architecture contract BROKEN
Do not use `flask` outside the interface layer. BROKEN
Contracts: 0 kept, 2 broken.
----------------
Broken contracts
----------------
Layered architecture contract
-----------------------------
domain is not allowed to import application:
- domain.entity -> application.repository (l.5)
Do not use `flask` outside the interface layer.
-----------------------------------------------
infrastructure is not allowed to import flask:
- infrastructure.db -> domain.entity (l.4)
domain.entity -> flask (l.3)
application is not allowed to import flask:
- application.repository -> domain.entity (l.4)
domain.entity -> flask (l.3)
- application.service -> domain.entity (l.6)
domain.entity -> flask (l.3)
domain is not allowed to import flask:
- domain.entity -> flask (l.3)
If there is code that violates the rule, it will display an error.
Let's define it in the CI tool and have it checked at the time of PR.
Recommended Posts