12

I have a service where some validation rules must be checked before a particular operation should be able to take place.

For instance, the client should not generate printable reports if all of the validation rules are not being met.

However, an individual client may not have all of the required information (that user may only be able to access a subset of the data that is used to determine validation success), so a request must be sent to the server: basically "is a thing valid between start and finish".

The response will either be some sort of token that indicates VALID: FEEL FREE TO CONTINUE, or a list of validation failure reasons, that can be presented to the user.

It's obvious that a successful validation will return a 200 OK. But I don't feel that a success status code is appropriate for a validation failure. I'm leaning towards a 409 Conflict, but I've only ever used this to reject a PUT or POST. Is it valid (snicker) to have a validation failure indicated by a 409, or is there a better way?

Note: the action performed is not being performed on the server, so skipping this check, and just attempting the action, with a 403 in the case of the action being forbidden is not an option.

merv
  • 67,214
  • 13
  • 180
  • 245
Matthew Schinckel
  • 35,041
  • 6
  • 86
  • 121
  • 3
    You've requested validation information from the server. It has complied. Feels like success to me (from an HTTP perspective) – Damien_The_Unbeliever Jun 29 '12 at 07:15
  • Damien_The_Unbeliever: If you put this into an answer, I'll accept it. – Matthew Schinckel Aug 16 '12 at 04:48
  • I don't what's the big deal here? You can use `409` for validation. But only in one case that is If user is trying to create a resource that already exist, hence `conflict`. – sujeet Mar 12 '20 at 05:32
  • ...which is not the case here. The request itself has succeeded, but reported a failed validation. Like the accepted answer says. Your comment does not add any value. – Matthew Schinckel Mar 16 '20 at 23:39

5 Answers5

31

You've sent a request to the server for it to perform validation. It has successfully performed said validation. From an HTTP perspective, the request was well formed and correctly processed by the server.

So I'd say returning any HTTP error code would be incorrect.


This answer continues to receive downvotes and I'm not entirely sure why (none of the downvoters seem to leave any comments). Through a fair amount of back and forth with the OP, we established that the entire point of this request/response was to perform validation. The server received the request, it performed the validation that it was requested to perform, and it returned the results of that validation process to the caller.

There was absolutely nothing wrong with the client sending this request.

The server understood the request.

The request was valid (from an HTTP perspective).

The server could process the request.

The server performed 100% of the activity it was meant to and is returning the results that are produced having processed the request.

And that is why, as I say, I do not believe that an HTTP error code is appropriate.

I.e. imagine that the server exposes an endpoint that validates email addresses (for whatever particular form you wish to say that validation can be performed). It receives a request saying "validate abc@invalid.org" and it produces a response saying "I took a look at this email address and I'd like you to tell the user that I can't get a valid DNS response for invalid.org". If people don't think a 200 response is correct here, I'd love to understand their reasoning.

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
  • 15
    -1 `403 Forbidden The server understood the request, but is refusing to fulfill it.` and `410 Gone The requested resource is no longer available at the server and no forwarding address is known.` are two errors where the request was well formed and correctly processed. – user247702 Feb 27 '13 at 15:55
  • 1
    Also, how would you differentiate between *data has been saved* and *data is invalid*? Reading the content would make the usage of status codes pointless. There are tons of discussions about this for REST APIs, and so far I haven't seen any that suggest returning `200 OK`. – user247702 Feb 27 '13 at 16:03
  • 5
    @Stijn - From my reading of the original question, this wasn't Validation being performed prior to performing further processing of them within the same operation. This service (endpoint) has one purpose - "please run some validation for me". If it *has* run the validation (no matter what the outcome) it has completed all of the work it was intended to do. It is *not* refusing service, so 403 seems wrong. – Damien_The_Unbeliever Feb 27 '13 at 17:22
  • 1
    I wasn't suggesting to use 403 for this, merely giving examples that don't match your statement. Apologies for the confusion. – user247702 Feb 27 '13 at 22:43
  • 2
    409 is another situation where the data are valid and processed, but the action was rejected. In this case, we are wanting to know if it is safe to proceed. I'd probably prefer to perform the desired action, and then return errors if it could not be completed, but it is necessary to indicate after changes leading up to the 'final' action if we are ready to perform said action. – Matthew Schinckel Jun 21 '13 at 00:58
  • FWIW I've removed my downvote on this.I don't know how, but I misunderstood the original question even with your explanation in the comment. Perhaps I was too focused on my own use case at the time. My apologies for that. – user247702 Mar 27 '15 at 16:29
  • @Stijn - appreciated. – Damien_The_Unbeliever Mar 27 '15 at 17:01
  • I haven't dvoted but "*You've sent a request to the server for it to perform validation. It has successfully performed said validation*" No I sent a request to save a form, get some data, update some data, etc. Validation is not the issue of the REST it's an issue in an application or its data. If I send a request to save some data (POST, PUT, etc) and said data was NOT saved, that is not a 200 response. The response code is about the intent of the request. This said, so much subjectivity in all of this, hence no dvote from me. – James Oct 13 '19 at 18:18
12

While it is defined in a proposed standard still, 422 Unprocessable Entity is an appropriate status.

