Search code examples
restswaggerdesign-principles

RESTful design for multiple responses with single endpoint


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


Solution

  • 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.