Response format for json api

180 views
Skip to first unread message

JonoB

unread,
Oct 20, 2012, 3:53:00 PM10/20/12
to api-...@googlegroups.com
Hi,

I am in the process of building our API, which (to start off with) will only return json. I've been going round in circles on the best way to structure responses to GET requests. At the moment, I have settled on the following.

For successful responses, I have something like this:

/contacts
[
 {"id":1,"address":123,"city":"London"},
 {"id":2,"address":"456","city":"New York"}
 ...
]


/contacts/3 {"id":3,"address":123,"city":"London"}

For unsuccessful responses, I have the following (this allows me to show more than 1 error message if necessary):
{"errors":["Invalid public key credentials"]}


Extra meta information (such as rate limit, pagination and http code) are returned in the header.


I know that there is no "right" way, but having seen so many different implementations, I'd like to know if this doesn't fall foul of accepted best practice. Am I missing anything super obvious here?

Many thanks for any input that you can give.

mca

unread,
Oct 20, 2012, 3:55:01 PM10/20/12
to api-...@googlegroups.com
start with this recent thread from the group:

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.
 
 

Mike Schinkel

unread,
Oct 20, 2012, 8:26:47 PM10/20/12
to api-...@googlegroups.com
More for this topic came from Mike's RESTFest where Todd Fredrich[1] talked about looking at JSend[2] and JSONRequest[3] and ended up going with a modified JSend looking something like this:

On Success:
{
"code": 200,
"status": "success",
"data": [
  {"id":1,"address":123,"city":"London"},
{"id":2,"address":"456","city":"New York"}
  ...
]
}
On Error:
{
"code": 401,
"status": "error",
"message": "Invalid public key credentials",
"data": "bad-credentials",
}

-Mike

Live Flex

unread,
Oct 21, 2012, 8:26:54 AM10/21/12
to api-...@googlegroups.com
Thanks for the reply Mike. I see a lot of value in that kind of response, although there is an argument that the code and status could be included in the header.

Steve Klabnik

unread,
Oct 21, 2012, 9:47:19 AM10/21/12
to api-...@googlegroups.com
> Thanks for the reply Mike. I see a lot of value in that kind of response,
> although there is an argument that the code and status could be included in
> the header.

Yeah, a code in the body seems to imply to me you're not using the
http code, which makes me sad. Then again, I'm assuming someone who
goes to RESTfest isn't making that mistake, so why duplicate the info?

I guess I'll have to watch the video :)

Peter Williams

unread,
Oct 21, 2012, 11:59:51 AM10/21/12
to api-...@googlegroups.com

I don't like this approach. It obscures the most important parts of the representation with information that is best handled in the HTTP layer. Most HTTP libs these days are not broken and therefore allow easy access to the header info.

