Mailing List Archive

RESTful response codes.
Here's a discussion I'm having with a consumer of an API.

For a RESTful service they would like the API to ALWAYS include a response
body that includes a { status_block => { status => 'success" } }. I, of
course, point out that HTTP already provides a complete list of http status
codes. But, they suggest that there might be a time when additional status
is needed. I cannot think of case where that would happen. PUT a
resource and it's either successful or not -- there's no gray area.

The HTTP spec http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html seems
pretty clear.

Can anyone think of a reason to always return a status? Or better, any
references that would be more helpful or convincing than the spec listed
above?

Thanks,

--
Bill Moseley
moseley@hank.org
Re: RESTful response codes. [ In reply to ]
I think your API needs to provide a mapping between HTTP response codes and your intended response codes.. that should be enough to keep them happy..


201-> created
401-> access denied


etc.


On Feb 23, 2012, at 3:25 PM, Bill Moseley wrote:

> Here's a discussion I'm having with a consumer of an API.
>
> For a RESTful service they would like the API to ALWAYS include a response body that includes a { status_block => { status => 'success" } }. I, of course, point out that HTTP already provides a complete list of http status codes. But, they suggest that there might be a time when additional status is needed. I cannot think of case where that would happen. PUT a resource and it's either successful or not -- there's no gray area.
>
> The HTTP spec http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html seems pretty clear.
>
> Can anyone think of a reason to always return a status? Or better, any references that would be more helpful or convincing than the spec listed above?
>
> Thanks,
>
> --
> Bill Moseley
> moseley@hank.org
> _______________________________________________
> List: Catalyst@lists.scsys.co.uk
> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
> Dev site: http://dev.catalyst.perl.org/

Francisco Obispo
email: fobispo@isc.org
Phone: +1 650 423 1374 || INOC-DBA *3557* NOC
PGP KeyID = B38DB1BE


_______________________________________________
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/
Re: RESTful response codes. [ In reply to ]
I suspect he's used to XML-RPC, where it's conventional to return, on error, a valid XML document and an HTTP status of 200. It's the content of the document that determines the status.

You should, IMO, try to steer them to your way of thinking, which seems rather more conventional for a RESTful API.

Regards
David

On 23 Feb 2012, at 23:25, Bill Moseley wrote:

> Here's a discussion I'm having with a consumer of an API.
>
> For a RESTful service they would like the API to ALWAYS include a response body that includes a { status_block => { status => 'success" } }. I, of course, point out that HTTP already provides a complete list of http status codes. But, they suggest that there might be a time when additional status is needed. I cannot think of case where that would happen. PUT a resource and it's either successful or not -- there's no gray area.
>
> The HTTP spec http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html seems pretty clear.
>
> Can anyone think of a reason to always return a status? Or better, any references that would be more helpful or convincing than the spec listed above?
[sig snip]
Re: RESTful response codes. [ In reply to ]
Think I've been here before...

Sounds like this is down to the separation of transport vs application.

If the request was successfully received, you should return a 200.

If your app decides something was wrong, then it's for your own message
framework to send that information back.


Don't just jump on the back of HTTP codes and leave the client wondering
if it just a bad line, etc.




--

IntelCompute
Web Design and Online Marketing

http://www.intelcompute.com


-----Original Message-----
From: David Stevenson <hoagy@ytfc.com>
Reply-to: The elegant MVC web framework <catalyst@lists.scsys.co.uk>
To: The elegant MVC web framework <catalyst@lists.scsys.co.uk>
Subject: Re: [Catalyst] RESTful response codes.
Date: Fri, 24 Feb 2012 00:06:55 +0000

I suspect he's used to XML-RPC, where it's conventional to return, on
error, a valid XML document and an HTTP status of 200. It's the content
of the document that determines the status.


You should, IMO, try to steer them to your way of thinking, which seems
rather more conventional for a RESTful API.


Regards
David

On 23 Feb 2012, at 23:25, Bill Moseley wrote:

> Here's a discussion I'm having with a consumer of an API.
>
>
> For a RESTful service they would like the API to ALWAYS include a
> response body that includes a { status_block => { status =>
> 'success" } }. I, of course, point out that HTTP already provides a
> complete list of http status codes. But, they suggest that there
> might be a time when additional status is needed. I cannot think of
> case where that would happen. PUT a resource and it's either
> successful or not -- there's no gray area.
>
>
> The HTTP spec http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
> seems pretty clear.
>
>
> Can anyone think of a reason to always return a status? Or better,
> any references that would be more helpful or convincing than the spec
> listed above?
[sig snip]


_______________________________________________
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


_______________________________________________
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/
Re: RESTful response codes. [ In reply to ]
On Fri, Feb 24, 2012 at 7:31 AM, Rob Brown <rob@intelcompute.com> wrote:

> Think I've been here before...
>
> Sounds like this is down to the separation of transport vs application.
>
> If the request was successfully received, you should return a 200.
>
> If your app decides something was wrong, then it's for your own message
> framework to send that information back.
>
>
> Don't just jump on the back of HTTP codes and leave the client wondering
> if it just a bad line, etc.
>

I was going to disagree with you, but I think we are talking about two
differnt things.

For a 400 response I completely agree with you. In that case I do return a
very detailed and standard-formatted response that explains why the client
request could not be processed.


This consumer of he API is arguing that the 2xx HTTP response are not
enough of a "status" -- that *every* request needs a status (and that
should not mix HTTP "transport" codes with business logic). But, I cannot
think of an example where this would be the case.

So you do GET /user/1234 and it returns a 200 with a status saying { status
=> "here's the user you asked for, but I was not able to look up their LDAP
id because the server was down. Hope you don't mind the omission." }.
That's a scary road to head down, no?

I cannot think of a POST, GET, PUT, or DELETE on a resource where the
status cannot be represented with HTTP response status -- because that's
how it is designed.



--
Bill Moseley
moseley@hank.org
Re: RESTful response codes. [ In reply to ]
On Fri, 24 Feb 2012, Bill Moseley wrote:

> This consumer of he API is arguing that the 2xx HTTP response are not
> enough of a "status" -- that every request needs a status (and that
> should not mix HTTP "transport" codes with business logic).  But, I
> cannot think of an example where this would be the case.
>
> So you do GET /user/1234 and it returns a 200 with a status saying {
> status => "here's the user you asked for, but I was not able to look up
> their LDAP id because the server was down.  Hope you don't mind the
> omission." }.  That's a scary road to head down, no?
>
> I cannot think of a POST, GET, PUT, or DELETE on a resource where the
> status cannot be represented with HTTP response status -- because that's
> how it is designed.

I think part of this comes down to your choice of URI and what represents
a "thing" in your web app.

If you're able to separate each thing into a sane URI and support PGPD as
appropriate on every URI, then the HTTP statuses should "just work", for
some value of "just".

One thing that can be a bit though is some sort of batch update, where you
want to update more than one thing at once for efficiency. What do you do
if part of the batch succeeds and part fails? Maybe you just run
everything in a transaction so this isn't possible.


-dave

/*============================================================
http://VegGuide.org http://blog.urth.org
Your guide to all that's veg House Absolute(ly Pointless)
============================================================*/
Re: RESTful response codes. [ In reply to ]
On Fri, Feb 24, 2012 at 10:08 AM, Dave Rolsky <autarch@urth.org> wrote:

>
> One thing that can be a bit though is some sort of batch update, where you
> want to update more than one thing at once for efficiency. What do you do
> if part of the batch succeeds and part fails? Maybe you just run everything
> in a transaction so this isn't possible.
>

Yes, that's a good example.

The transaction part is up to the business logic. If the logic is
All-or-None then it's 200 or 400, right?

As and example, for batch file uploads the business logic allows some to
fail, so I return a response and a way for the client to map what they
uploaded to the items in the response (e.g. the response keyed by
client-provided filename). Some may be accepted and some may be rejected
with an error: "sorry, .exe files are not accepted".

So, that's a 200 response with the response structure that indicates what
was done with each item in the batch. The request worked as expected --
and it's expected that some items may fail.

Now, If sending a batch of items vs. a bunch of pipelined single POST
requests is much faster is another question. And if not, then life might
be simpler, eh, more restful, if only allow one upload at time.


For a batch update I'd tend to fail the entire thing, but it depends on the
business logic.

Say, to *set* the set of tags associated with a photo:

PUT /photo/123/tags { tags => [ 1,2,3,55,9 ] }

And "55" doesn't exist I'd probably fail 400 because you cannot complete
what the request requested.

So, likewise if each element happes to be more complex (say updating a
collection of users) then it's still the same.



BTW -- I'm lazy so I always return a hash with a key and a value of a LIST.

GET /user # returns ALL users

returns a LIST of users:

{ user => [ \%user1, \%user2, ... ] }

So, what I do for convention is ALWAYS return a list, so:

GET /user/123 returns { user => [\%user123] }

... which makes coding easy on both ends. And having it keyed by "user"
means I am free to combine requests to return additional data in the same
response structure, of course.

Yes, there's gray area.


--
Bill Moseley
moseley@hank.org
Re: RESTful response codes. [ In reply to ]
* Bill Moseley <moseley@hank.org> [2012-02-24 03:00]:
> I was going to disagree with you, but I think we are talking about two
> differnt things.
>
> For a 400 response I completely agree with you. In that case I do
> return a very detailed and standard-formatted response that explains
> why the client request could not be processed.

Right. A 4xx response says you couldn’t give the client the thing it
asked for, which means the response body bears no relation to the
content of the thing anyway and could be anything you deem useful in
that scenario. A machine-readable structured error message is the
obvious option.

> This consumer of he API is arguing that the 2xx HTTP response are not
> enough of a "status" -- that *every* request needs a status (and that
> should not mix HTTP "transport" codes with business logic). But,
> I cannot think of an example where this would be the case.

It is the wrong way to think of HTTP. HTTP is an application protocol,
not a transport protocol. Rather than a network layer for carrying the
arbitrary semantics specific to your application, it is a standardised
vocabulary for expressing application semantics in a general way.

That means sometimes one has to constrain an application design in order
to fit it into HTTP. But that is not an arbitrary capricious lack of
freedom, rather HTTP is derived from a set of principles designed to
guarantee a particular set of characteristics. Those are what one gets
those in exchange for abiding by HTTP’s restrictions.

This API consumer’s request is mistaken in two ways:

1. They are essentially arguing that your application needs arbitrary
application-specific semantics beyond the vocabulary. That is a…
rather contestable premise. Far from everything fits into HTTP but
few who claim special snowflake status have grounds for it.

2. The mechanism they suggest is broken. In a 200 response the body is
supposed to represent the state of the *resource*, expressed in some
concrete format. What they are asking you to put in the response body
is information about the *request*. That does not belong there. This
is another indicator that they are thinking about HTTP as a transport
protocol.

In short, I suggest you don’t listen.

> So you do GET /user/1234 and it returns a 200 with a status saying
> { status => "here's the user you asked for, but I was not able to look
> up their LDAP id because the server was down. Hope you don't mind the
> omission." }. That's a scary road to head down, no?

That’s even worse than the suggestion above, it’s plain broken.

Regards,
--
Aristotle Pagaltzis // <http://plasmasturm.org/>

_______________________________________________
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/