RESTful design for multiple responses with single endpoint
Asked Answered
W

1

6

I'm working on the project which provides REST API. Recently we decided to integrate it with Swagger to create detailed documentation for each endpoint. Almost all RESTs were successfully integrated but for some of them we encountered few difficulties.

So, we have a REST with "/users" resource which by default returns list of users by given criterias in JSON format, e.g. :

[
{
    name: "user1",
    age: 50,
    group: "group1"
},
{
    name: "user2",
    age: 30,
    group: "group2"
},
{
    name: "user3",
    age: 20,
    group: "group1"
}
]

One of the requirements to this REST was to group users by "group" field and provide response with following format:

[
    group1: [ 
        {
            name: "user1",
            age: 50,
            group: "group1"
        },
        {
            name: "user3",
            age: 20,
            group: "group1"
        }]
    group2: [
        {
            name: "user2",
            age: 30,
            group: "group2"
         }
    ]
]

We provide such response when query param groupby equals to "group". So, the problem is that Swagger allows to provide only single response format by single endpoint(method and response code). E.g. we can't provide 2 response formats for /users endpoint "200" response code and GET HTTP method.

And now I'm absolutely confused about the way how to change our REST design in order to make it Swagger compatible.

Notes: It seems to incorrect to add new endpoint for groupped users as far as according to the REST design principles grouped users are not a separate resource but just additional representation of existing resource.

Swagger is not a strict requirement so any ideas regarding other REST documentation tools would be highly appreciated

Wassyngton answered 12/12, 2015 at 23:19 Comment(0)
J
6

As you correctly pointed out, you return two different formats (representations) in your two use cases. Ungrouped users are returned as an array (collection) of users. When you append a groupBy query parameter you return something completely different - a set of search results.

If you want to do a RESTful search, treat a search as a resource of its own. The downside is that it will require two requests to the server to get a response: one to create a search object and return a 201 with an appropriate Location header and a link to search results, and one another request to retrieve results for this search. The upside is that is will work with Swagger and you an reuse the pattern for other resources.

Alternatively, if you only need to group users by one parameter - group, you can indeed add an extra resource: /user-groups as you are effectively retrieving all groups of users with user collections embedded.

Jessie answered 16/12, 2015 at 21:21 Comment(2)
Could you please provide some details about part with 201 response code, or give some exampleWassyngton
When you create a new search resource by POSTing to /searches you should return a status code of 201 CREATED and a Location header with the URI of the search (not its results!) as the value. You should also return a link to the result of this search. Calling the URI on that link would return a search result representation which you can craft for grouping. For example: totalCount: 10, groups: [ {name: "group1", results: [{name: "user2", group: "group1"...}, {...}...]} ] . This would be restful but quite high maintenance so do consider the simpler user-groups option.Jessie

© 2022 - 2024 — McMap. All rights reserved.