Standard endpoints with complex filtering vs. Custom endpoints with custom, pre-filtered results: what's most JSONAPI-esque?

Let’s say I have a simple application where users can create collaborative photo albums. All albums are visible to all users and any user can add or remove a picture from any album. Any picture must always be inside one and only one album. On a user’s home page, they have a select menu that lists all existing albums for display. When they choose an album, a subset of the pictures in that album is displayed. The subset is configurable by the user, who can choose what pictures they want to see from that album and in what order. The models would look something like this:

# I'm using Django just for the sake of this example, but my question should be
# relevant regardless of frameworks

class User(models.Model):
    name = models.CharField()

class Album(models.Model):
    name = models.CharField()

class Photo(models.Model):
    name = models.CharField()
    album = models.ForeignKey(Album, related_name='photos')

class PhotoDisplay(models.Model):
    photo = models.OneToOneField(Photo, related_name='display')
    user = models.ForeignKey(User)
    order = models.PositiveSmallInteger()

If I’m working on the user home page, for each album, I’d want to retrieve the subset of photos the user wants to see in the right order. Given an Album with id=1 and a User with id=3, in the backend, using Django’s ORM, I’d do something like this:

>>> Album.objects.get(id=1).photos.filter(
...    display__isnull=False, display__user_id=3).order_by('display__order')
<QuerySet [<Photo: dog-pic.jpg>, <Photo: cat-pic.jpg>]>

Now, within the framework and philosophy of JSONAPI, what would be most recommended:

  1. Write a custom endpoint that returns exactly this
{
  "links": {
    "self": "http://example.com/albums/1/photos-for-display?filter[user]=3"
  },
  "data": [
     {
         "type": "photos",
         "id": "18",
         "attributes": {
             "name": "dog-pic.jpg"
         }
     },
     {
         "type": "photos",
         "id": "5",
         "attributes": {
             "name": "cat-pic.jpg"
         }
     }
 ]
}

2. Be more frontend-agnostic and just make sure to respect the JSONAPI interface, leaving the work of filtering/sorting to the frontenders, who would in turn probably use some complex filtering like this:

```json
{
  "links": {
    "self": "http://example.com/albums/1/photos?filter[user]=3,filter[display__isnull]=False,sort=display__order"
  },
  "data": [
     {
         "type": "photos",
         "id": "18",
         "attributes": {
             "name": "dog-pic.jpg"
         }
     },
     {
         "type": "photos",
         "id": "5",
         "attributes": {
             "name": "cat-pic.jpg"
         }
     }
 ]
}

Note that in this case I’d have to implement a Django-specific filtering strategy so I can use the __ syntax for specific database operations (e.g. __isnull) and following relationships (e.g. display__order).

What’s the most JSONAPI-esque way of doing things? Which one best captures the spirit that inspired the creation of JSONAPI? Or either one is equally fine?

Thanks

1 Like