LoginSignup
2
5

More than 3 years have passed since last update.

Pythonでレイヤードアーキテクチャするときはimport-linterが便利だった

Last updated at Posted at 2021-01-09

概要

Pythonで開発する場合でもレイヤードアーキテクチャーをベースとした設計をすることがあります。
その時、依存の方向性をチェックしたくなる時があります。

project_root/
  ├ infrastructure/
  │ └ db
  ├ interface/
  │ └ controllers
  ├ application/
  │ └ service
  └ domain/
    └ entity

例として上記の様なパッケージ構成を考えます。
依存の方向性をinfrastructure -> interface -> application -> domainと言った形で定義しているとします。
開発時にルールを破っているインポートを自動でチェックするにはimport-linterを使うと簡単に解決できます。

サンプルのリポジトリを用意しました。ソースコード全体はこちらを参照してください。

使い方

$ pip install import-linter

setup.cfg.importlinterでレイヤーの定義と依存の方向性を定義します。
まずは[importlinter]のセクションでレイヤーの定義をします。

[importlinter]
root_packages =
    infrastructure
    interface
    application
    domain

type = layersはレイヤードアーキテクチャ用のルール設定です。
依存の方向性をレイヤーの順序で表現しています。

[importlinter:contract:1]
name = layered architecture contract
type = layers
layers =
    infrastructure
    interface
    application
    domain

様々なオプションがあり柔軟なルールを構成することができます。
例えばflaskのパッケージのインポートを特定のレイヤーに限定したい場合などは、include_external_packagesを有効にして下記のようにtype = forbiddenで定義することができます。

[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

チェックする

ルールの設定が完了したら以下のコマンドでチェックを行います。

$ 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)

ルール違反を行なっているコードが存在する場合はエラーを表示してくれます。

CIツールに定義してPR時にチェックしてもらいましょう。

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5