まず第一に、それは概念を離れて分離する価値があります。あなたにはドメインがあり、API層があります。レイヤーを作成した後、API層はドメインの上に位置する必要があります。ドメインはAPIの存在を完全に意識する必要がありません。
src/Acme/Api/
src/Acme/Core/
APIのすべてがHTTPレベルの通信を処理します。これは、次のようなものです。ルーティング、要求&レスポンスマッピング、ステータスコードなど
コアのすべてがビジネス関連の操作を処理します。 CQRSスタイルのアプローチに続いて、あなたのようなもので終わることができます:
src/Acme/Api/Controller
src/Acme/Api/DTO/Request/
src/Acme/Api/DTO/Response/
src/Core/Domain/
src/Core/Command/
src/Core/CommandHandler/
src/Core/Infrastructure/
src/Core/ReadModel/
しかし、実際に、レイアウト&命名が柔軟になるだろう、それは多少あなたが適用しているものの建築パターンにより異なります。 DDDコンテキストでは、集約、モデル、値オブジェクト&のリポジトリを共通の名前空間(Domain
)の下に置くことが重要です。
は、個々の問題に対処するには、次のどのようなクラス
をバージョン管理すべきですか? (コントローラ、モデル、ビューなど)
私の考えでは、バージョンモデルには意味がありません。モデルは常にビジネスの最新の表現でなければならず、より古いのルールを維持することは不要と思われる。
バージョン管理はどのように処理するかはあなた次第です。それを完全なAPI(パス+要求/応答ペイロード)にバージョンアップする方法として扱うこともできますし、要求/応答ペイロードだけをバージョンすることもできます。 APIを完全にバージョン管理することはおそらく最も柔軟ですが、そのような劇的な変更を行うことは比較的まれです。 Accept
/Content-Type
ヘッダーを利用して、要求レベルごとにバージョン管理することを検討してください。両方の組み合わせを使用することもできます(URLのメジャーバージョンバンプを使用してパスを再定義し、特にContent-Type
のバージョンを強制します)。
さらに理論的には、要求/応答のペイロードを定義するJSONスキーマをバージョンアップすることができます。
GET /1.0/user/317684e2-3704-11e6-8172-b0bea8105888/payment/2caad76e-3705-11e6-8172-b0bea8105888
Accept: application/vnd+acme+json; schema=payment.out.v1.json
HTTP/1.1 200 OK
Content-Type: application/vnd+acme+json; schema=payment.out.v1.json; charset=UTF-8
{
"payee": "Bob Dylan",
// snip
}
```
レスポンス・ペイロードに非後方互換性の変化を紹介したい場合は、あなたは、クライアントが支払いのために「V2」JSON Schemaに対して要求できるようにすることができます:例として
GET /1.0/user/317684e2-3704-11e6-8172-b0bea8105888/payment/2caad76e-3705-11e6-8172-b0bea8105888
Accept: application/vnd+acme+json; schema=payment.out.v2.json
HTTP/1.1 200 OK
Content-Type: application/vnd+acme+json; schema=payment.out.v2.json; charset=UTF-8
{
"payee": {
"forename": "Bob",
"surname": "Dylan"
},
// snip
}
メジャーAPIバージョンは変更されていませんが、応答ペイロードは異なります。古いバージョンを廃止するか、または主要なAPIバージョンをバンプして、ペイロードレベルで最小値を設定することができます。
Content-Type
ヘッダーを利用することで、リクエストボディに同じ手法を適用できます。
ドメインドリブンデザインをバンドルしたときにどうしましたか? (完全なバンドルディレクトリをバージョンアップするか、バンドルの中に入れる?) バージョン管理はどうすればよいですか?
恐らくすでに答えられていますが、Symfonyスタイルのバンドルについて考えることはできません。 Core
、またはそれを呼びたいものは、それに固有のSymfony/Silexを何も持たないはずです。 Infrastructure
では、おそらくDoctrineを使用してRepository
インターフェースの実装をしているかもしれませんが、それはsymfony/Silexをフレームワークとして使っているのではなく、Doctrineをライブラリとして活用しています。理論的には、全く違うフレームワークのためにAPIレイヤーを交換してCore
に変更することができます。
ただし、避けられないものがいくつかあります:依存性注入&設定。 symfonyではこれまでこれを解決するためにCoreBundle
を作成しました。これはCore
の外にあります。
ちなみに、このようなプロジェクト内では1つの限定されたコンテキストのみを包含するのが賢明かもしれませんので、もっと分類することを心配しないでください。少ないコードの重複で
、
それは重複が発生することは避けられないですが、あなたは動作を定義するオブジェクトをバージョン管理されないので、これは唯一、あなたのDTOの場合でなければならないとき(あなたのモデル) 。 DTOでの複製は実際には大きな問題ではありません。失われたものよりも明快さが得られれば、バージョンごとにクラスを定義するだけです。ツールはコピーされたコードをコードに伝えるかもしれませんが、そのようなコンテキストを理解できるツールではありません。
古いバージョンを容易に除去
あなたが別々のDTOを定義する場合、そのような作業は簡単でなければなりません。 DTOを削除し、JSONスキーマを削除します。これで、APIは指定された古いバージョンのリクエストを拒否します。
少ない副作用、あなたのAPI層で/レスポンスオブジェクトを要求するためにマッピングされている場合はバージョン
の間で共有されますバグ修正何かが、それは、変更によって影響を受けることができ、あなたのマッピングコードだ場合モデルで。 API契約テスト、インプロセスコンポーネントテスト、単体テストなどのテストでは、モデルの変更によってAPIのすべてのバージョンが異なる動作をしないことを確認する必要があります。