JSON API design: including the same resource in multiple places

50 Views Asked by At

Let's say I'm developing a Rails backend to be used as an API. I have a Book model which has_many Reviews. Each of those Reviews has_many Photos and belongs_to a User. To get an idea of what I'm going for, picture hotel review websites where there are images from both the hotel and users in one gallery. However, alongside the gallery you'll also find individual reviews by a user, containing a couple of pictures. Currently my JSON responses look this:

{
 book: {
  id: 1,
  star_rating: 5
  original_images: []
 },
 reviews: [
  {
   id: 1,
   title: "great book",
   photos: [
    {
     url: "http://foobar.gov",
     caption: "hi"
    },
    {
     url: "www.hello.world",
     caption: "hi"
    }
   ],
   user: {
    name: "Fred"
   }
  },
  {
   id: 2,
   ..etc
  }

My dilemma: on the front end of my app, I want to be able to loop through the reviews and show the review data + review photos, so doing something like review.user, review.title, and review.photos in a loop would be great and works with my current data structure. On the other hand, when I want to show a gallery, it would be easier for me if I had an array at the same level of the structure as original_images, which would contain all of the urls. However, if I was to do this, when I want to display only a specific review's photos, I would have to essentially do a search within that one jumbo-sized array and pick out the images that belong to that particular review.

My question: Should I just include the photos in multiple places? Both where they are now, but also in one large array as a sibling of original_images?

1

There are 1 best solutions below

0
On

So it seems you are looking to solve two problems in regards to review photos:

  1. Displaying all the review photos for a particular resource (hotel in your case).
  2. Displaying only the individual review photos of a resource.

I'm presuming that when the page loads for the hotel, you will want to have all the review photos for it ready. When you want to display an individual review's photos, I assume that a user would click on review and go to a new page or some sort of modal would appear.

Your API is currently sending you all the data you need. Now you just need to wrangle the data on the client side to fit your needs. So when the page loads you will loop through the response and create two arrays: reviews and allReviewImages. You will then display all the review images for the hotel by getting it from the allReviewImages array and then display all the reviews and their associated images by going through the reviewsarray.

To display an individual review's image in a separate page or modal, you can create the necessary logic/link when going through the reviews array: <div data-imagelink="{reviews.photos[id]}"></div>

I don't know what your client is coded with but you get the idea from the example above.

You are getting the data you need from your API response, you just need to do some wrangling on the client side and you should be able to do what you need!