Validation of multiple response codes - citrus-framework

I have to use a REST api that creates a user. This api returns response code 201 (accepted), 409 (user already exists) or some other code in case something went wrong. I want to validate that the received response code is either 201 or 409 (and not something else).
Now my code only checks one of these response codes:
http()
.client(AddUserClient)
.receive()
.response(HttpStatus.CONFLICT)
Is it possible to change this, so both values results in an OK-test?
Cheers,
Ed

The Citrus Http Java fluent API does not support this kind of validation at the moment. I will add this as soon as possible, thanks for the hint!
In the meantime you will need to use the default receive fluent API for this special operation:
receive(AddUserClient)
.payload(...)
.header(HttpMessageHeaders.HTTP_STATUS_CODE, "#assertThat(anyOf(is(200), is(409)))#")
.header(HttpMessageHeaders.HTTP_VERSION, "HTTP/1.1");
You can combine Http fluent API and default fluent API in a Citrus test case without limitations.

Related

How to define a boolean API RESTful?

I have to define an API that answers whether a resource with given ID can be created, like
Can I (caller) create this resource with id=resource1 ?
The possible responses could be
401 - The caller is not authenticated
403 - The caller is authenticated but not authorized to perform this check
200 - Yes, you can create a resource with id=resource1
...
Now my questions are
How can I model the API?
Will, GET /resources/resource1 be a good choice?
What HTTP codes will suite for responses like,
(a) this resource id is already taken, (b) you don't have permission to create this particular id (but only few other ids), (c) you can create this id.
An example in github may help you.
The api designed for checking if a user is following another user:
GET /user/following/:username
The deal information is presented in github's api document
For your question1, I think you can implement like this:
GET /resource/existence/:resource_id
For question2, you may also take a look at github's client errors
Would it be better to just try and create the resource with a POST? and let your implementation handle the response from there? In which case your responses could be:
a) 409: Conflict
b) 401: Unauthorized
c) 200: OK
If that's not possible, then I guess your payload response from a GET can contain the result. Something as simple as:
true: You can create the resource
false: You cannot create the resource
Since you want to check the permissions regarding the addition, you should use a different resource than the one that actually added the element. IMO something like /permissions/{elementName}?id=theid or /permissions/{elementName}/{operationName}?id=theid. Accessing it with method GET would suit.
Using the same resource would be a bit "messy" I think since I would expect the method GET on /resources/resource1 to actually return the content of the element with identifier ressource1.
Regarding the response, I would see this:
401 if the user isn't authentication and the permission resource requires an authentication.
204 if the current user is allowed to add an element with the specified identifier. I don't think that you need a response payload in this case.
Regarding the case when the user isn't allowed to add an element with the provided identifier, I think the status code 403 (Forbidden) suits. Perhaps a status code 400 could also match if you consider that the user provides a wrong content. In this case some hints about the error (identifier value not allowed) should be returned within the response payload.
For me, the status code 409 (Conflict) is more when implementing optimistic locking, i.e. concurrent accesses (updates) on the same element.
Hope it will help you,
Thierry

HTTP Status codes confusion

