web-dev-qa-db-fra.com

Champs spécifiques de retour de contrôleur de repos de ressort

La meilleure façon de concevoir une API JSON à l'aide de Spring MVC m'a été donnée. Comme nous le savons tous, IO est coûteux et je ne souhaite donc pas que le client effectue plusieurs appels d'API pour obtenir ce dont il a besoin. Cependant, en même temps, je ne veux pas forcément retourner l’évier de la cuisine.

Par exemple, je travaillais sur une API de jeu similaire à IMDB, mais plutôt pour les jeux vidéo.

Si je retournais tout ce qui était connecté à Game, cela ressemblerait à quelque chose comme ça.

/ api/jeu/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"
        }
    ]
}

Cependant, ils n’auront peut-être pas besoin de toutes ces informations, mais ils pourraient le faire. Faire des appels pour tout semble être une mauvaise idée d'I/O et de performance.

J'ai pensé le faire en spécifiant le paramètre include dans les requêtes. 

Maintenant, par exemple, si vous n'avez pas spécifié d'inclusion, tout ce que vous obtiendrez est le suivant.

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

Cependant, si vous souhaitez que toutes les informations dont vos demandes ont l'apparence ressemblent à ceci.

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

De cette façon, le client a la possibilité de spécifier la quantité d'informations qu'il souhaite. Cependant, je ne sais pas trop quel est le meilleur moyen de le mettre en œuvre avec Spring MVC.

Je pense que le contrôleur ressemblerait à quelque chose comme ça.

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?
}

Je ne sais pas comment vous pouvez éventuellement sérialiser l'objet Game. Est-ce seulement possible. Quelle est la meilleure façon d’aborder ceci au printemps MVC?

Pour info, j'utilise Spring Boot, qui inclut Jackson pour la sérialisation. 

14
greyfox

Au lieu de renvoyer un objet Game, vous pouvez le sérialiser en tant que Map<String, Object>, où les clés de mappage représentent les noms d'attributs. Vous pouvez donc ajouter les valeurs à votre carte en fonction du paramètre 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;

}

Par exemple, si vous avez un Map<String, Object> comme ceci:

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

Ce serait sérialisé comme ceci:

{
  "id": 1,
  "title": "Call of Duty Advanced Warfare",
  "publishers": [
    {
        "id": 1,
        "name": "Activision"
    }
  ]
}
11
Marlon Bernardes

Sachant que ma réponse arrive assez tard: je vous recommande de regarder Projections

Ce que vous demandez, ce sont des projections.

Puisque vous parlez de Spring, je voudrais l'essayer: https://docs.spring.io/spring-data/rest/docs/current/reference/html/#projections- extraits

1
yaccob