4

Say I have a Student who has a ID number, a name, a profile picture, some contact details, and is enrolled in several courses.

From the perspective of a Single Page Application there are different scenarios where I might want to see different views of this student object.

For example:

  • An admin page might want to see the student, and their contact details.
  • A yearbook just wants the student and their profile picture.
  • A profile page wants the student and the list of courses they are enrolled in.
  • A grades page wants the student, and the list of courses they are in, and the grades for those courses.

Where this question is relevant is mostly on the 'and the courses they are enrolled in' questions - where, on the backend this involves some kind of multiple table joins and formatting.

The question is - what is the RESTful way of doing this/what REST principles should I adhere to?

For example, is the right way to do this, to just declare several endpoints like:

  • /api/v1/student/:id/contactsummary
  • /api/v1/student/:id/profilesummary
  • /api/v1/student/:id/profileandcoursessummary
  • /api/v1/student/:id/gradessummary

?

2 Answers 2

7

The question is - what is the RESTful way of doing this/what REST principles should I adhere to? is the right way to do this, to just declare several endpoints

An important thing to understand about REST: if the resource identifier is different, then the resource is different. As far as a generic client can tell, these are three different things:

/api/v1/student/1/contactsummary
/api/v1/student/1/profilesummary
/api/v1/student/2/profilesummary

In use cases where the resources are read-only, it probably doesn't matter very much.

But if the client is going to POST/PUT/PATCH the contact summary, then there is an interesting question: should that change invalidate previously cached representations of the profile summary?

When the answer is "no", then you certainly want two different URI.

When the answer is "yes", then you want the same URI, and need some other way to distinguish the two representations. That leads you to the realm of content negotiation. So you might have two different media types, application/vnd.example.contactsummary+json and application/vnd.example.profilesummary+json, and the client asks for the representation it expects (much in the same way that a web browser can ask for images differently than it asks for scripts).

Remember - the fact that the underlying implementation of these "resources" happens to be the same, or not, is only an implementation detail. HTTP semantics insulate the client from the need to know, or care, about what is really going on.

Your URI design is motivated by the illusion you create

on the internet, no one knows you are a dog

5
1

A good API is flexible enough to be easy to understand and flexible to attend different scenarios.

You are on the right path, but I will make some changes and explain why.

About the contact details, the word summary seems unnecessary if your objetive is show the contacts on a single format. So I recommend:

/api/v1/students/:id/contacts/

If you would like also to show the contacts in a shorter way, the summary of the contacts could be represented on this way:

/api/v1/students/:id/contacts/summary/

I'm not a big fan to use this singular word on endpoints, but seems OK in this kind of problem. The same logic can be applied on the other endpoints.

The special case is when you mention that would like to have a endpoint to show the profile of the student and courses:

/api/v1/student/:id/profileandcoursessummary

Sometimes to be more flexible and clear about what your endpoint is capable to do, one single endpoint is not the best solution. So you could have two different endpoints to have a better representation about the API intentions:

/api/v1/students/:id/profiles/ # or /profile
/api/v1/students/:id/courses/

If you would like to both on the same endpoint (to make less requests), you can assume that each time that you bring the profile you also will bring the courses. It's not really necessary to declare the courses on the name of the endpoint. So, you can just use:

/api/v1/students/:id/profiles/

About this case:

A grades page wants the student, and the list of courses they are in, and the grades for those courses.

I will recommend something like:

/api/v1/students/:id/courses/grades/

Instead of:

/api/v1/students/:id/grades/

Because you are getting the grades from the courses of the student, and not the grades directly from the student.

My final tip is consider another alternative to version your API. There are pros and cons on use version on the URL (like you did using v1). Take a look on the Versioning using Accept header, also know as Versioning through content negotiation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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