RESTful API Design – What to Return When No Rows Found

api-designjsonprogramming practicesrest

I'm currently coding an API for a social network with the Slim Framework. My question is: What are the best practices when there are no rows to return in the json structure?

Lets say that this call /v1/get/movies returns 2 rows from the table movie names:

[
    {"name": "Ghostbusters"},
    {"name": "Indiana Jones"}
]

But, then I call /v1/get/books and there are no rows in that table. Should I just return an empty structure?

[
]

…or would it be better a message and an error code?

[
    "errors": {
        "message": "no matches found",
        "code": 134
    }
]

Which is a better practice? (the API will be used in iOS and Android apps) Thanks!

Best Answer

Usually I would return number of records in result as metadata. I am not sure if that is normal REST practice, but it is not much extra data, and it is very precise. Usually there is pagination for lots of services, it is impractical to return huge resultset at once. Personally I am annoyed when there is pagination for small result sets.. If it is empty, return number_of_records : 0 and books as empty list/array books : [].

{
    meta: {
        number_of_records : 2,
        records_per_page : 10,
        page : 0
    },
    books : [
        {id:1},
        {id:27}
    ]
}

EDIT (few years later): Answer from Martin Wickman is much better, here is "short" of explanation why.

When dealing with pagination always keep in mind possibility of contents or ordering changing. Like, first request comes, 24 results, you return first 10. After that, "new book" is inserted and now you have 25 results, but with original request it would come ordered in 10th place. When first user requests 2nd page, he would not get "new book". There are ways to handle such problems, like providing "request id" which should be sent with following API calls, then returning next page from "old" result set, which should be stored somehow and tied to "request id". Alternative is to add field like "result list changed since first request".

Generally, if you can, try to put extra effort and avoid pagination. Pagination is additional state which can be mutated and tracking such changes is error prone, even more so because both server and client need to handle it.

If you have too much data to process at once, consider returning "id list" with all results and details for some chunk of that list, and provide multi_get/get_by_id_list API calls for resource.