Soeunパーク:
リクエストパラメータは相互に排他的であるとき@Controller法にAPIを設計するためのより良い方法は何ですか?
レッツは、リクエストパラメータに一致するユーザーのリストを提供するAPIがあることを言います。
コードは次のとおりです。
public ResponseEntity getList(@RequestParam(required = false) Integer userId,
@RequestParam(required = false) User.Type userType,
@RequestParam(required = false) Integer age) {
List<User> userList = null;
if (userId != null) {
//logic
userList = getUserByUserId()
} else if (userType != null) {
//logic
userList = getUserByType()
} else if (age != null) {
//logic
userList = getListByAge()
} else {
userList = getAllWithoutCondition();
}
return ResponseEntity.ok(userList);
}
ここでのポイントは以下のとおりです。
ユーザーは、複数のリクエストパラメータを指定して照会することはできません。一つだけリクエストパラメータまたは有効であるパラメータなしの要求(の一つだけuserId
、age
あるいはtype
要求に存在している必要があります)。
私はこのような状況のためのAPIを設計するためのより良い方法が何であるかわかりません。あなたは私にいくつかのアドバイスを与えることはできますか?
アンドリューTobilko:
私はコメントでみんなが提案したアプローチが好き:
@RequestMapping(value = "...", params = {"!userType", "!userAge"})
public ResponseEntity<List<User>> getListByUserId(@RequestParam Integer userId) { ... }
// similarly, define two more
あなたは、各エンドポイントの制限の管理を開始するまでは、堅牢かつ実現可能になります。それは退屈で維持するのは難しい見えます。さらに、私は何のparamsを取らないエンドポイントがどのように反応するかわかりません。それが呼び出さなるだろうか、他の方法により陰にできますか?
各エンドポイントのための要件-代わりに制限を書き込むので、私は条件を導入することをお勧めします。それは可能性がありMap<String, Function<String, List<User>>>
、次の形式で:
<param name> -> <action to get a list>
私はまた、あなたが単一にすべての着信リクエストパラメータを収集助言Map<String, String>
サイズによって、それを検証します。
public class Controller {
private Map<String, Function<String, List<User>>> handlers = new HashMap<>();
{
handlers.put("userId", id -> getUsersById(Integer.valueOf(id)));
handlers.put("userType", type -> getUsersByType(User.Type.valueOf(type)));
handlers.put("userAge", age -> getUsersByAge(Integer.valueOf(age)));
}
@RequestMapping("...")
public ResponseEntity<List<User>> getList(@RequestParam Map<String, String> params) {
if (params.size() > 1) {
return ResponseEntity.unprocessableEntity().build();
}
if (params.size() == 0) {
return ResponseEntity.ok(getAllWithoutCondition());
}
Map.Entry<String, String> paramEntry = params.entrySet().iterator().next();
return ResponseEntity.ok(handlers.get(paramEntry.getKey()).apply(paramEntry.getValue()));
}
private List<User> getAllWithoutCondition() { ... }
private List<User> getUsersById(Integer id) { ... }
private List<User> getUsersByType(User.Type type) { ... }
private List<User> getUsersByAge(Integer age) { ... }
}