Open sergey-morenets opened 1 year ago
Suppose we generate a Micronaut application (Java 17+Maven) with the following features: validation, serialization-jackson, lombok, http-client, then add these classes:
package org.acme.model;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
@Data
public class Product {
@NotEmpty
private String name;
private int id;
}
We add also a validated controller:
package org.acme;
import io.micronaut.http.annotation.Body;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Post;
import jakarta.validation.Valid;
import org.acme.model.Product;
@Controller("/product")
public class ProductsController {
@Post
public String addProduct(@Valid @Body Product product) {
return String.format("added product %s", product);
}
}
Start the application with mn:run
and issue a POST request in your favorite http client app:
POST http://localhost:8080/product
Content-Type: application/json
{
"id": 1000, "name": null
}
I have a few remarks:
BeanValidationConfiguration
class annotated with @SerdeImport
there will be an error stating
" No bean introspection available for type [class org.acme.model.Product]. Ensure the class is annotated with io.micronaut.core.annotation.Introspected""
So fixing the error should be straightforward: annotate the class with @Introspected
. Problem is, this time around we get another error:
"Internal Server Error: No deserializable introspection present for type: Product product. Consider adding Serdeable.Deserializable annotate to type Product product. Alternatively if you are not in control of the project's source code, you can use @SerdeImport(Product.class) to enable deserialization of this type."
When we use the annotation Serdeable.Deserializable
we get the expected output:
{
"_links": {
"self": [
{
"href": "/product",
"templated": false
}
]
},
"_embedded": {
"errors": [
{
"message": "product.name: must not be empty"
}
]
},
"message": "Bad Request"
}
Serdeable.Deserializable
, which brings me to the second point, using the @SerdeImport(Product.class)
annotation. This is what OP tried and I can confirm that if you use it, no extra annotations are required on Product
. This should come as unsurprising though, because the intented usage of @SerdeImport
is to introspect external classes (from a library that you do not own @sergey-morenets).The section 5 of Validation docs is indeed incorrect with respect to point 1 (it should have mentioned @Serdeable.Deserializable
instead of @Introspected
) and incomplete with respect to point 2 (a quick remark could be added there, that you don't need @Introspected
on your own classes if you choose to mark them via @SerdeImport
.)
Expected Behavior
Validation documentation shouldn't state that @Introspected annotation is required for validation.
Actual Behaviour
Current Micronaut Validation documentation (https://micronaut-projects.github.io/micronaut-validation/snapshot/guide/) states that:
To validate data classes, e.g. POJOs (typically used in JSON interchange), the class must be annotated with @Introspected (see Micronaut Guide Introspection section) or, if the class is external, be imported by the @Introspected annotation.
However that's not true as per Micronaut 4.1.4.
So here's our POJO:
And our configuration class:
So there's no @Introspected here (@SerdeImport is meta-annotation but doesn't contain it) however Jakarta Validation works which was confirmed by our tests.
Steps To Reproduce
No response
Environment Information
No response
Example Application
No response
Version
4.1.4