こんにちは。
エンジニアリングマネージャー楽しいよ!
というを広めたいと思っている @dskst9 です。
この記事は ドメイン駆動設計 #1 Advent Calendar 2018 - Qiita の13日目の記事で、DDDの境界づけられたコンテキストとAPIについて書いています。
11 日目 は @nrslib さんの「アプリケーションサービスの凝集度を高めたい」でした。
さいしょに
境界づけられたコンテキストを意識することで、より疎結合で柔軟な API を設計できるというお話です。
まずは、3行でまとめます。
- API は使う側と使われる側とで、別のコンテキストである
- コンテキストを意識しないと、 API からドメイン知識が漏れる
- それは時に、ドメインモデル貧血症を起こし感染する
境界づけられたコンテキストとは
境界づけられたコンテキストとは、モデリングによりモデルが適用されるコンテキストを明示的に定義した境界と言えます。
モデルとは何?というのを掘り下げていけばさらに深くなってしまい、それだけで一記事になってしまいますので参考記事をリンクいたします。
境界づけられたコンテキストを意識して API を見てみる
我々が何気なく使ってる/作っている API にも、境界づけられたコンテキストが存在しています。
API 1つ1つがモデルであり、そこにはドメインがあると考えることができます。
そう考えると、 API とはモデルのインターフェースだと言えます。
そして、コンテキストのやり取りをインターフェースを通すことで、境界づけられたコンテキストを作ることができるのです。
マイクロサービスはまさにそれで、1つのサービスは境界づけられたコンテキストに収めるという設計を行います。マイクロサービスとDDDは4日目の記事にも書かれていますのでご参考ください。
s-edword.hatenablog.com
なぜコンテキストを意識するのか
さて、なぜコンテキストを意識する必要があるのでしょうか。
先の話の通り、 API のパラメーターはコンテキストの会話であり、ここにドメイン知識が漏れるとドメイン知識が境界を越えてしまうということがわかります。
わかりやすく、具体的な例で考えてみましょう。
今回は Wikipedia の API を例に上げて考えてみます。
先に断っておきますが、この API が良い悪いとかではなく、 API のドメイン知識とは何かという説明のために引用いたします。
実際の API で考えてみる
Wikipedia のページ情報を取得する API:Info という API を参考に考えていきます。
この API で取得できる記事情報の中には、ページ保護の情報も含まれており、レスポンスは以下のように定義されています。
inprop=protection
Protection results include:
- protection:
The list of applied page protections.- type: The type of restriction (see restrictiontypes entry).
- level: The restriction level.
- expiry: When the page protection expires. Can be an ISO date or the word "infinity".
- source: For cascading protection, the source page causing the given page to be protected.
- restrictiontypes:
Allowed restriction types for the page.
This will normally be a subset of $wgRestrictionTypes, but can be customized by extensions to include other values via the TitleGetRestrictionTypes hook.
レスポンスに含まれる type や level といった値がどんな意味を持っているか注目してみましょう。
- Manual:$wgRestrictionTypes - MediaWiki
- 制限することができるアクション
- Default value:
array( 'create', 'edit', 'move', 'upload' )
- Manual:$wgRestrictionLevels - MediaWiki
- 各制限タイプに対して選択できる権限のリスト
- Default value:
array( '', 'autoconfirmed', 'sysop' )
API のレスポンスとして、 create, edit などの制限することができるアクションや、 autoconfirmed や sysop という権限のリストが見えてきます。さらに、sysops という値には下記のような機能もあるようです。
sysopsよりも高いレベル、つまりsysop編集からの保護を設定した場合、sysopsは保護レベルのページを与えることも、削除することもできません。
何やらドメイン知識なようなものが出てきました。
そのドメイン知識は本当に公開すべきなのか
さて、ここで考えるべきことがあります。
本当にそのドメイン知識の公開が必要なのか?
ということです。
先の例の通り、 Wikipedia API:Info からは権限のリストが持つドメイン知識を取得できます。
取得できるということは、使う側もこのドメイン知識を意識する必要があります。
本来公開しなくていいドメイン知識を公開すると、境界づけられたコンテキストからドメイン知識が漏れ出すことになります。
さらに、 API が DB の値をそのまま返すなんてことをすると、ドメインモデル貧血症が起きて、使う側も感染してしまいます。
アンチパターン
- API のリクエストにドメイン知識を入れてしまう
- API のレスンポンスでなんでもかんでも返却する
- DB の値をそのまま返却する
おわりに
ドメイン知識を何も公開しない API というものは存在しません。
我々が意識するべきは、 API にも境界づけられたコンテキストがあり、ドメイン知識をもっているということ。意志を持って、ドメイン知識を公開していく必要があるということです。
ドメイン駆動設計 #1 Advent Calendar 2018 - Qiita もいよいよ折り返しです!
明日14日目は @pospome さんの DDDとコードとしての正しさ になります!