Aws lambda json deserilisation provides default values for missing properties - java

hey I have a function in lambda with spring cloud functions that takes a dataobject as a input param say (InputObj).
The lambda is triggered via an api gateway.
The problem is if I leave out some properties of the InputObj and send a request. I get a default value for those missing properties.
What I would need is something like a 400 bad request error to be thrown unless the user provide all properties of the InputObj.
how can i go about doing it.

I say the simplest way to do that is to:
Not have default values. What's the point of having them if you are saying they are not valid.
Have the getter for the property to throw an exception if such property was not set. This way it will fail during serialization resulting in bad HTTP response

Related

What to return to from a REST API when updates fail

I am writing a web application using Spring Boot that frequently updates data on the back end and returns the updated object to reflect the update on the front end.
The question I have is what to return from my methods if the update should fail for some reason.
I am currently returning the object as it was received should it fail but as it stands the state on the front end would not reflect the failure on the back end in the case that it occurs.
I want to return the object to update the state but doing so prevents me from returning a String or HttpStatus indicating a problem doesn't it? Returning the old object doesn't seem a good solution either.
You can throw an exception in this case of failure from your REST controller.
To handle this exception, Spring provides ResponseEntityExceptionHandler callback class with the help of which you can handle the thrown exception and set different headers in the response entity.
So on client-side, you can recognise that some failure is occurred on server side.
You can set HttpStatus as HttpStatus.INTERNAL_SERVER_ERROR and add more details in the body.
The question I have is what to return from my methods if the update should fail for some reason.
You first need to determine whether the error was caused by the client or by the server, then you can determine the most suitable status code to be returned, either in the 4xx or in the 5xx range. See this answer which may give you some insights.
Instead of returning the request request back in the response, you should return a payload that describes what the problem was. Consider, for example, the payload defined in the RFC 7807 along with the application/problem+json media type.
Finally, this answer may give you insights on how to map an exception to a HTTP status code in Spring:
You can map exceptions to responses by annotating an exception class with #ResponseStatus.
It also gives you the possibility to implement a HandlerExceptionResolver or extend one of the existing implementations, such as the AbstractHandlerExceptionResolver.
Another approach would be using a ResponseEntityExceptionHandler annotated with #ControllerAdvice and define the handled exceptions by annotating the implemented method with #ExceptionHandler.

Is any additional attributes required to force the java type in spring integration

We are using spring-integation (xml based configuration), In which we are performing below steps
Convert the payload (java-object) to json
Make the rest api call
Convert back to java-object
<int:object-to-json-transformer content-type="test.Request" input-channel="objectToJsonChannel" output-channel="apiChannel"/>
<int-http:outbound-gateway id="apiChannel"
request-channel="apiChannel"
reply-channel="jsonToObjectChannel"
....
/>
<int:json-to-object-transformer type="test.Response" input-channel="jsonToObjectChannel" output-channel="responseChannel"/>
Above code works till spring-integration version 5.1. When I upgrade to 5.2. It starts to throw the exception as
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [test.Request] to type [test.Response].
I have noticed that object-to-json-transformer add class type on the header with key json__TypeId__. Then it uses that class type for json-to-object-transformer.
But it is expected that type attribute mentioned on json-to-object-transformer should be used if mentioned.
Please suggest on fixing this issue or Is it really bug on spring integration (5.2).
Consider to add a <header-filter header-names="json_*" /> before calling your REST service. The <int:object-to-json-transformer> populates JsonHeaders to let downstream to know what the real type of JSON we curry in the payload.
A <int:json-to-object-transformer> prefers those headers instead of static type option.
But since the payload is already a different representation than those request headers it does a wrong thing.
I would suggest an option on the <int:json-to-object-transformer> to make a preference, but that would not be fully logical. Since we have changed a payload, it would be better to change its respective headers. Otherwise we just lying to ourselves.
On the other hand a HTTP Outbound Gateway can take care for your to convert request into a JSON for network and back from JSON response to some POJO type.
See https://docs.spring.io/spring-integration/docs/5.2.3.RELEASE/reference/html/http.html#http-outbound and its expected-response-type. As long as a contentType header is an application/json, you are good to avoid those <int:object-to-json-transformer> & <int:json-to-object-transformer>.

Spring Data REST Bean Validation

Consider a Person entity with a property name that is annotated as #NotNull. Then a simple PersonRepository and this repo exposed with Spring Data Rest.
When I POST to create a new Person, if the name property is null a ValidationException occurs as expected. But what I actually get on the client is an Internal Server Error (500) and the message is a TransactionSystemException that happened much later in the exception chain.
What I'd expect to get is a Bad Request (400) with the actual ValidationException and all it's useful information so the client can know what's wrong with the posted data.
There seems to be a way to attach custom validators with SDR as explained here. But the thing is, this is not a custom validator, it's a standard bean validation that happens when the repository is asked to save data. So I'm not really sure how those two come together.
So questions:
What are my options to let the client know what's wrong with the submitted data when using SDR?. Things like what fields are invalid and what's the error for each field would be awesome.
Are there any examples about this anywhere?
Thanks a lot.
What you need is a proper ExceptionHandler, it will handle back end exceptions and send meaningful rich messages (json/xml) to the front end client.
Take a look a this git repository

Getting information out of ConstraintViolationException - Jersey

I'm using Jersey 2.19 to implement a REST API.
I enabled ServerProperties.BV_SEND_ERROR_IN_RESPONSE to transform ConstraintViolationException into validation errors. This is working. In addition to the response code I get some text in the response that looks like:
Parameter value must be 'true' or 'false' (path = MyResource.m_myParam, invalidValue = invalid).
I have also created a custom exception mapper to map ConstraintViolationExceptions to a particular HTTP response code of my choosing.
This is also working.
However, I note that the additional information is no longer present int he response. If I call getMessage on the exception it returns null.
How do I get access to the same information in my mapper?
Just call ConstraintViolationException.getConstraintViolations() which will return a Set<ConstraintViolation>. Take a look at the ConstraintViolation API to see all the information you have access to.
The particular message you are showings is a String built from information obtained through getMessage(), getPropertyPath(), and getInvalidValue() of the ConstraintViolation

Put Rest webservices with just one parameter

I am using Java and Jersey for my REST web services. I want to have a put method that takes just one integer value. From this integer value I can then use business logic to update my database. Usually I am passing a custom DTO from my PUT as they often contain more than one piece of information. It seems a bit wasteful creating a custom DTO for just one value. Is it possible to pass this variable as a #PathParam with a PUT
I have tried
#PUT
#Path("apple/{pearId}")
public void doStuff(#PathParam("pearId") Integer pearId) {...}
but this does not work if I pass in
http://myurl/apple/123
I tried using REST client to PUT this but end up with a HTTP Status 403
Can I pass a variable as a PUT #PathParam?
Thanks
UPDATE: more details on error
The error is from REST Client
HTTP Status 403 -
type Status report
message
descriptionAccess to the specified resource () has been forbidden
I will add logging now to see if I actually get into the method
You can definitely use #PathParam with a PUT. HTTP 403 means Forbidden. This error is probably not coming from Jersey. Where is that error coming from? Does your code throw that error?

Categories