Search code examples
javascriptjavanode.jsrestapi-design

REST API design for collection that is naturally divided into subcollections


I have a a collection of requests send from my client application to server that handles them. I create new request with this request

POST api/v1/requests

After the request is send it recieves the status PENDING and after being evaluated the staus is changed to RESOLVED. Thus I have collection requests that is divided into 2 subcollections: requests.pending and requests.resolved. I need a way to get pagable access to both of them AND to be albe to cache those pages.

Would it be the REST way to make them like this:

GET api/v1/requests/page/:page            - returns pages of all requests collection
GET api/v1/requests/pending/page/:page    - returns pages of pending requests collection
GET api/v1/requests/resolved/page/:page   - returns pages of resolved requests collection

I'm a bit uncomfortable with this approach as main resource is requests collection and I'm creating 2 artificial collection (or stores) on top of it. Nevertheless I think I can't just approach this with query params like this as query parameters are not supposed to be cached witin REST protocol by cache servers:

GET api/v1/requests/?page=:page            - returns pages of all requests

Solution

  • There are a LOT of ways to do your urls here and I'm sure there will be several (strong) opinions given.

    My recommendation would be the following...

    POST ../api/v1/request
    

    The v1 vs 1 is my personal preference, I think the v1 is more descriptive than just a 1.

    There are a lot of discussions of plural vs singular for resource names. My preference is for singular.

    // redirects to a paginated url
    GET ../api/v1/request -> ../api/v1/request?page=1&rpp=10
    
    // your default page that return all types of requests ordered
    // however you want, most likely reverse date created.
    GET ../api/v1/request?page=1&rpp=10
    
    // returns pending requests.
    GET ../api/v1/request?page=1&rpp=10&status=pending
    
    // returns resolved requests.
    GET ../api/v1/request?page=1&rpp=10&status=resolved
    

    Here is my thinking... From what I can tell, you're actually trying to query the requests that you have.

    Generally, more specific/nested urls are for child relationships.

    For example, get all the addresses for a specific customer:

    GET ../api/v1/customer/1/address
    

    All the above urls would be able to be cacheable and bookmarkable.