So, I am trying to display meaningful and accurate HTTP status codes and I'm getting confused even after going through the examples online. Here's my situation:
In the URL which accepts the query param:
#POST query
Sample URL: /putRecord?Name=A&Age=25&house=permanent
what status code do i return when one of the params is missing? (All 3 are mandatory) - from what I've read, I am guessing it is a 400: Bad request. But this seems too general. Is there a way for me to say that the query was malformed? Source:here
Assuming I validate the name for duplicates against the DB, if I get a duplicate, what status code do I return?
So, if there's a duplicate entry available already, I can't add the record. Do I display 304 (Not modified) or just the error code from 2?
Clarification: For 3, another possibility is when I can't actually commit to the DB and I rollback(possibly). What status code will it be now?
Thanks so much!
Ad 1. You can return, besides the code itself (400) also a short message with explanation. So, instead of returing "400 Bad Request" you could respond with "400 Query param name required" or something similar. This message is called "reason phrase" and is defined in 6.1 in RFC 2616. Or, if you need more flexibility, you could return document with the explanation.
Ad 2. I would consider using 422 Unprocessable entity. From the RFC 4918:
The 422 (Unprocessable Entity) status code means the server understands the content type of the request entity, 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.
Ad 3. I would return 422, but it really depends whether this situation is considered an error in your logic, or is it a regular, expected situation.
Edit: As #War10ck suggested in the comment, HTTP 409 (in place of HTTP 422) might make sense as well.
Note on handling duplicates: it seems (correct me if I'm wrong) that you consider new entity being a duplicate if it's name is already in the database. If so, that you could maybe consider using a HTTP PUT instead of HTTP POST?
You could define the following resource:
HTTP PUT /record/:name
So, "name" would be a part of the URI. Then, in case there is a second PUT to the same resource (same "name"), it'd be elegant to respond with 409/422.
If you're using different key for unique constraint, modify the URI appropriately.
As a rule of thumb, POST is for situations where you can have multiple instances of a given resource, i.e.
HTTP POST /log ;; Because we have many logs
And PUT for situations where each resource is unique:
HTTP PUT /person/:name (or /person/:tax-number if :name isn't unique)
Also, note that I've renamed your resource from "putRecord" to "record" - PUT is a HTTP method, no reason to have it in URI as well.

What should a RESTful API POST/DELETE return in the body?

To follow and unfollow a person via a RESTful API, I have
POST /person/bob/follow
DELETE /person/bob/follow
What should these return in the body?
A collection of everyone you follow
The person you just followed / unfollowed
A status like { status: "ok" }
Nothing.
If you respond on errors using a HTTP server status, the status code does not say anything. If you respond with a 404 Not Found if there is no user Bob, or a 500 Internal Server Error if the database is broken, the only successful response you will ever get is OK. Users do not have to check the status code, they only have to check the HTTP status code.
I suggest you return nothing, and the fact that it is a successful response (i.e. 200 OK or 204 No Content) indicates that the operation was successful.
It all depends on your app/API design and the contract you are gonna define with the client/callers. But generally, in all the cases you should return status code to make your client aware of the result.
Like: respond(ResponseCode::OK, ...)
For POST: I'd return 'bob' object containing all of his followers + status code
For DELETE: I'd only return the status code.
Generally, for an API, I'm apologist to use the HTTP status codes instead of always OK with a code defined status.
This means that you can follow the existing standards for answers, and anyone who gets an error code will know roughly what happened/what they have to do.
Take a look at the wiki article http status codes for a usable reference manual.
Also, together with the error code, and because is an API we are talking about, it is useful to have a more descriptive message about the error. Something meaningful like error: "Auth token missing", or whatever standard you might come up with.
When it comes to creating resources, I generally answer back with 201 (Created) and the resource just created. Keep in mind that you might want to exclude some attributes from the resource (e.g. You're creating a user, you shouldn't return sensitive info such as the encrypted password)
Regarding the deletion of resources, generally return with either 200 (Ok) or 202 (Accepted) and no extra info.
Nevertheless, As #yek mentioned, it highly depends on the commitment with the API consumer. The most important thing is that you document the API decently and explain what should be the expectations.

Picking HTTP status codes for errors from REST-ful services

When a client invokes my REST-ful service, it needs to know if the response came back was 'from me' or rather a diagnosis from the containing web server that something awful happened.
One theory is that, if my code is called, it should always return an HTTP OK(=200), and any errors I've got to return should be just represented in the data I return. After all, it's my code that gets the response, not the naked browser.
Somewhat self-evidently, if I'm using REST to generate HTML read directly by a browser, I absolutely must return an error code if there's an error. In the case I care about, it's always Javascript or Java that is interpreting the entrails of the response.
Another possibility is that there is some family of HTTP status codes that I could return with a high confidence that it/they would never be generated by a problem in the surrounding container. Is this the case?
I use the following:
GET
200 OK
400 Bad Request (when input criteria not correct)
POST
202 Accepted (returned by authorization method)
401 Unauthorized (also returned by authorization)
201 Created (when creating a new resource; I also set the location header)
400 Bad Request (when data for creating new entity is invalid or transaction rollback)
PUT
Same as POST
201 Ok
400 Bad Request
DELETE
200 OK
404 Not Found (same as GET)
I would not know how to avoid that some container returns codes like 404.
4xx codes are meant to handle client errors along with possibly some entity that describes the problem in detail (and thus would mean a combination of both of your mentioned approaches). Since REST relies on HTTP and the according semantics of status as well as methods, always returning 200 in any possible case is a violation of this principle in my opinion.
If you for instance have a request such as http://foo.com/bar/123 which represents a bar ressource with id=123 and you return 200 with some content, the client has no chance to figure out if this was the intended response or some sort of error that occured. Therefore one should try to map error conditions to status codes as discussed in REST: Mapping application errors to HTTP Status codes for example.

When is it appropriate to respond with a HTTP 412 error?

It is unclear to me when you should and should not return a HTTP 412: Precondition Failed, error for a web service? I am thinking of using it when validating data. For example, if a client POST's XML data and that data is missing a required data element, then responding with a 412 and a description of the error.
Does that align with the spirit of responding with an HTTP 412, or should something else be used (e.g. another http error code or web application exception)?
If you look at RFC 2616 you'll see a number of request headers that can be used to apply conditions to a request:
If-Match
If-Modified-Since
If-None-Match
If-Range
If-Unmodified-Since
These headers contain 'preconditions', allowing the client to tell the server to only complete the request if certain conditions are met. For example, you use a PUT request to update the state of a resource, but you only want the PUT to be actioned if the resource has not been modified by someone else since your most recent GET.
The response status code 412 (Precondition Failed) is typically used when these preconditions fail.
Your example sounds like an invalid request (i.e. the client has submitted data that is invalid because of missing values). A status code of 400 (Bad Request) is more appropriate here IMO.
412 is reserved for cases where the request is conditional, and the condition isn't met.
For your use case, 422 Unprocessable Entity is a good match.
Your best bet would be to avoid 412. In practice most web services that I've used send a 400 code (Bad Request). A lot of frameworks have built-in support for 400 too and your clients will appreciate a more common error code. Often times, especially with REST interfaces, a simple "message" or "error" element is returned with a description.