Tell me more ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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!

share|improve this question
1  
To me this feels like the question whether zero is actually an amount. – scarfridge May 29 at 8:14
13  
Your example is broken. You can't have a json objects with duplicate keys. What you are looking for is an array, ie [{"name": "..."}, {"name":"..."}] – Martin Wickman May 29 at 8:18
@MartinWickman Sorry for that, i just fixed it. – andufo May 29 at 14:03
6  
@andufo, actually, you didn't... – avakar May 29 at 17:40
5  
If your application is meant to be RESTful, then why is the verb/method "get" a part of your endpoint URI? – user50849 May 30 at 7:20

8 Answers

up vote 17 down vote accepted

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

{
    meta: {
        number_of_records : 0,
        records_per_page : 10,
        page : 0
    },
    books : [
        {id:1},
        {id:27}
    ]
}
share|improve this answer
I believe this is the best way to treat results. Having 0 records is not an error, its 0 records, so the meta?number_of_records value should be standard for the rest of the calls. Thanks! – andufo May 29 at 16:48
1  
Huh, I wonder why this one isn't voted as highly as the other one. I like this more as it's giving both an empty list (that was supposed to be a list, right?) that you can blindly iterate over without special conditions, but also the metadata count as a way of saying, "No, we didn't gloss over an error for you, there actually were 0 results". – Izkata May 30 at 3:37
2  
Problem with this is that adding "number_of_records" does not provide any more information, it just adds redundancy and increases complexity. To signal an error, return a suitable http code + something in the body. – Martin Wickman May 30 at 10:10
1  
@cspray books is list, as Izkata pointed, my typo. – GrizzLy May 30 at 14:33
2  
@MartinWickman I did not want to pollute original answer with extra metadata, but in my experience, lots of services do not return all data straight away, but in "paginated" way. – GrizzLy May 30 at 14:46
show 1 more comment

Your example is broken. You shouldn't have json objects with duplicate keys. What you are looking for is an array with movie objects, like this:

 [
    {"name": "movie1"}, 
    {"name": "movie2"}
 ]

This approach also answers your question. You should return an empty array when the query does not match:

[]

On the other hand, if you try to get a specific movie resource with GET api/movie/34 and that movie does not exist, then return 404 with a suitable (json encoded) error message in the body

share|improve this answer
1  
+1 This is valid JSON according to json_xs. – l0b0 May 29 at 11:03
+1 for returning the appropriate status code – cspray May 30 at 4:52

If this is JSON, you should really consider returning an Array of objects. This has many advantages including that when you have no records it is an empty array.

So when you have records, you would be returning:

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

And when you have no records, you would be returning:

    [

    ]
share|improve this answer
3  
That's malformed JSON. You can't have value (here: an array) without a key. You probably wanted to omit the outer curly braces. – Xion May 29 at 10:28
Verified @Xion's comment with json_xs -t null < test.json – l0b0 May 29 at 11:02
@Xion Thanks for catching the error! – Devdatta Tengshe May 29 at 11:19

If you execute operation successfully, but it doesn't have anything to return, such as empty map {} or empty array [] I would prefer to respond with 204 response code, here is excerpt from HTTP Status Code Definitions spec:

The server has fulfilled the request but does not need to return an entity-body, and might want to return updated metainformation. The response MAY include new or updated metainformation in the form of entity-headers, which if present SHOULD be associated with the requested variant.

If the client is a user agent, it SHOULD NOT change its document view from that which caused the request to be sent. This response is primarily intended to allow input for actions to take place without causing a change to the user agent's active document view, although any new or updated metainformation SHOULD be applied to the document currently in the user agent's active view.

The 204 response MUST NOT include a message-body, and thus is always terminated by the first empty line after the header fields.

Essentially, I recommend using 204 in RESTful applications over HTTP when there is nothing to return.

share|improve this answer
I agree with @avakar's comment on other answer here. If the client's trying to access /v1/get/movies/1 then it should return 404 if there's no movies identifiable by 1. Just /v1/get/movies should return 200 even if there's no movie. But 204 isn't suitable because it's intended for input actions. – imel96 May 30 at 2:19

There has been a reasonable amount of work done on creating a standardised JSON API format.

Following the principles in that specification mean that all resources returned should effectively be "collections" (even when just a single resource is included). Following this would mean that your call to /v1/get/movies would return:

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

Your call to /v1/get/books (which returns zero resources) would return:

{
    "books": []
}
share|improve this answer

I've seen both cases in production environments. Which one you choose depends on who will be using the API. If they want to know why the list is empty or to be sure that the list is really empty and no errors occurred while retrieving it, then you should attach an "errors" object. If they don't care, go with returning an empty list. I'd go with second approach since it covers more needs than the first.

share|improve this answer

The first thing to consider, since you are building a RESTful API, is to return an appropriate response code. And the more appropriate response code to communicate that the request went through normally, but the requested resource is not available at the moment is the venerable 404.

If you design your API in such a way that it always returns a sensible response code, you might not even need to return a body when the resource was not found. That said, returning a body, especially a humanly readable one, can't hurt.

There's no "best practice" here, both your examples are arbitrary, just pick one and be consistent. Developers hate surprises, if /v1/get/movies returns {} when there are no movies then we'd expect /v1/get/actors to also return {} when there are no actors.

share|improve this answer
1  
Returning a 404 really is the right thing to do, but sadly no one really does it-- myself included. – RibaldEddie May 29 at 6:59
1  
if you have complex responses, and only parts of them are empty, returning a 404 will confuse the user. – devnull May 29 at 7:03
4  
I would disagree with the 404 message. A 404 I would interpret as "resource does not exist" and worry if I got something wrong with my URL or whatever. If I ask for a list of movies and get a 404 I would think that there isn't a movie resource at all. A "204 No Content" may be more appropriate. – thorsten müller May 29 at 7:15
7  
Ok, the "no body" thing would kill it. But: "The 4xx class of status code is intended for cases in which the client seems to have erred.". But there was no error on the client side. So a 404 gives wrong information. Either send 204 without a body or say it's ok and send an empty list. – thorsten müller May 29 at 7:29
5  
You're asking for a list of books, returning 404 would mean that the list doesn't exist, not that it is empty. Returning 200 along with an empty list seems the only reasonable option to me. – avakar May 29 at 17:47
show 7 more comments

I don't think the rigth answer is the one that is marked.

The answer provided by nirth should be the best, in a true REST scenario. The body response should be empty and the http status code: 204; the resource does exists but it has "no content" at that time: is empty.

REST HTTP_Status_Codes

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.