弹簧静止控制器返回特定字段

我一直在思考使用Spring MVC设计JSON API的最佳方法。 我们都知道IO很昂贵,因此我不想让客户端进行多次API调用以获得他们需要的东西。 但与此同时,我不一定要回厨房水槽。

作为一个例子,我正在开发类似于IMDB的游戏API,而不是用于video游戏。

如果我返回与游戏相关的所有内容,它将看起来像这样。

/ 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中处理此问题的最佳方法是什么?

仅供参考,我正在使用Spring Boot,其中包括Jackson进行序列化。

您可以将其序列化为Map ,而不是返回Game对象,其中map键表示属性名称。 因此,您可以根据include参数将值添加到地图中。

 @ResponseBody public Map 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 gameMap = service.convertGameToMap(game, include); return gameMap; } 

例如,如果你有一个Map就像这样:

 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" } ] }