So, I have created a Controller within which I have a POST endpoint like so:
@PostMapping("/foo/{some-field}")
public CompletableFuture<ResponseEntity> foo() {
//Do some operations...
...
if(doesNotExist({some-field})) {
return CompletableFuture.completedFuture(ResponseEntity.notFound().build());
}
return CompletableFuture.completedFuture(ResponseEntity.ok().build());
}
Now I would expect that if doesNotExist({some-field}) == true
, I'd be prompted with a NOT_FOUND
status.
I however end up with a OK
status every time around.
Are my expectations wrong in regards to how the ResponseEntity
is returned?
Any suggestions how to get the NOT_FOUND
status if doesNotExist({some-field}) == true
would be much appreciated.
From the comments I assume my initial question was a little to light, so let me explain when I see this failing, as it seems that my assumption of what the ResponseEntity.HttpStatus
would be is correct.
I have made small adjustments to the code block above.
The situation where I receive an unexpected status is when I try to test the NOT_FOUND
situation through Spring Cloud Contracts.
An example of the contract looks as follows:
Contract.make {
request {
method 'POST'
url "/foo/SomeNoneExistingField"
body("{}")
headers {
contentType applicationJson()
}
}
response {
status HttpStatus.NOT_FOUND.value()
}
}
So the {some-field}
in this contract is set to a field which ensure that doesNotExist({some-field}) == true
. I see it end up in this block if I am debugging my code as well.
Nonetheless, the Spring Cloud Contract test status that the response.status == OK
i.o. NOT_FOUND
.
Might I be using Spring Cloud Contracts incorrectly if my assumption on the HttpStatus
returned from a CompletableFuture
is correct?
Any help/advice is (again) much appreciated.
Ok, I figured out the issue I was experiencing. Credits to @Marcin Grzejszczak for putting me on the right track in regards to configuration.
What I was missing from my contracts to be able to handle async results, like a CompletableFuture
, was that I needed to add async()
to my result.
Thus, a contract like so:
Contract.make {
request {
method 'POST'
url "/foo/SomeNoneExistingField"
body("{}")
headers {
contentType applicationJson()
}
}
response {
status HttpStatus.NOT_FOUND.value()
async() // <---- This was it!
}
}
Did the trick.