Montag, Januar 27, 2020

Spring Rest-Controller Bestimmte Felder

Ich habe gehen durch meinen Kopf, der beste Weg, um design eine JSON-API mit Spring MVC. Wie wir alle wissen, IO ist teuer, und so will ich nicht zu machen, kann der client mehrere API-Aufrufe zu bekommen, was Sie brauchen. Aber zur gleichen Zeit ich don ‚ T unbedingt wollen, um die Rückkehr der Spüle.

Als Beispiel war ich arbeiten an einer game-API ähnlich wie IMDB, aber für video-Spiele statt.

Wenn ich wieder alles verbunden mit Spiel, würde es so Aussehen.

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

Jedoch können Sie nicht brauchen, all diese Informationen, aber dann wieder Sie sein könnten. Telefonieren für alles, was scheint wie eine schlechte Idee von der I/O und Leistung.

Dachte ich, es tun sich durch die Angabe von include-parameter in den Anforderungen.

Nun zum Beispiel, wenn Sie nicht angeben, keine includes alles, was Sie bekommen würde zurück, ist die folgende.

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

Jedoch wollen Sie alle die Informationen, die Ihr Anfragen würde in etwa so Aussehen.

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

Diese Weise hat der Kunde die Möglichkeit zu bestimmen, wie viel Informationen, die Sie wollen. Allerdings bin ich irgendwie an einem Verlust der beste Weg, um dies zu implementieren, mit Spring MVC.

Ich denke, der controller würde in etwa so Aussehen.

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

Ich bin mir nicht sicher, wie würden Sie Optional serialisieren, die das Spiel-Objekt. Ist dies auch möglich. Was ist der beste Weg, um diesen Ansatz in Spring MVC?

Zur info, ich bin mit Spring Boot, die beinhaltet Jackson für die Serialisierung.

  • Scheint, wie Sie einige der vorzeitige Optimierung hier. Gibt es wirklich so viele Daten in die Entität, die Sie brauchen, um es zu filtern, die auf Wunsch des Kunden? Basierend auf dem, was Sie gezeigt haben, Sie werden übermäßig erschweren client und server und brechen die RESTfullness von Ihrem service, während nicht speichern, viel IO.
  • In dem Fall von meinem Beispiel, ich Stimme zu, das ist definitiv übertrieben. Können nur sagen, dass zum Beispiel sake, obwohl, dass gibt dem Spiel-Objekt ergeben würde, in einer riesigen JSON-Objekt, sagen Sie, dass es besser wäre zu tun /Spiel/1/Bewertungen statt /game/1?include=Bewertungen?
  • wenn das Objekt ist riesig, dann würde ich ersuchen, die Sammlungen trennen subresourses, da der Aufwand der Ausstellung mehrere Anfragen wäre die kleine sowieso im Verhältnis zum gesamten Volumen der übertragenen Daten.
  • stackoverflow.com/questions/23101260/…
InformationsquelleAutor greyfox | 2015-05-31

2 Kommentare

  1. 12

    Anstatt eines Game Objekt ist, könnte es zu serialisieren als Map<String, Object>, wo die Karte Schlüssel stellen die Namen der attribute. So können Sie die Werte hinzufügen, um Ihre anzeigen auf der Grundlage der include parameter.

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

    Als ein Beispiel, wenn Sie eine Map<String, Object> wie diese:

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

    Wäre es serialisiert werden, wie diese:

    {
      "id": 1,
      "title": "Call of Duty Advanced Warfare",
      "publishers": [
        {
            "id": 1,
            "name": "Activision"
        }
      ]
    }
    • Sie tun dies mit einem benutzerdefinierten Dienst klingt nicht wie eine gute Idee zu mir, gibt es eine „Feder“ Weg, dies zu tun?
    • Sie könnte auch auf die Suche nach how to serialise Felder, die basierend auf Ihren Namen (mit Jackson) oder so etwas wie GraphQL. Other than, die ich bin mir nicht sicher, ob es eine „Feder“ Weg, um das gleiche Ergebnis zu erzielen.
    • Wie können wir konvertieren Klasse Spiel Zuordnen?

Kostenlose Online-Tests