Say I have a team
object, that has a name
property, a city
property and a players
property, where the players
property is a an array of possibly many players. This is represented in an SQL database with a teams
table and a players
table, where each player has a name
and a team_id
.
Building a RESTful api based on this simple data-structure, I'm in doubt if there is a clear rule regarding, if the return object should/could include a list of players, when hitting /teams/:id
?
I have a view, that needs to show a team, and its players with their names, so:
1: Should /teams/:id
join the two tables behind the scene and return the full team
object, with a players property, that is an array of names and id's?
2: Should /teams/:id
join the two tables behind the scene and return the team
object, with a players property, that is an array of just id's that will then have to be queried one-by-one to /players/:id
?
3: Should two calls be made, one to /teams/:id
and one to /teams/:id/players
?
4: Should a query string be used like this /teams/:id?fields=name,city,players
?
If either 2 or 3 is the way to go, how would one approach the situation, where a team could also have multiple cities, resulting in another cities
table in the DB to keep it normalized? Should a new endpoint then be created at /teams/:id/cities
.
When creating RESTful API's, is it the normalized datastructure in the DB that dictates the endpoints in the API?
What is a Resource? REST architecture treats every content as a resource. These resources can be Text Files, Html Pages, Images, Videos or Dynamic Business Data. REST Server simply provides access to resources and REST client accesses and modifies the resources. Here each resource is identified by URIs/ Global IDs.
POST method is call when you have to add a child resource under resources collection. RFC-2616 depicts that the PUT method sends a request for an enclosed entity stored in the supplied request URI. This method requests the server to accept the entity which is enclosed in the request. PUT method answer can be cached.
We can identify a single “customer” resource using the URN “/customers/{customerId}”. A resource may “contain” sub-collection resources also. For example, sub-collection resource “accounts” of a particular “customer” can be identified using the URN “/customers/{customerId}/accounts” (in a banking domain).
This Account resource and every other JSON resource will always have an href property, which is the fully qualified canonical URL where that resource resides. Whenever you see an href property, you know you can access that resource by executing a GET request to the resource's URL.
Usually with a RESTful API, it is best that the use-cases dictate the endpoints of the API, not necessarily the data structure.
If you sometimes need just the teams, sometimes need just the players of a team, and sometimes need both together, I would have 3 distinct calls, probably something like /teams/:id
, /players/:teamid
and player-teams/:teamid
(or something similar).
The reason you want to do it this way is because it minimizes the number of HTTP requests that need to be made for any given page. Of all of the typical performance issues, an inflated number of HTTP requests is usually one of the most common performance hits, and usually one of the easiest to avoid.
That being said, you also don't want to go so crazy that you create an over-inflated API. Think through the typical use cases and make calls for those. Don't just implement every possible combination you can think of just for the sake of it. Remember You Aren't Gonna Need It.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With