in put mapping (we use if more than one filed needs to be updated by user ) but concern is i am using dto class in that i am using validation annotations like size future and notnull when user needs to create we need to validate all the fileds so my logic works but incase of put mapping user can update two flieds or 4 flieds more than one for sure in this case how to handle ??? if user doesnt enter some filelds i am getting validation exception because validation annotion is applied for all the fields so in case of update i need to handle validation manually ? pl provide any solution bro @dburyak do i need to create seperatedto class for update and check manually if user enterd or not if entered validate that filed or any other way ?
guys pl provide input on this
Maybe you can prepare a dto with the existing data then update the entered values from api call and finally try to validate the dto This way the previous data will remain and new values will be validated
Firstly, there's a huge confusion in rest standard, and you also falling into it. No worries, most of engineers confuse these. There are semantically two type of "updates" - "replace existing" and "update provided fields only". Rest defines that "PUT" http method should be used for *replace* kind of updates. I.e. whatever you provide in PUT body is supposed to entirely overwrite the existing entity, except identifiers, maybe leaving only metadata fields like "createdAt", "lastUpdated", etc. So, what you're trying to do is supposed to be under "PATCH" http method. Summary: - POST - create new - PUT - replace existing - PATCH - update only provided fields of existing Now regarding the question itself. There's no nice solution to this, you either need: - if you'd like to use validation annotations, you need have two separate DTOs, one for create/replace, another for patch - if you'd like to stick with single DTO, then you need to do validation manually, and have 2 separate validators - for create/replace and another for patch I solved it nicely with MapStruct recently by the way, let me dig it, and come back
This will work. But it's more error prone as now you have bunch of fragile code - objects merging that depends on field names. Any time something changes in rest DTOs, you need to update this merging code. Also this will add an unnecessary DB call. Instead of having a single "update", this way you always have to do select + update. Besides those downsides, this is quite a good approach.
Ok, I found what I had in memory, and unfortunately it's not about validations. It's about json views. https://reflectoring.io/jackson-jsonview-tutorial/ This allows to have same DTO, but mark which fields are for read, which are for replace and which for update. for example: class SomeDto { @JsonView({SUMMARY.class, READ.class}) UUID id; @JsonView({SUMMARY.class, READ.class, UPDATE.class}) State state; @JsonView({READ.class, CREATE.class, UPDATE.class}) Double rate; @JsonView({SUMMARY.class, READ.class}) Duration duration; .... Here I have two separate GET endpoints, one is "brief" (summary), which returns less information. And another is a classic "read", which returns full information. This way it's easy to work with DTOs, you just mark which fields are redable, which updatable, which can be specified only in create, etc. In your case if you'd like to support partial updates (patching), I highly recommend to not use the word "update", but to go with "replace" and "patch" to avoid that typical confusion that I explained above. And I used manual validators https://docs.spring.io/spring-framework/reference/core/validation/validator.html Separate validators for each DTO, separate validator for create, separate for patch. Validator for create requires all non-nullable fields. For patch - validates only fields with non-empty data. And all the repeated logic (like phone numbers validation, emails) can be moved to abstract class, so there won't be duplication. This is an approach that I prefer. Benefits: - one DTO, that is easy to work with - no extra DB call required - no fragile code, no manual objects merging, etc. downsides: - manual validators - even though they are typically very simple to implement, it's just boring repetitive plumbing work - manual invocation of validators, you have to not forget to call validator as your first action in the controller
I've just googled a little bit, and found this. This is perfect!!! Seems to be a mechanism exactly for the job: https://www.baeldung.com/javax-validation-groups Called "validation groups".
Обсуждают сегодня