[WSG] REST HTTP error codes and responses for form/parameter validation

The current ActiveRecord::Errors#to_xml just spits out the full_messages. Though Rick has that working by pulling out bits of strings it doesn't really help non-ActiveResource XML consumers, and hey, it's XML, so why not put it in an attribute instead?

http://dev.rubyonrails.org/browser/trunk/activeresource/lib/active_resource/validations.rb?rev=5068

Below is my post to a discussion on the web standards group list I started just the other day.

(Awesome work BTW Rick. ActiveResource is coming together quite nicely!)

-- tim

Sorry, and of course DHH for laying the ground work :slight_smile:

-- tim

> The current Rails approach for validation errors when trying to > create resources is to return "400 Bad Request" with the following > response: > > <?xml version="1.0" encoding="UTF-8"?> > <errors> > <error>Password confirmation can't be blank</error> > <error>Password is too short (minimum is 4 characters)</error> > <error>Password can't be blank</error> > <error>Login is too short (minimum is 3 characters)</error> > <error>Login can't be blank</error> > <error>Email is too short (minimum is 3 characters)</error> > <error>Email can't be blank</error> > </errors> > > It could definitely be improved by at least including the resource > attribute the error relates to: > > <?xml version="1.0" encoding="UTF-8"?> > <errors type="ActiveRecord::Errors"> > <error attribute="password_confirmation">Password confirmation > can't be blank</error> > <error attribute="password">Password is too short (minimum is 4 > characters)</error> > <error attribute="password">Password can't be blank</error> > <error attribute="login">Login is too short (minimum is 3 > characters)</error> > <error attribute="login">Login can't be blank</error> > <error attribute="email">Email is too short (minimum is 3 > characters)</error> > <error attribute="email">Email can't be blank</error> > </errors>

Looks good to me, except for the type attribute of <errors>.

Any thoughts on using 400? I know that's kind of a generic status code, but none of the others really fit.

Wouldn’t a ‘409 Conflict’ make more sense for errors?

I realize how we serve out data via a REST API (i.e. XML data format, HTTP status codes, etc.) is pretty manual/flexible at this point and everyone is probably doing things a little bit differently (some people are using slightly different status codes, some people are formatting xml a little differently, etc.)

What sort of guidelines should we be looking to follow to help our APIs be “ActiveResource-compatible”? Is it too early for that right now? Do you think things will get to the point to where Rails will make it difficult NOT to conform to the ActiveResource conventions? I know that’s generally the idea with most best-practices for Rails, but I don’t see things quite being there yet in terms of generating a REST API.

I’m using 400 for validation errors and 409 for stale object errors (optimistic lock failed).

jeremy

Looks good to me, except for the type attribute of <errors>.

If 400's are only ever going to represent validation errors then we don't need the <error type="validation">.

I'll put together a patch for the <error attribute="">. Relying on the full message isn't going to sit well with the i18n folk.

Any thoughts on using 400? I know that's kind of a generic status code, but none of the others really fit.

Yeah, nothing else really makes sense.

-- tim

If 400's are only ever going to represent validation errors then we don't need the <error type="validation">.

I'll put together a patch for the <error attribute="">. Relying on the full message isn't going to sit well with the i18n folk.

Sending back english strings isn't going to be too useful for non-interactive users of an api, perhaps we need to think about also including some kind of 'error code'. i.e.

<error attribute="first_name" code="invalid.format">First name must be letters</error>

Using those two values people can deduce what's wrong without just chucking a string up to a user. This is pretty critical when your web service call isn't going to be handled by a user who can read the strings and figure out what's going on.

Anyone have any opinions on this?