If you really do have clients that are not able to access the response codes I'd prefer tucking that info away in a corner so that clients with less brain damage can ignore it.  For example,

    {
      "address": "123 ...",
      // rest of data
      "_resp_metadata": {
        // for clients that use borked HTTP libs
        "code": 200,
        "status": "success"
    }

Peter
Barelyenough.org

Mike Schinkel

unread,
Oct 21, 2012, 4:17:34 PM10/21/12
to api-...@googlegroups.com
On Oct 21, 2012, at 8:26 AM, Live Flex <live...@gmail.com> wrote:
Thanks for the reply Mike. I see a lot of value in that kind of response, although there is an argument that the code and status could be included in the header.

On Oct 21, 2012, at 11:59 AM, Peter Williams <pe...@barelyenough.org> wrote:
I don't like this approach. It obscures the most important parts of the representation with information that is best handled in the HTTP layer. Most HTTP libs these days are not broken and therefore allow easy access to the header info.

If you watch the video[1] you'll see that Todd addresses the need around 4:30 saying that in jQuery AJAX you can't read the status code nor headers and he had at least one person in the audience agree that it is a problem.

I post his example to the list because it seemed that others on this and the prior thread were collecting different approaches and I felt his approach had merit to be added to the list.

If you really do have clients that are not able to access the response codes I'd prefer tucking that info away in a corner so that clients with less brain damage can ignore it.  For example,

    {
      "address": "123 ...",
      // rest of data 
      "_resp_metadata": {
        // for clients that use borked HTTP libs
        "code": 200,
        "status": "success"
    }

I prefer Todd's approach because it puts the meta at the top level and then "real data" in the "data" property. Nothing obscures the real data and if you just want the pure data you can easily grab just it.  Not so if there is an embedded "_resp_metadata" or otherwise named property. FWIW.

"Ionuț G. Stan"

unread,
Oct 22, 2012, 8:33:32 AM10/22/12
to api-...@googlegroups.com
On 21/Oct/2012 23:17, Mike Schinkel wrote:
> On Oct 21, 2012, at 8:26 AM, Live Flex <live...@gmail.com
> <mailto:live...@gmail.com>> wrote:
>> Thanks for the reply Mike. I see a lot of value in that kind of
>> response, although there is an argument that the code and status could
>> be included in the header.
>
> On Oct 21, 2012, at 11:59 AM, Peter Williams <pe...@barelyenough.org
I prefer Twitter's approach here[0]. If you're using a dumb HTTP client,
then add a query param requiring HTTP-level info to be added to the
response body (the API must support this of course).

For example, if you send a request to the Twitter API and the URL
includes a "suppress_response_codes" query param then all responses,
even those with errors, will be returned as 200 OK, and the real status
code will be included in the response body.

I don't want to pollute the response body for dumb HTTP clients that are
supposed to be fixed.

[0]:
https://dev.twitter.com/docs/things-every-developer-should-know#parameters-have-certain-expectations

--
Ionuț G. Stan | http://igstan.ro

Andrei Neculau

unread,
Oct 23, 2012, 10:41:02 AM10/23/12
to api-...@googlegroups.com
+1

I would actually throw in a proxy for these clients with special needs, and wrap the HTTP request/response overall, while keeping the "real" payload intact.

Regular request:

POST /x
< 202
< Content-Type: application/xml
<root><status>pending</this></root>


Special request (JSONP?!):

GET /x?callback=fun
Prefer: mechanism=jsonp
> X-HTTP-Override-Method: POST
< 200
< Content-Type: application/javascript
fun({
 http_status_code: 202,
 http_headers: [
  'Content-Type: application/xml'
 ],
 payload: '<root><status>pending</status></root>'
});

Live Flex

unread,
Oct 23, 2012, 10:51:20 AM10/23/12
to api-...@googlegroups.com
Ionuț G. Stan's approach seems to be the best, as it satisfies everyone's requirements.

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+unsubscribe@googlegroups.com.

Frode Rosand

unread,
Oct 23, 2012, 4:59:41 PM10/23/12
to api-...@googlegroups.com
Just a quick note on jQuery. It can access the status codes from the response header and has been able to do so for a while.


Frode

Mike Schinkel

unread,
Oct 23, 2012, 6:04:00 PM10/23/12
to api-...@googlegroups.com
On Oct 23, 2012, at 4:59 PM, Frode Rosand <fr...@rosand.net> wrote:
> Just a quick note on jQuery. It can access the status codes from the response header and has been able to do so for a while.

What about JSONP? For example: https://developer.foursquare.com/overview/responses

-Mike

Peter Williams

unread,
Oct 23, 2012, 10:47:47 PM10/23/12
to api-...@googlegroups.com
Someone just a little less caring than i might say that people that
let untrusted third parties execute arbitrary code in their private
sand box will get what they deserve. Being much nicer than that, i
will say that a service could really do any weird thing it wants with
its jsonp responses but it should avoid mucking up the representations
it gives to clients that want reasonable responses.

Peter
barelyenough.org

Andrei Neculau

unread,
Oct 24, 2012, 2:10:35 AM10/24/12
to api-...@googlegroups.com
apigee/brian mulloy on proxies http://t.co/IJd4hKxS
Reply all
Reply to author
Forward
0 new messages