Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support @Validated validation groups #510

Closed
Briggybros opened this issue Mar 26, 2020 · 5 comments
Closed

Support @Validated validation groups #510

Briggybros opened this issue Mar 26, 2020 · 5 comments

Comments

@Briggybros
Copy link

Is your feature request related to a problem? Please describe.
Using one request object for PUT and PATCH methods and using @Validated annotation with validation groups should respect the validation of the group.

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("controller")
public class Controller {
  @PutMapping
  public void put(@RequestBody @Validated(Request.PUT.class) Request request) {}

  @PatchMapping
  public void patch(@RequestBody @Validated(Request.PATCH.class) Request request) {}
}
import javax.validation.constraints.NotNull;


public class Request {
  @NotNull(groups = {PUT.class}) public String name;

  interface PUT {}

  interface PATCH {}
}

Generates: irrelevant parts omitted for brevity

{
    "openapi": "3.0.1",
    "info": {},
    "servers": [],
    "paths": {
        "/controller": {
            "put": {
                "tags": [
                    "controller"
                ],
                "operationId": "put",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Request"
                            }
                        }
                    }
                },
                "responses": {}
            },
            "patch": {
                "tags": [
                    "controller"
                ],
                "operationId": "patch",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Request"
                            }
                        }
                    }
                },
                "responses": {}
            }
        }
    },
    "components": {
        "schemas": {
            "Request": {
                "required": [
                    "name"
                ],
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string"
                    }
                }
            }
        }
    }
}

Describe the solution you'd like
In the above example the patch route should have name as an optional parameter, not required

Something like:

{
    "openapi": "3.0.1",
    "info": {},
    "servers": [],
    "paths": {
        "/controller": {
            "put": {
                "tags": [
                    "controller"
                ],
                "operationId": "put",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Request_PUT"
                            }
                        }
                    }
                },
                "responses": {}
            },
            "patch": {
                "tags": [
                    "controller"
                ],
                "operationId": "patch",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Request_PATCH"
                            }
                        }
                    }
                },
                "responses": {}
            }
        }
    },
    "components": {
        "schemas": {
            "Request_PUT": {
                "required": [
                    "name"
                ],
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string"
                    }
                }
            },
            "Request_PATCH": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string"
                    }
                }
            }
        }
    }
}

Describe alternatives you've considered
Obvious alternative is different request objects. Though this is annoyingly verbose for the above case.

@bnasslahsen
Copy link
Contributor

@Briggybros,

You can achieve your expected OpenAPI description, by using @RequestBody or @Parameter annotation.
The feature you are asking will not be supported in short term.
You can contribute, if you estimate its useful for the community.

@omarAbdelhadyok
Copy link

Can you provide an example on how to achieve this using @RequestBody or @Parameter?

@bensaufley
Copy link

Always the worst to stumble on a thread that is asking for exactly what you need and the last comment is a question that's a year old 😞. @omarAbdelhadyok did you solve your use case?

@Briggybros
Copy link
Author

@bensaufley A method like this might help:

@RestController
@RequestMapping("controller")
public class Controller {
    @PutMapping
    public void put(
            @RequestBody
            @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    content = @Content(
                            schema = @Schema(
                                    // See https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Annotations#schema
                                    implementation = Request.class,
                                    requiredProperties = {"name"}
                            )
                    )
            )
            @Validated(Request.PUT.class) Request request
    ) {}

    @PatchMapping
    public void patch(
            @RequestBody
            @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    content = @Content(
                            schema = @Schema(
                                    // See https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Annotations#schema
                                    implementation = Request.class,
                                    requiredProperties = {}
                            )
                    )
            )
            @Validated(Request.PATCH.class) Request request
    ) {}
}

As with the original issue, this is still not DRY..

@Showleen
Copy link

plan support it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants