Spring Bootを使用してRest APIを作成し、Hibernate Validationを使用してリクエスト入力を検証しています。
しかし、他の種類の検証も必要です。たとえば、更新データをチェックする必要がある場合、会社IDが存在しない場合は、カスタム例外をスローします。
この検証は、サービス層またはコントローラー層に配置する必要がありますか?
サービス層:
public Company update(Company entity) {
if (entity.getId() == null || repository.findOne(entity.getId()) == null) {
throw new ResourceNotFoundException("can not update un existence data with id : "
+ entity.getId());
}
return repository.saveAndFlush(entity);
}
コントローラー層:
public HttpEntity<CompanyResource> update(@Valid @RequestBody Company companyRequest) {
Company company = companyService.getById(companyRequest.getId());
Precondition.checkDataFound(company,
"Can't not find data with id : " + companyRequest.getId());
// TODO : extract ignore properties to constant
BeanUtils.copyProperties(companyRequest, company, "createdBy", "createdDate",
"updatedBy", "updatedDate", "version", "markForDelete");
Company updatedCompany = companyService.update(company);
CompanyResource companyResource = companyAssembler.toResource(updatedCompany);
return new ResponseEntity<CompanyResource>(companyResource, HttpStatus.OK);
}
コントローラー層とサービス層の両方が特定のインターフェースを公開します。インターフェイスは、インターフェイスの使用方法に関する規約を定義します。コントラクトは通常、どの引数(およびそのタイプと値)が予期されるか、どの例外がスローされるか、どの副作用が発生するかなどを意味します。
これで、検証は基本的にコントローラーのupdate()メソッドとサービスレイヤーのupdate()メソッドのコントラクトの適用になります。どちらも非常によく似た契約を結んでいるため、検証(契約の実施)も一般的になるのは当然です。
これを行う1つの可能な方法は、このコントラクトの検証を分離し、両方のレイヤーで呼び出させることです。これは通常、最も明確です。各クラス/メソッドは独自の規約を適用しますが、パフォーマンス(データベースへのアクセス)またはその他の理由により、多くの場合非実用的です。
他の可能性は、サービス層コントラクトで検証が失敗した場合の動作を明示的に定義しながら、この検証をサービス層に委任することです。サービスレイヤーは通常、いくつかの一般的な検証エラー(または例外をスロー)を返し、コントローラーレイヤーはエラーに対して特定の方法で反応する必要があります。
この設計では、サービスレイヤーのビジネスロジック(非常に汎用的である必要があります)とコントローラー(統合ロジックを処理する)の間の結合が多すぎるという危険があります。
とにかく、これはかなり物議を醸す質問であり、100人が100件の回答で答えます。これは私の見解です。
入力はサービス層でチェックする必要があります。
「IDが見つかりません」は論理的なエラー状態です。したがって、コントローラーレイヤーからスローする必要があります。
これも、レイヤー/デザインに依存します。
サービスレイヤーが実行することと、コントローラーレイヤーに期待されること.
Hibernate検証は、データのintegrityに対するチェックです。 bbddからのRuntimeExceptionを回避するため。それらはConstrainsで制御する必要がある検証とほとんど同じです。ビジネスレイヤーのみフィードである必要があります永続性レイヤーなので、ビジネスレイヤーからのデータの正当性を信頼するかどうかはあなた次第です
DAOには検証を入れません。上位層からの有効なデータを期待しています。エラーが発生した場合は、bbddにその内容を認識する責任を委任します。
次に、ビジネス層での検証が行われます。すべてのビジネス検証は、データのコヒーレンスの維持に焦点を当てており、-その整合性ではありません.
最後に、コントロールレイヤーで以前の検証を行います。そのような層にのみ関連するもの。
どの検証がビジネス層で提供されることが意図されているかがすぐにわかります。最も一般的なのは、IDコントロールです。これは、両方の層で簡単に実装できます。多くのコントローラーまたはクライアントがビジネスレイヤーを消費することが予想される場合は、どこでも同じ検証を繰り返すのではなく、ビジネスレイヤーに配置する優れた候補になります。
コントローラーには、他のファサードでは再現できない独自のルールと条件がある場合があります。次に、そのようなコントローラーに入れる候補です。
何を検証するのか、何に関係なく全員に適用したいのかを考えてください。または、それがコンテキスト検証である場合(「特定のコントロール/ビューファサードでのみ発生する何かを検証しています」。
Javaショップでは、Webウィジェットの検証を3つの別々の操作に意図的に分割しています。
レイヤー1が失敗した場合、2または3はチェックされません。同様に、1が成功し、2が失敗した場合、3は実行されません。これにより、偽のエラーメッセージが生成されなくなります。
ウィジェットのコンテンツではなく、REST呼び出しの値について質問していますが、同じ原則が適用されます。