相互に排他的なリクエストパラメータのためのAPIを設計するためのより良い方法は何ですか?

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);
}

ここでのポイントは以下のとおりです。

ユーザーは、複数のリクエストパラメータを指定して照会することはできません。一つだけリクエストパラメータまたは有効であるパラメータなしの要求(の一つだけuserIdageあるいは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) { ... }

}

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=171332&siteId=1