BeniRose
BeniRose

Reputation: 412

REST: Filter primary resource by properties on related resource

I'm looking for some guidance/advice/input on the concept of filtering resources when making a REST API call. Let's say I have Users and Posts, and a User creates a Post. If I want to get all Posts, I might have a route as follows:

GET /api/posts

Now if I wanted to get all posts that were created after a certain date, I might add a filter parameter like so

GET /api/posts?created_after=2017-09-01

However, let's say I want to get all posts by Users that were created after a certain date. Is this the right format?

GET /api/posts?user.created_after=2017-09-01

When it comes to filtering, grouping, etc, I'm having a hard time figuring out the right stuff to do for REST APIs, particularly when using a paginated API. If I do this client side (which was my initial thought) then you potentially end up with a variable number of resources per page, based on what meets your criteria. It seems complicated to add all of this logic as query parameters over the API, but I can't see any other way to do it. Is there a standard for this kind of thing?

Upvotes: 2

Views: 1095

Answers (2)

Tarlog
Tarlog

Reputation: 10154

Personally, I would not use user.created_after.

I would rather prefer one of the following options:

Option I: /api/posts/users/{userid}?created_after=2017-09-01

Option II: /api/posts/?user={userid}&created_after=2017-09-01

The reason is simple: It looks wrong to me to create dynamic query parameters. Instead you can combine the query parameters (Option II) or even define a more specific resource (Option I).

Regarding pagination: the standard approach is something like this: In addition to filter parameters, you define the following parameters: page and pageSize. When constructing the request, client will specify something like page=2&pageSize=25&orderBy=creationDate. It's important to note that server must always validate the parameters and can potentially ignore or override incorrect parameters (e.g. page doesn't exist, or pageSize is too big may not return an error, but instead returning reasonable output. This really depends on your business case)

Upvotes: 1

Evert
Evert

Reputation: 99599

There is no objective 'right' way. If using user.created_after logically makes sense in the context of your API, then there's nothing really wrong with it.

Upvotes: 1

Related Questions