22

私は、Spring MVC を使用して JSON API を設計するための最良の方法を頭の中を調べてきました。IO が高価であることは誰もが知っているので、必要なものを取得するためにクライアントに複数の API 呼び出しを行わせたくありません。しかし同時に、私は必ずしも台所の流しを返したいとは思っていません。

例として、私は IMDB に似たゲーム API に取り組んでいましたが、代わりにビデオ ゲーム用でした。

Game に接続されているものをすべて戻すと、次のようになります。

/api/ゲーム/1

{
    "id": 1,
    "title": "Call of Duty Advanced Warfare",
    "release_date": "2014-11-24",
    "publishers": [
        {
            "id": 1,
            "name": "Activision"
        }
    ],
    "developers": [
        {
            "id": 1,
            "name": "Sledge Hammer"
        }
    ],
    "platforms": [
        {
            "id": 1,
            "name": "Xbox One",
            "manufactorer": "Microsoft",
            "release_date": "2013-11-11"
        },
        {
            "id": 2,
            "name": "Playstation 4",
            "manufactorer": "Sony",
            "release_date": "2013-11-18"
        },
        {
            "id": 3,
            "name": "Xbox 360",
            "manufactorer": "Microsoft",
            "release_date": "2005-11-12"
        }
    ],
    "esrbRating": {
        "id": 1,
        "code": "T",
        "name": "Teen",
        "description": "Content is generally suitable for ages 13 and up. May contain violence, suggestive themes, crude humor, minimal blood, simulated gambling and/or infrequent use of strong language."
    },
    "reviews": [
        {
            "id": 1,
            "user_id": 111,
            "rating": 4.5,
            "description": "This game is awesome"
        }
    ]
}

ただし、これらすべての情報が必要なわけではありませんが、必要になる場合もあります。I/O とパフォーマンスの観点から、すべてを呼び出すことは悪い考えのように思えます。

リクエストに include パラメータを指定することでそれを行うことを考えました。

たとえば、インクルードを指定しなかった場合、返されるのは次のとおりです。

{
    "id": 1,
    "title": "Call of Duty Advanced Warfare",
    "release_date": "2014-11-24"
}

ただし、リクエストするすべての情報が必要な場合は、次のようになります。

/api/game/1?include=publishers,developers,platforms,reviews,esrbRating

このようにして、クライアントは必要な情報量を指定できます。ただし、Spring MVC を使用してこれを実装する最良の方法については、ちょっと迷っています。

コントローラーはこんな感じになると思います。

public @ResponseBody Game getGame(@PathVariable("id") long id, 
    @RequestParam(value = "include", required = false) String include)) {

        // check which include params are present

        // then someone do the filtering?
}

オプションで Game オブジェクトをシリアル化する方法がわかりません。これは可能ですか?Spring MVC でこれにアプローチする最良の方法は何ですか?

参考までに、シリアル化にはJacksonを含むSpring Bootを使用しています。

4

4 に答える 4

19

オブジェクトを返す代わりに、マップ キーが属性名を表すGameとしてシリアル化できます。Map<String, Object>したがって、パラメーターに基づいてマップに値を追加できincludeます。

@ResponseBody
public Map<String, Object> getGame(@PathVariable("id") long id, String include) {

    Game game = service.loadGame(id);
    // check the `include` parameter and create a map containing only the required attributes
    Map<String, Object> gameMap = service.convertGameToMap(game, include);

    return gameMap;

}

例として、次のような場合Map<String, Object>

gameMap.put("id", game.getId());
gameMap.put("title", game.getTitle());
gameMap.put("publishers", game.getPublishers());

次のようにシリアル化されます。

{
  "id": 1,
  "title": "Call of Duty Advanced Warfare",
  "publishers": [
    {
        "id": 1,
        "name": "Activision"
    }
  ]
}
于 2015-05-31T15:20:47.713 に答える
0

解決策 1: API 応答 (モデル内) に含めたくない変数に @JsonIgnore を追加します。

@JsonIgnore
    private Set<Student> students;

解決策 2: 含めたくない変数のゲッターを削除します。

他の場所でそれらが必要な場合は、ゲッターに別の形式を使用して、Spring が認識しないようにします。

于 2021-08-28T08:25:49.617 に答える