Przeszukując moją głowę, najlepiej jest zaprojektować interfejs API JSON przy użyciu Spring MVC. Jak wszyscy wiemy, IO jest drogi, a więc nie chcę, aby klient wykonywał kilka wywołań API, aby uzyskać to, czego potrzebuje. Jednak w tym samym czasie niekoniecznie chcę zwrócić zlew kuchenny.Sterownik spoczynku sprężyny Zwróć określone pola
Jako przykład pracowałem nad API gry podobnym do IMDB, ale zamiast gier wideo.
Gdybym zwrócił wszystko, co jest podłączone do Gry, wyglądałoby to tak.
/api/gra/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"
}
]
}
Jednak nie mogą one potrzebować wszystkich tych informacji, ale potem znowu oni mogą. Robienie wezwań do wszystkiego wydaje się złym pomysłem z I/O i wydajności.
Zastanowiłem się nad zrobieniem tego poprzez podanie parametru include w żądaniach.
Teraz, na przykład, jeśli nie podano żadnych załączników, wszystko, co można uzyskać, jest następujące.
{
"id": 1,
"title": "Call of Duty Advanced Warfare",
"release_date": "2014-11-24"
}
Jednak chcesz, aby wszystkie informacje, które twoja prośba wyglądałaby tak.
/api/game/1?include=publishers,developers,platforms,reviews,esrbRating
W ten sposób klient ma możliwość określenia, ile informacji chce. Jednak jestem w pewnym sensie beznadziejny najlepszym sposobem na wdrożenie tego przy użyciu Spring MVC.
Myślę, że kontroler wyglądałby tak.
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?
}
Nie jestem pewien, w jaki sposób opcjonalnie serializuje się obiekt Game. Czy to możliwe? Jaki jest najlepszy sposób podejścia do tego w Spring MVC?
FYI, używam Spring Boot, który obejmuje Jackson do serializacji.
Wydaje się zrobić trochę przedwczesne optymalizacji tutaj. Czy w twojej jednostce jest naprawdę tyle danych, że trzeba je filtrować na żądanie klienta? Na podstawie tego, co pokazałeś, nadmiernie skomplikujesz zarówno klienta, jak i serwer, i przerwiesz RESTfullness twojej usługi, nie oszczędzając przy tym wiele IO. –
W przypadku mojego przykładu, zgadzam się, że to zdecydowanie przesada. Powiedzmy tylko, na przykład, że zwracanie obiektu Game skutkuje ogromnym obiektem JSON, czy uważasz, że lepiej byłoby zrobić/game/1/reviews zamiast/game/1? Include = reviews? – greyfox
jeśli obiekt jest ogromny, to chciałbym poprosić o kolekcje z oddzielnych podprojektów, ponieważ obciążenie związane z wydaniem kilku wniosków byłoby niewielkie w stosunku do całkowitej ilości przesłanych danych. –