RESTful APIを開発しています。DAOを使用してサービスにデータを提供しています。
サービスであろうとDAO契約であろうと、特定の責任をどこに置くべきかを判断するのに苦労しています。または、単に責任を負うのではなく、各コンポーネントが何をすべきか、またはすべきでないかを決定するだけです。
APIのCRUD部分のシナリオでは、たとえば作成機能に焦点を当てましょう。リソースが作成された(または作成されなかった)場合、サービスからどのような応答が期待されますか?作成されたシリアル化されたオブジェクト?真/偽のメッセージ?何もない?これは私が意味することです:
_// Option 1
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Resource createResource(Resource resource) {
dao.create(resource);
return resource;
}
// Option 2
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void createResource(Resource resource) {
dao.create(resource);
}
// Option 3
@POST
@Consumes(MediaType.APPLICATION_JSON)
public String createResource(Resource resource) {
return dao.create(resource); // or even a custom message?
}
_
しかし、さらに進んでください。 DAOは何を返す必要がありますか? dao.create()
メソッドはブール値を返す必要がありますか?作成されたオブジェクトを返すか、作成できなかった場合はnull
を返す必要がありますか?または単にvoid
になりますか?
_// Option 1
public Resource create(Resource resource) {
return resources.add(resource) ? resource : null;
}
// Option 2
public void create(Resource resource) {
resources.add(resource);
}
// Option 3
public boolean create(Resource resource) {
return resources.add(resource);
}
_
RESTfulサービスから通常何が期待されるかを理解し、「誰が何をすべきか」の最良の区分を決定したいだけです。
それとも私はこれを考えすぎており、どの実装も意味があり、他の実装と同じくらい優れていますか?
DAOが新しく作成されたリソースを返すことは一般的です。特に、ORMが舞台裏で使用されている場合、いくつかの理由が考えられます。
返されたオブジェクトには、代理の主キーセットが含まれていることがよくありますが、より重要なのは-
返されたオブジェクトはデータベースセッションにアタッチされることが多いため、セッションが閉じられると、それ以降の変更が自動的にコミットされる可能性があります。
あなたの例では、これはそれほど重要ではありませんが、より複雑なビジネスロジックが関係する場合に便利です。含めるオプションはこのパターンに従いません。
RESTエンドポイントについては、Ericに同意しますが、作成が成功したら、ステータスコード201で応答し、Locationヘッダーを新しいリソースの正規URLに設定し、シリアル化して、リソース自体がレスポンスボディに含まれます。オプション1はこれに最も近くなります。
パフォーマンス上の理由から、リソースを作成するHTTP API呼び出しがそのリソースの表現をクライアントに返すのは素晴らしいことです。それ以外の場合は、リソースを取得するために個別のGET呼び出しを行う必要があります。
リクエストの成功または失敗は、レスポンスのステータスコードによって伝えられます。成功の場合は2xxコード、エラーの場合は4xxおよび5xxコードです。成功または失敗を示すメッセージまたはブール値を送信する必要はありません*が、失敗の場合は、何が問題かを示すメッセージを送信する必要があります。
[*]一部のクライアントは応答にその情報を含めると便利な場合があるため、とにかく好きな人もいます。これはステータスコードに追加されるものであり、代わりではありません。