1

Let's say I have a REST API with resources that look something like this:

/users/<id>

{
  "id": <str:user_id>,
  "firstName": <str:first_name>,
  "lastName": <str:last_name>,
  "favoriteColor": <str:color_name>,
  "lotsOfStuff": {...}
}

/groups/<id>

{
  "id": <str:group_id>,
  "name": <str:group_name>,
  "members": <array:list_of_users>
}

I'm wondering what counts as an acceptable way to populate the group.members array. Most things I read imply that the options are:

  1. include only id's (or links) that reference each user in the group. Something like:
members: ["/users/1", "/users/2", "/users/3"]
  1. include a full copy of the user resource.
members: [
  {
    "id": "1",
    "firstName": "Jon",
    "lastName": "Doe",
    "favoriteColor": "Blue",
    "lotsOfStuff": {...}
  },
  ...
]

Option 1 can be very inconvenient for the client because it requires a lot of extra requests to learn about the group members.
Option 2 might be inefficient or infeasible if the user resource is very large.

The 3rd option I would like to use is to include a reference plus a small subset of the target resource. Something like:

"members": [
  {
    "id": "users/1",
    "name": "Bob"
  },
  {
    "id": "users/2",
    "name": "Sally"
  }
]

Now the client has something to work with, but can make an extra call for details. This maps nicely onto list-details UIs.

Is this considered bad practice? Is there a terrible pitfall here that I'm missing?

1 Answer 1

2

Sounds like a very good API to me.

I'm a backend engineer for about 5 years, mainly building http services in Golang.

You need to be aware that you're making a decision to manually manage this new entity (what you call "small subset of the data"). Other than that, there are not hidden pitfalls in my experience. As long as you have basic QA practices, there's no more risk that option 1 or 2.

I would say this is the correct decision for a stable api implementation, with the cost of maintaining a bit more code if something needs to be changed in the /groups/<id> endpoint structure. For example, if /groups/ members also need to have the favorite color, you'll need to add that line of code, and probably add the column to the sql query. I think it's a reasonable price to pay.

This is just a reflection of my style and opinions, and there are many valid counter arguments to mine.

My style is leaning towards explicitness, and to change code only when there's a need. Your solution seems explicit to me, and also there's some need for performance by your /groups/<id>, as you say. So go for it :)

So, to answer the question:

Is this considered bad practice? Is there a terrible pitfall here that I'm missing?

  1. Not a bad practice, in my opinion. I'm using it.
  2. And no, no terrible pitfalls. I've been working like this for a couple of years and even if you realize it's a mistake for that particular place, it's easy to revert back to either option 1 or 2, as needed. So I guarantee it's safe enough to try and see how it feels.

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.