13

I'm working to design a REST API to be consumed by a React SPA.

The client-side of the SPA queries data about a relationship between two entities: Team and Player where Teams have many Players and Players can only belong to one Team.

I want to query all the Teams and then get all the Players for each team (which you could imagine would be a fairly typical use-case for these resources in a SPA.)

I can see 3 main approaches:

  1. Expand the /teams endpoint to have some param ?expand=player or something similar that includes a player array for each team. The data comes back nice to be consumed by the react application but now the REST API endpoint is becoming more complex and less compliant to the single-responsibility principle.

  2. Query /teams to get the IDs of all teams and then query each team /team/:id/players. But this will increase the # of requests to the backend, although it will separate responsibilities nicer and make things more explicit.

  3. Query /teams to get the IDs of all teams and then query /players/:ids where :ids is the IDs of all the teams. This is also quite explicit but could result in a huge URL and isn't a nice and tidy.

What approach is generally regarded as the best? Of course all of them have trade-offs, but perhaps I am overlooking some trade-offs?

4
  • 1
    COuldn't your title be miselading ? Because if one player belongs only to one team, it's a one to many relation and not many to many.
    – Christophe
    Aug 26, 2018 at 21:51
  • @Christophe thanks, I modified it to the more general case of resource relationships in general. Aug 26, 2018 at 22:52
  • Are you typically / always going to be getting the team + player data?
    – Andy
    Aug 27, 2018 at 22:36
  • This is also quite explicit but could result in a huge URL and isn't nice and tidy. Oh dear, looking for aesthetics in URL? Have you ever seen Google's URLs?
    – Laiv
    Jun 11, 2020 at 12:39

3 Answers 3

7

I want to query all the Teams and then get all the Players for each team

How would you do it as a web site?

If you weren't trying to create a "REST API", you would probably just create a single html page that would have all the data you want; one fetch from the client, and tada, you are done.

If there was a lot of data, then you might deliver it as multiple pages, linked together.

But either way, it would just be a big block of HTML, that clients could pull down by getting the link.

Does the spelling of the link matter? Not to the client, they are just fetching it. The server needs to be able to match the correct HTML to the link, but the server can do that any way it likes.

So if you want to put that page in your /teams hierarchy, or in your /players hierarchy, or in a completely separate /league, /reports or /views hierarchy, those are all perfectly fine choices.

The fact that the representation you are using is a JSON document, rather than HTML, or XML, or whatever, doesn't change that.

Part of the point of REST is that its not important that the client be able to disassemble your URI and from it deduce your database schema.

What the server is actually doing to find the correct representation is an implementation detail that we conceal behind the uniform interface.

3
  • this is by the BEST and most simplified explanation of a RESTful api I have ever seen. I've been trying to understand how RESTful endpoints are structured in order for me to retrieve data as the UI would need it (at the request of BE team) and I didn't understand what to do. While this post may not specifically 'choose' a choice from the OP lists, it gives understanding of what a RESTful API actually is -- especially for a beginner like me. This helps me TONS. Thank you. Thank you. Thank you. +100
    – Chris22
    Apr 10, 2019 at 18:05
  • 4
    this doesn't really answer the question in my opinion
    – steviesh
    Jun 6, 2020 at 18:54
  • Yes, he does So if you want to put that page in your /teams hierarchy, or in your /players hierarchy, or in a completely separate /league, /reports or /views hierarchy, those are all perfectly fine choices.
    – Laiv
    Jun 11, 2020 at 12:34
2

It depends on the functions of the clients of the application, amount of data and performance of processing requests.

If all players of all teams are always required include the collection of Players in each Team resource that is returned.

If the details of the players are not always required each team can include the collection of all player ID's and retrieve details as needed.

If players are not required for all functions of the application where teams are processed get players as needed.

But then the URL is not really important. For a REST API it's more important to define how clients find out which URL's exist to perform actions on resources, depending on their MIME type. This is the HATEOAS (Hypermedia As The Engine Of Application State) part of REST.

3
  • 1
    Your contribution suggests that you have good ideas on REST APIs. However, after having read it several times, I have the feeling that if could be too general and I'm still not sure if it really answers the question. Could you elaborate a little bit and refer explicitly to the different approaches of the questions in order to avoid misunderstandings ?
    – Christophe
    Aug 26, 2018 at 22:23
  • @Christophe The question is general though too; should you return links or the actual data? This answer is saying it depends on what you typically expect clients to need, which IMO is spot on.
    – Andy
    Aug 27, 2018 at 22:40
  • @Christophe It may not be the final answer to the question, but it was the best I could do with the available information. The question seems to focus on URL's. I'm saying it's more important to define the API depending on the requirements and gave a few options without knowing those details. For example: what if this API is for a soccer application with multiple server backends to handle all teams of the world? Or is there only 1 client, directly linked to 1 API implementation. In that case REST might be overkill and exchanging unspecified blobs of JSON is good enough.
    – Kwebble
    Aug 29, 2018 at 20:34
0

I think option #2 is the simplest to understand, implement and maintain, because you can build it on top of some very basic CRUD operations, that could also be reusable in other cases.

It will result in more requests to your server, but you can probably handle them asynchronously and in parallel, so the application will still be responsive.

If your backend has good horizontal scaling, having smaller requests might actually give you better performance.

Not the answer you're looking for? Browse other questions tagged or ask your own question.