1

I have the following request.

@Data
public class ProductRequest {
    @NotEmpty
    private String code;

    @NotEmpty
    private String name;
}

I use this request for 2 different methods and both of them use only one field, not need the other field. Let's say that methodA using code and methodB using name field in this request (not need other field). So, in this scene I think a solution for using the same request for both methods, instead of creating 2 separate request. So, is there anything that make it possible one of the field is not null? I am also not sure if it solves my problem, because in this scene request will not know which property should not be null. Any idea to fix this problem?

2 Answers2

0
  1. You can do it with a custom validator (spring, code validation, no javax.)

  2. With javax.validation:

    • Groups sound like a perfect match for your scenario.
    • of course also achievable with a Custom Constraint. (similar to 1.)

    Drawback: you'll have to deal with your "validation structure" (@Valid vs @validated/how to pass the group)

  3. ...

xerx593
  • 12,237
  • 5
  • 33
  • 64
  • Thanks a lot for your explanations. I have a look at these pages, but I am not sure if they exactly help me for my situation. Because, as you know, my request should also need to know which field should be not null. So, if you think it is possible, could you pls post an example implementation for this request above as an update to your answer? –  Nov 12 '21 at 17:34
  • By the way I could not see a proper example r definition for javax.validation Group on the page you referred. –  Nov 12 '21 at 20:10
0

You could group your constraints so that you can tell which properties to be validated in each case. The first step is to add the attribute groups to your javax validation annotations. For that you need to create some marker interfaces, one for each of your use cases:

public interface MethodA { } // You should name this properly, it is just for demonstration purposes

public interface MethodB { }

Then you need to configure the groups attribute in your annotations:

@Data
public class ProductRequest {
    @NotEmpty(groups = MethodA.class)
    private String code;

    @NotEmpty(groups = MethodB.class)
    private String name;
}

The final step is the usage of @Validated instead of @Valid to trigger data validation. Something along the following lines:

@RequestMapping(value = "/methodA", method = RequestMethod.POST)
public String methodA(@Validated(MethodA.class) @RequestBody ProductRequest productRequest) {
    (...)
}

@RequestMapping(value = "/methodB", method = RequestMethod.POST)
public String methodB(@Validated(MethodB.class) @RequestBody ProductRequest productRequest) {
    (...)
}

You can read more about this in the following online resources:

João Dias
  • 16,277
  • 6
  • 33
  • 45
  • Not tested yet, but seems a proper approach. ON the other hand, I think it may be good idea to use a single property and pass it via `@PathVariable @NotNull String name` instead of using a Request class. Is that true? –  Nov 15 '21 at 06:37
  • It depends on what you are trying to do in the POST method and what does that `name` mean. What is your intent? – João Dias Nov 15 '21 at 10:23
  • I am trying to update name field. –  Nov 15 '21 at 14:20
  • Then you shouldn't do it you a path variable. Your REST resource is `Product` and you should use a `PATCH` request to update its `name` attribute providing it the request body. – João Dias Nov 15 '21 at 14:24
  • What about using name parameter in the request? SHould I use Request class for that rather than parameters except from id or uuid? –  Nov 15 '21 at 14:25
  • Now I am not following you. I would suggest you create a new question with all the details since we are drifting a bit on the topic itself. Add the link here as a comment so that I can check it. Thanks! ;) – João Dias Nov 15 '21 at 15:07
  • No need to follow, you may just reply my comment –  Nov 15 '21 at 15:46
  • And as a consequence, you removed my answer which is correct as accepted. I don't think that is the spirit we are looking forward to here at StackOverflow but ok. The question is that I can't reply to your comment because I don't understand what you are trying to ask. There is no `id` or `uuid` in your question, so I don't know what you are talking about. It may make sense to you but it does not to us. And again, changing the scope of a question after it was already correctly answered is not something you should do, otherwise, no question will have an end. – João Dias Nov 15 '21 at 15:54
  • @Henry, if you want me to help you, I need you to give me more details of what is now your issue. The best way to do this is by creating a new question on which you can describe the problem clearly instead of being restricted by the number of characters of a comment. So please do it and post here the link to the question. I will take a look. Then, accept again my answer so that this question can be "closed" again. Thanks! – João Dias Nov 15 '21 at 22:37
  • Marked as answer and voted up, thanks a lot for your valuable helps. –  Nov 16 '21 at 05:14
  • What about my other question on the other thread? –  Nov 16 '21 at 10:47
  • I will have a look. – João Dias Nov 16 '21 at 11:00