The 422 (Unprocessable Entity) status code means the server understands the content type of the request entity (hence a 415(Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a 400 (Bad Request) status code is inappropriate) but was unable to process the contained instructions.

For example, this error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.

References:

Community
  • 1
  • 1
user247702
  • 23,641
  • 15
  • 110
  • 157
  • 1
    I think you missed the part where the *entire* purpose of the call is to perform validation. In such a case, indicating errors (when the request was well formed and we could perform the requested validation) seems wrong. – Damien_The_Unbeliever Feb 27 '13 at 20:06
  • @Damien_The_Unbeliever I still don't think returning 200 when there are validation errors is a good way to do this. You'd still need to parse the content to find out if the validation was successful or not. – user247702 Feb 27 '13 at 22:46
  • @Stijn Yes, that was my concern. However, the request itself succeeded: it's just that it was invalid. – Matthew Schinckel Feb 27 '13 at 23:06
0

If the state of your HTTP resource is somewhere "between start and finish" to paraphrase your words on this admittedly older question, I would like to put a vote in for returning status 202. It has the advantage of being a 2-- "success" type response so a dumber client will not consider it a broken page, and its stated purpose in the HTTP 1.1 spec sounds like what you want (though many of the status code definitions are very ambiguous).

Specification Link

Excerpt:

202 Accepted

The request has been accepted for processing, but the processing has not been 
completed. The request might or might not eventually be acted upon, as it 
might be disallowed when processing actually takes place...

The 202 response is intentionally non-committal. Its purpose is to allow a server 
to accept a request for some other process (perhaps a batch-oriented process 
that is only run once per day) without requiring that the user agent's 
connection to the server persist until the process is completed. The entity 
returned with this response SHOULD include an indication of the request's 
current status and either a pointer to a status monitor or some estimate of 
when the user can expect the request to be fulfilled.
welegan
  • 3,013
  • 3
  • 15
  • 20
  • The second paragraph of your quote is what steers me away from `202`. It is known if validation passed or succeeded. The crux of the question is that the request was successful, it's just that the answer to the question asked by the request was 'validation failed' (or passed). – Matthew Schinckel Jun 21 '13 at 00:55
0

As is often the case it's hard to advise precisely without knowing exactly what you are doing, how, and why etc. For example:

I have a service where some validation rules must be checked before a particular operation should be able to take place.

Is this service serving local code? If so you should throw an exception to local code or return something normal.
Is it tied to an API request? If so on face value I can't see why you'd validate on a separate REST call rather than doing it all in one request.

However, an individual client may not have all of the required information (that user may only be able to access a subset of the data that is used to determine validation success), so a request must be sent to the server: basically "is a thing valid between start and finish".

I'm making assumptions for example's sake, but eg you can just let them make the request which they would if they had all the necessary data etc, and validate at that point.

The response will either be some sort of token that indicates VALID: FEEL FREE TO CONTINUE, or a list of validation failure reasons, that can be presented to the user.

This is why I'm suggesting what I have, as your above reads like the requirement is:

  1. Send request to API, API performs Validation and returns a response;
  2. If response shows valid then user sends the next response to do the actual thing;
  3. If response shows invalid then user has to do something and retry until they get a valid response then they still have to do the actual thing;

Alternative:

  1. Send request to API, perform validation, if valid do the thing, else return response indicating invalid state;
  2. User makes changes and again just has one request to send to do validation and the actual thing;

Note: the action performed is not being performed on the server, so skipping this check, and just attempting the action, with a 403 in the case of the action being forbidden is not an option.

If this isn't any kind pf remote/API request then I would suggest not using HTTP codes. Is this just all done within the same codebase? If so exceptions or bools etc from your validation to serve a message to the user.

James
  • 4,644
  • 5
  • 37
  • 48
-1

I think as long as you aren't misusing a code for something it was not intended then it really comes down to preference and opinion. A 409 is probably ok to use for validation failure although I think I personally would prefer a 200 with the validation error as a response. I think this makes it easier for developers to check for the common communication errors such as 401 or 500 and deal with them before they have to worry about validating the data they sent.

sanpaco
  • 785
  • 1
  • 14
  • 32
  • 5
    I don't _quite_ totally agree. `409` implies (to me) that we communicated fine with the server: but our request would have caused invalid data to be stored (for instance). However, in this case, I agree that `200 OK` should be returned, as the validation request was handled ok. – Matthew Schinckel Jun 21 '13 at 00:57
  • In general its best to handle errors that are not HTTP communication errors with a HTTP 200 and some kind of error code in the response. Otherwise the client is likely to misinterpret your response as a problem with your servers. – sanpaco Dec 22 '14 at 16:58
  • 1
    Sending back a 409 when data was well formed, but fails business logic checks fails your tests. It's clearly not a communication failure, but an error in validation. I think in this case the response _should_ indeed be a 200, but IMHO your blanket statement is misleading. – Matthew Schinckel Jan 05 '15 at 03:56
  • Fair enough, in fact, the more that I think about it, a 409 response is probably just fine to use as a validation failure. I think it really comes down to opinion and as long as your are consistent and have good documentation you can go either way. – sanpaco Jul 10 '15 at 21:15