Architecture: 概要


Hanami は2つの原則に基づいています: クリーンアーキテクチャMonolith First

クリーンアーキテクチャ

このアーキテクチャの主な目的は、プロダクトのコア配信メカニズムとの間で懸念を分離することです。 前者は私たちのプロダクトが実装するユースケースのセットで表現され、後者はこれらの機能を外の世界で利用できるようにするためのインターフェースです。

新しいプロジェクトを生成すると、2つの重要なディレクトリが見つかります: lib/apps/。 それらは上記の主要部分のホームです。

アプリケーションコア

どのように外部の世界に公開されるのかを心配することなく、一連の機能を実装します。 これが私たちのプロダクトの土台であり、私たちはそれに対する依存関係をどのように管理するかに注意を払いたいのです。

Hanami::Modelは、私たちのRubyオブジェクトを永続化するためのデフォルトの選択です。 これは_ソフトな依存関係_です。Gemfileから削除して他のものに置き換えることができます。

Hanami::Modelを使用するbookshelfという名前の新しく作られたプロジェクトに対してlib/ディレクトリがどのように表示されるかを見てみましょう。

$ tree lib
lib
├── bookshelf
│   ├── entities
│   ├── mailers
│   │   └── templates
│   └── repositories
└── bookshelf.rb

5 directories, 1 file

そのアイデアは私たちのアプリケーションをRuby gemのように開発することです。

lib/bookshelf.rbファイルが私たちのアプリケーションの入り口になっています。このファイルが必要なときは、lib/下にあるすべてのコードを必要とし、初期化します。

2つの重要なディレクトリがあります:

  • lib/bookshelf/entities
  • lib/bookshelf/repositories

それらは私たちのモデルドメインの中核にあるRubyオブジェクトであるエンティティを含んでいます、そしてそれらはどんな永続化メカニズムも知りません。 この目的のために私たちは別の概念、リポジトリを持っています。それは私たちのエンティティと基礎となるデータベースの間の仲介者です。

Bookというエンティティごとに、BookRepositoryを持つことができます。

私たちはユースケースを実装するためにlib/bookshelf/interactorsのように望むだけ多くのディレクトリを追加することができます。

配送メカニズム

HanamiはWebという名前のデフォルトアプリケーションを生成します。これはapps/web下にあります。 このアプリケーションは、エンティティ、リポジトリ、およびそこで定義されている他のすべてのオブジェクトを使用するため、製品のコアに依存します。

それは私たちの機能のために、Web配信メカニズムとして使用されています。

$ tree apps/web
apps/web
├── application.rb
├── assets
│   ├── favicon.ico
│   ├── images
│   ├── javascripts
│   └── stylesheets
├── config
│   └── routes.rb
├── controllers
├── templates
│   └── application.html.erb
└── views
    └── application_layout.rb

8 directories, 5 files

このコードを簡単に見てみましょう。

ファイルapps/web/application.rbは、Web::Applicationという名前のHanamiアプリケーションを含んでいます。ここで、プロジェクトのこのコンポーネントのすべての設定を構成できます。 apps/web/controllersviewstemplatesなどのディレクトリには、アクションビューテンプレートが含まれます。

JavaScriptやスタイルシートなどのWebアセットは、アプリケーションによって自動的に提供されます。

モノリスファースト

デフォルトのアプリケーションWebは、顧客用のUIインターフェースとして使用できます。 私たちのストーリーのある時点で、管理パネルを使ってユーザーを管理したいと思います。

私たちが導入しようとしている機能のセットは私たちのメインのUI(Web)に属していないことを私たちは知っています。 一方、マイクロサービスアーキテクチャを実装するのは時期尚早です。これは、ユーザーが自分のパスワードをリセットできるようにすることだけを目的としています。

Hanamiは私たちの問題に対する解決策を持っています: 私たちは同じRubyプロセスの中にある新しいアプリを生成することができますが、それは別々のコンポーネントです。

$ bundle exec hanami generate app admin

このコマンドは私たちのプロジェクトのルートから実行しなければなりません。apps/admin下に新しいアプリケーション(Admin::Application)が生成されます。

私たちのプロダクトライフサイクルの後期段階では、これをスタンドアロンコンポーネントに抽出することにしました。 apps/admin下にあるすべてのものを別のリポジトリーに移動して別々にデプロイする必要があるだけです。

プロジェクトの内部構造

lib/apps/についてはすでに検討しましたが、新たに生成されたプロジェクトには説明が必要な部分が他にもあります。

$ tree -L 1
.
├── Gemfile
├── Gemfile.lock
├── README.md
├── Rakefile
├── apps
├── config
├── config.ru
├── db
├── lib
└── spec

簡単に紹介しましょう:

  • GemfileGemfile.lockBundlerの生成物です。
  • README.mdはプロジェクトの設定方法と使用方法を教えてくれます。
  • Rakefileは私たちのプロジェクトのためのRakeタスクを記述しています。
  • config/は重要なファイルconfig/environment.rbが含まれていて、これはプロジェクトのエントリポイントです。 それを要求することによって、私たちは依存関係(Ruby gems)、Hanamiフレームワーク、そして私たちのコードをプリロードします。
  • config.ruはRackサーバーがどのように私たちのアプリケーションを実行しなければならないかを記述するファイルです。
  • db/はデータベースファイルが含まれます(ファイルシステムアダプタやSQLite用) 私たちのプロジェクトがSQLデータベースを使用するとき、それはdb/migrationsdb/schema.sqlも含みます。
  • spec/はユニットテストと受け入れテストが含まれます。