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

Automatically add required if a field is @notNull or @NotBlank #2817

Closed
lako12 opened this issue Dec 17, 2024 · 11 comments
Closed

Automatically add required if a field is @notNull or @NotBlank #2817

lako12 opened this issue Dec 17, 2024 · 11 comments
Labels
enhancement New feature or request

Comments

@lako12
Copy link

lako12 commented Dec 17, 2024

I have a project with Swagger 3, I noticed a different behavior compared to Swagger 2 and I think it's a bug because with a structure of a certain type, I can make the call to the API, but Swagger doesn't allow me to do it.

I have this API:

    @PostMapping(path = "/testOne", consumes = MediaType.APPLICATION_JSON_VALUE)
    ResponseEntity<String> testOne(@ParameterObject @Valid ClassOne test) {
        return ResponseEntity.ok("ok");
    }
@Data
public class ClassOne {

    @Valid
    private ClassTwo description;

}
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class ClassTwo {

    @NotNull
    private String name;
}

As you can see, ClassOne has an object with the @Valid annotation and I am not obliged to pass it (because maybe I want to pass other attributes that I have not added in this example). However, the @Valid annotation ensures that if I pass any attribute that is inside that class, then it must respect the rules that I indicate inside (@NotNull etc.). The problem is that on the swagger it says required, even if I do not indicate required and therefore I cannot make the call to the API. This is therefore a problem as I said before, because I may want to send other attributes of ClassOne.
This problem occurs only in the case of @PraameterObject, while if I use @RequestBody, it is not mandatory.

In my opinion swagger should not automatically add requird if an attribute has the annotation @NotNull or @NotBlank, it should refer to what the user indicates with the annotation @Schema

attached is a zip with an example.
demo.zip

@lako12 lako12 changed the title Aggiunge in automatico required se un campo è @notNull oppure @NotBlank Automatically add required if a field is @notNull or @NotBlank Dec 17, 2024
@bnasslahsen bnasslahsen added the enhancement New feature or request label Dec 29, 2024
@mc1arke
Copy link
Contributor

mc1arke commented Dec 30, 2024

@bnasslahsen This appears to have broken the fix for #2787 as it has returned to only considering the mandatory/optional status of a child field, and not whether the parent object is mandatory/optional. #2787 intended to prevent a field being shown as mandatory if its parent field was not mandatory in a @ParameterObject request, which is what was safeguarded in the app233 test that the fix for this has altered.

@bnasslahsen
Copy link
Collaborator

bnasslahsen commented Dec 30, 2024

@mc1arke,

It is expected. I have reviewed your PR, to only consider this behaviour for annotations on the child fields levels, and not on the parent Object level. There is no defined Java rules for that.

@mc1arke
Copy link
Contributor

mc1arke commented Dec 30, 2024

There is no defined Java rules for that

I'm not sure what you mean by this as it isn't a Java requirement, but a combinatorial logic problem. It may not be stated in a specification but is an implication of the process being followed, namely that in a collapsed structure, something being non-mandatory immediately implies that all child elements are non-mandatory, even if they are directly specified as mandatory.

If it helps, consider the same scenario for 'hidden' fields: a child field cannot be made visible in a collapsed structure if the parent field isn't visible. We have the convenience of being able to short-circuit any further processing on hidden fields but would need to continue processing in the case of the mandatory/non-mandatory status, but would need to end up with a similar outcome.

I think this issue is actually pointing out the same problem as I'd raised in the Mandatory parameters in non-mandatory parent fields section of my original issue.

@bnasslahsen
Copy link
Collaborator

bnasslahsen commented Dec 30, 2024

@mc1arke,

The problem is in your combinatorial logic.

From the Java point of view, there is no relation between the method parameters annotations and the exploded parameters definitions.
Ideally, after breaking exploding fields parameters, we can only think about preserving the fields annotations.

@mc1arke
Copy link
Contributor

mc1arke commented Dec 30, 2024

From the Java point of view they are still required (under certain circumstances) and the validator will enforce that.

Your example swagger shows the following error if an attempt is made to not specify schemaNotRequiredNestedParameterObject or any of its child fields:
image

However if you execute an actual request to that endpoint without specifying schemaNotRequiredNestedParameterObject.requiredParameterField then you get a successful response, so what swagger is claiming versus what the application actually does is different:

$ curl -v 'http://localhost:9099/optional-parent?nestedNonNullParameterObject.requiredParameterField=test1&nestedNotBlankParameterObject.requiredParameterField=test2'
* Host localhost:9099 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:9099...
* Connected to localhost (::1) port 9099
> GET /optional-parent?nestedNonNullParameterObject.requiredParameterField=test1&nestedNotBlankParameterObject.requiredParameterField=test2 HTTP/1.1
> Host: localhost:9099
> User-Agent: curl/8.7.1
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 200 
< Content-Length: 0
< Date: Mon, 30 Dec 2024 15:26:09 GMT
< 

Conversely, attempting the same request but not specifying nestedNonNullParameterObject.requiredParameterField results in a validation error, so we can prove that the validation is being enforced:

$ curl -v 'http://localhost:9099/optional-parent?schemaNotRequiredNestedParameterObject.requiredParameterField=test1&nestedNotBlankParameterObject.requiredParameterField=test2'
* Host localhost:9099 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:9099...
* Connected to localhost (::1) port 9099
> GET /optional-parent?schemaNotRequiredNestedParameterObject.requiredParameterField=test1&nestedNotBlankParameterObject.requiredParameterField=test2 HTTP/1.1
> Host: localhost:9099
> User-Agent: curl/8.7.1
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 400 
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Mon, 30 Dec 2024 15:29:30 GMT
< Connection: close
< 
* Closing connection
{"timestamp":"2024-12-30T15:29:30.224+00:00","status":400,"error":"Bad Request","path":"/optional-parent"}
[http-nio-9099-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public void com.github.mc1arke.springdoctest.ParameterController.nestedParameterObjectWithOptionalParentField(com.github.mc1arke.springdoctest.ParameterController$ParameterObjectWithOptionalField): [Field error in object 'parameterObjectWithOptionalField' on field 'nestedNonNullParameterObject': rejected value [null]; codes [NotNull.parameterObjectWithOptionalField.nestedNonNullParameterObject,NotNull.nestedNonNullParameterObject,NotNull.com.github.mc1arke.springdoctest.ParameterController$NestedNonNullParameterObject,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [parameterObjectWithOptionalField.nestedNonNullParameterObject,nestedNonNullParameterObject]; arguments []; default message [nestedNonNullParameterObject]]; default message [must not be null]] ]

For visiblity, the above was performed using the following controller and models

package com.github.mc1arke.springdoctest;

import org.springdoc.core.annotations.ParameterObject;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

@RestController
public class ParameterController {

    @GetMapping("/optional-parent")
    public void nestedParameterObjectWithOptionalParentField(@Valid @ParameterObject ParameterObjectWithOptionalField parameters) {

    }

    public record ParameterObjectWithOptionalField(
        NestedRequiredParameterObject schemaNotRequiredNestedParameterObject,
        @NotNull NestedNonNullParameterObject nestedNonNullParameterObject,
        @NotNull NestedNotBlankParameterObject nestedNotBlankParameterObject
    ) {

    }

    public record NestedRequiredParameterObject(
        @Schema(requiredMode = Schema.RequiredMode.REQUIRED) String requiredParameterField) {
    }

    public record NestedNonNullParameterObject(
        @NotNull String requiredParameterField) {
    }

    public record NestedNotBlankParameterObject(
        @NotBlank String requiredParameterField) {
    }


}

@bnasslahsen
Copy link
Collaborator

bnasslahsen commented Dec 30, 2024

@mc1arke,

I have reverted all the changes from your PR, from what i see, not all the use cases are well descibed.
I agree, with the second samples you provided, but they are not enough to accept the PR.

We need to have a formal expected test cases, something similar to the following:

ParamObj-
Schema/Param
ParamObj-
NotNull/Blank
NestedField-
Schema/Param
NestedField-
NotNull/Blank
Resulting
Required
true true true true true
true true true false true
true true true none true
true true false true true
true true false false true
true true false none true
true true none true true
true true none false true
true true none none true
true false true true true
true false true false true
true false true none true
true false false true true
true false false false true
true false false none true
true false none true true
true false none false true
true false none none true
true none true true true
true none true false true
true none true none true
true none false true true
true none false false true
true none false none true
true none none true true
true none none false true
true none none none true
false true true true false
false true true false false
false true true none false
false true false true false
false true false false false
false true false none false
false true none true false
false true none false false
false true none none false
false false true true false
false false true false false
false false true none false
false false false true false
false false false false false
false false false none false
false false none true false
false false none false false
false false none none false
false none true true false
false none true false false
false none true none false
false none false true false
false none false false false
false none false none false
false none none true false
false none none false false
false none none none false

Can you formalize / review the expected use cases first ?

Otherwise, we leave the simple way, which is only consider required on nested fields only when required is defined with @Parameter and @Schema are defined.

@mc1arke
Copy link
Contributor

mc1arke commented Dec 31, 2024

I'm not sure how none in column 2 and 4 (*-NotNull/Blank) differs from false as the @NotNull annotation is either present or isn't. If we're specifying none on the nested Schema then I think we should do the same on the ParamObj schema for completeness.

I've created the table below based on the following models that cover all the cases I think you've specified:

    public record MultiFieldParameterObject(
            @Valid @Schema(requiredMode = RequiredMode.REQUIRED) @NotNull MultiFieldNestedParameterObject requiredNotNullParameterObject,
            @Valid @Schema(requiredMode = RequiredMode.REQUIRED) MultiFieldNestedParameterObject requiredNoValidationParameterObject,
            @Valid @Schema(requiredMode = RequiredMode.NOT_REQUIRED) @NotNull MultiFieldNestedParameterObject notRequiredNotNullParameterObject,
            @Valid @Schema(requiredMode = RequiredMode.NOT_REQUIRED) MultiFieldNestedParameterObject notRequiredNoValidationParameterObject,
            @Valid @NotNull MultiFieldNestedParameterObject noSchemaNotNullParameterObject,
            @Valid MultiFieldNestedParameterObject noSchemaNoValidationParameterObject) {

    }

    public record MultiFieldNestedParameterObject (
            @Schema(requiredMode = Schema.RequiredMode.REQUIRED) @NotNull String requiredNotNullField,
            @Schema(requiredMode = Schema.RequiredMode.REQUIRED) String requiredNoValidationField,
            @Schema(requiredMode = RequiredMode.NOT_REQUIRED) @NotNull String notRequiredNotNullField,
            @Schema(requiredMode = RequiredMode.NOT_REQUIRED) String notRequiredNoValidationField,
            @NotNull String noSchemaNotNullField,
            String noSchemaNoValidationField) {
    }
ParamObj-Schema/Param ParamObj-NotNull/Blank NestedField-Schema/Param Required NestedField-NotNull/Blank Resulting Required Flattened Field Name
TRUE Present TRUE Present TRUE requiredNotNullParameterObject.requiredNotNullField
TRUE Present TRUE Absent TRUE requiredNotNullParameterObject.requiredNoValidationField
TRUE Present FALSE Present FALSE requiredNotNullParameterObject.notRequiredNotNullField
TRUE Present FALSE Absent FALSE requiredNotNullParameterObject.notRequiredNoValidationField
TRUE Present Absent Present TRUE requiredNotNullParameterObject.noSchemaNotNullField
TRUE Present Absent Absent FALSE requiredNotNullParameterObject.noSchemaNoValidationField
TRUE Absent TRUE Present TRUE requiredNoValidationParameterObject.requiredNotNullField
TRUE Absent TRUE Absent TRUE requiredNoValidationParameterObject.requiredNoValidationField
TRUE Absent FALSE Present FALSE requiredNoValidationParameterObject.notRequiredNotNullField
TRUE Absent FALSE Absent FALSE requiredNoValidationParameterObject.notRequiredNoValidationField
TRUE Absent Absent Present TRUE requiredNoValidationParameterObject.noSchemaNotNullField
TRUE Absent Absent Absent FALSE requiredNoValidationParameterObject.noSchemaNoValidationField
FALSE Present TRUE Present FALSE notRequiredNotNullParameterObject.requiredNotNullField
FALSE Present TRUE Absent FALSE notRequiredNotNullParameterObject.requiredNoValidationField
FALSE Present FALSE Present FALSE notRequiredNotNullParameterObject.notRequiredNotNullField
FALSE Present FALSE Absent FALSE notRequiredNotNullParameterObject.notRequiredNoValidationField
FALSE Present Absent Present FALSE notRequiredNotNullParameterObject.noSchemaNotNullField
FALSE Present Absent Absent FALSE notRequiredNotNullParameterObject.noSchemaNoValidationField
FALSE Absent TRUE Present FALSE notRequiredNoValidationParameterObject.requiredNotNullField
FALSE Absent TRUE Absent FALSE notRequiredNoValidationParameterObject.requiredNoValidationField
FALSE Absent FALSE Present FALSE notRequiredNoValidationParameterObject.notRequiredNotNullField
FALSE Absent FALSE Absent FALSE notRequiredNoValidationParameterObject.notRequiredNoValidationField
FALSE Absent Absent Present FALSE notRequiredNoValidationParameterObject.noSchemaNotNullField
FALSE Absent Absent Absent FALSE notRequiredNoValidationParameterObject.noSchemaNoValidationField
Absent Present TRUE Present TRUE noSchemaNotNullParameterObject.requiredNotNullField
Absent Present TRUE Absent TRUE noSchemaNotNullParameterObject.requiredNoValidationField
Absent Present FALSE Present FALSE noSchemaNotNullParameterObject.notRequiredNotNullField
Absent Present FALSE Absent FALSE noSchemaNotNullParameterObject.notRequiredNoValidationField
Absent Present Absent Present TRUE noSchemaNotNullParameterObject.noSchemaNotNullField
Absent Present Absent Absent FALSE noSchemaNotNullParameterObject.noSchemaNoValidationField
Absent Absent TRUE Present FALSE noSchemaNoValidationParameterObject.requiredNotNullField
Absent Absent TRUE Absent FALSE noSchemaNoValidationParameterObject.requiredNoValidationField
Absent Absent FALSE Present FALSE noSchemaNoValidationParameterObject.notRequiredNotNullField
Absent Absent FALSE Absent FALSE noSchemaNoValidationParameterObject.notRequiredNoValidationField
Absent Absent Absent Present FALSE noSchemaNoValidationParameterObject.noSchemaNotNullField
Absent Absent Absent Absent FALSE noSchemaNoValidationParameterObject.noSchemaNoValidationField

mc1arke added a commit to mc1arke/springdoc-openapi that referenced this issue Dec 31, 2024
@bnasslahsen
Copy link
Collaborator

@mc1arke,

To make sure i share the same understanding.
For the case reported by lako12, Do you you confirm we are here ? Why is it called no Validation ?

ParamObj-Schema/Param ParamObj-NotNull/Blank NestedField-Schema/Param Required NestedField-NotNull/Blank Resulting Required Flattened Field Name
Absent Absent Absent Present FALSE noSchemaNoValidationParameterObject.noSchemaNotNullField

This is the revised version. I have highlighted some results in bold, as they should be considered as priority if they are explicitly defined by the user on the field level @Schema or @Parameter?

ParamObj-Schema/Param ParamObj-NotNull/Blank NestedField-Schema/Param Required NestedField-NotNull/Blank Resulting Required Flattened Field Name
TRUE Present TRUE Present TRUE requiredNotNullParameterObject.requiredNotNullField
TRUE Present TRUE Absent TRUE requiredNotNullParameterObject.requiredNoValidationField
TRUE Present FALSE Present FALSE -> why did you propose false? requiredNotNullParameterObject.notRequiredNotNullField
TRUE Present FALSE Absent FALSE requiredNotNullParameterObject.notRequiredNoValidationField
TRUE Present Absent Present TRUE requiredNotNullParameterObject.noSchemaNotNullField
TRUE Present Absent Absent FALSE requiredNotNullParameterObject.noSchemaNoValidationField
TRUE Absent TRUE Present TRUE requiredNoValidationParameterObject.requiredNotNullField
TRUE Absent TRUE Absent TRUE requiredNoValidationParameterObject.requiredNoValidationField
TRUE Absent FALSE Present FALSE requiredNoValidationParameterObject.notRequiredNotNullField
TRUE Absent FALSE Absent FALSE requiredNoValidationParameterObject.notRequiredNoValidationField
TRUE Absent Absent Present TRUE requiredNoValidationParameterObject.noSchemaNotNullField
TRUE Absent Absent Absent FALSE requiredNoValidationParameterObject.noSchemaNoValidationField
FALSE Present TRUE Present TRUE notRequiredNotNullParameterObject.requiredNotNullField
FALSE Present TRUE Absent TRUE notRequiredNotNullParameterObject.requiredNoValidationField
FALSE Present FALSE Present FALSE notRequiredNotNullParameterObject.notRequiredNotNullField
FALSE Present FALSE Absent FALSE notRequiredNotNullParameterObject.notRequiredNoValidationField
FALSE Present Absent Present FALSE notRequiredNotNullParameterObject.noSchemaNotNullField
FALSE Present Absent Absent FALSE notRequiredNotNullParameterObject.noSchemaNoValidationField
FALSE Absent TRUE Present TRUE notRequiredNoValidationParameterObject.requiredNotNullField
FALSE Absent TRUE Absent TRUE notRequiredNoValidationParameterObject.requiredNoValidationField
FALSE Absent FALSE Present FALSE notRequiredNoValidationParameterObject.notRequiredNotNullField
FALSE Absent FALSE Absent FALSE notRequiredNoValidationParameterObject.notRequiredNoValidationField
FALSE Absent Absent Present FALSE notRequiredNoValidationParameterObject.noSchemaNotNullField
FALSE Absent Absent Absent FALSE notRequiredNoValidationParameterObject.noSchemaNoValidationField
Absent Present TRUE Present TRUE noSchemaNotNullParameterObject.requiredNotNullField
Absent Present TRUE Absent TRUE noSchemaNotNullParameterObject.requiredNoValidationField
Absent Present FALSE Present FALSE noSchemaNotNullParameterObject.notRequiredNotNullField
Absent Present FALSE Absent FALSE noSchemaNotNullParameterObject.notRequiredNoValidationField
Absent Present Absent Present TRUE noSchemaNotNullParameterObject.noSchemaNotNullField
Absent Present Absent Absent FALSE noSchemaNotNullParameterObject.noSchemaNoValidationField
Absent Absent TRUE Present TRUE noSchemaNoValidationParameterObject.requiredNotNullField
Absent Absent TRUE Absent TRUE noSchemaNoValidationParameterObject.requiredNoValidationField
Absent Absent FALSE Present FALSE noSchemaNoValidationParameterObject.notRequiredNotNullField
Absent Absent FALSE Absent FALSE noSchemaNoValidationParameterObject.notRequiredNoValidationField
Absent Absent Absent Present FALSE noSchemaNoValidationParameterObject.noSchemaNotNullField
Absent Absent Absent Absent FALSE noSchemaNoValidationParameterObject.noSchemaNoValidationField

@mc1arke
Copy link
Contributor

mc1arke commented Dec 31, 2024

Yes, I'd agree the line you've called-out matches the initial report.

I'd called it noValidation since @NotNull is a validation parameter and I didn't want to confuse names with notNotNull or noNotNull so went with specifying that no validation was being applied to the field.

My assumptions when drawing up the table:

  • Specifying a non-AUTO value for requiredMode on @Schema overrides any validation annotation, so @Schema(requiredMode = RequiredMode.NOT_REQUIRED) @NotNull String field would generate swagger that says the field isn't required despite Java enforcing the validation - this is what the JavaDoc for Schema#requiredMode indicates is supposed to happen
  • Specifying @Schema without a requiredMode, specifying requiredMode as RequiredMode.AUTO, or not specifying @Schema will cause the presence or absence of the validation parameter to drive the required status of the field
  • Where there is no validation parameter and the @Schema annotation does not cause an override then the field is not mandatory
  • Where a parent field does not resolve as mandatory, the child field cannot be shown as mandatory regardless of the @Schema or validation annotations on the child field.

I notice that your updated table uses the @Schema on the child field to make a child field mandatory even if the parent field isn't mandatory, which is partially opposite to my 4th point. For me it makes the @Schema handling inconsistent since it's no longer matching what the heuristics for validation parameters do, so is there a particular use-case you're aiming for here?

mc1arke added a commit to mc1arke/springdoc-openapi that referenced this issue Dec 31, 2024
…doc#2817

When creating the flattened parameter definitions for an item annotated
with @ParameterObject, the @Schema and @Property annotations on any
fields prior to the final child-node of each branch of the parameter
tree are not taken into consideration. This results in the field name in
the code being used even where annotations may override that, prevents
the fields being hidden where one of the parent fields is marked as
hidden but the child field isn't hidden, and marks a field as mandatory
even where the field would only be mandatory if the parent object had
been declared through a sibling of the target field being set. To
overcome this, whilst the flattened parameter map is being built, each
field is now being inspected for a @parameter annotation or - where the
@parameter annotation isn't found - a @Schema annotation. Where a custom
name is included in either of those annotations then the overridden
field name is used in the flattened definition. If either annotation
declares the field as hidden then the field and all child fields are
removed from the resulting definition, and a field is no longer set as
mandatory unless the parent field was also declared as mandatory, or
resolved as non-null and was set in an automatic state, or the child
field is specifically set as required in the Schema or Parameter
annotation.
@mc1arke
Copy link
Contributor

mc1arke commented Dec 31, 2024

I've raised #2832 which is basically just re-applying #2788 but with an additional line to handle the forced required from a child @Schema annotation you'd put into your version of the test table, plus it contains a whole set of extra tests to prove the functionality aligns with the Java validators and to explicitly validate against the table contents.

@bnasslahsen
Copy link
Collaborator

bnasslahsen commented Dec 31, 2024

Thanks @mc1arke,

I am currently a little sick.
But will have a look to it, in the upcoming days.

mc1arke added a commit to mc1arke/springdoc-openapi that referenced this issue Jan 1, 2025
…doc#2817

When creating the flattened parameter definitions for an item annotated
with @ParameterObject, the @Schema and @Property annotations on any
fields prior to the final child-node of each branch of the parameter
tree are not taken into consideration. This results in the field name in
the code being used even where annotations may override that, prevents
the fields being hidden where one of the parent fields is marked as
hidden but the child field isn't hidden, and marks a field as mandatory
even where the field would only be mandatory if the parent object had
been declared through a sibling of the target field being set. To
overcome this, whilst the flattened parameter map is being built, each
field is now being inspected for a @parameter annotation or - where the
@parameter annotation isn't found - a @Schema annotation. Where a custom
name is included in either of those annotations then the overridden
field name is used in the flattened definition. If either annotation
declares the field as hidden then the field and all child fields are
removed from the resulting definition, and a field is no longer set as
mandatory unless the parent field was also declared as mandatory, or
resolved as non-null and was set in an automatic state, or the child
field is specifically set as required in the Schema or Parameter
annotation.
ndwlocatieservices added a commit to ndwnu/nls-accessibility-map that referenced this issue Jan 14, 2025
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [nu.ndw.nls.locationdataissuesapi:client-feign](https://dev.azure.com/ndwnu/NLS/_git/nls-location-data-issues) ([source](https://dev.azure.com/ndwnu/NLS/_git/nls-location-data-issues)) | compile | patch | `1.0.17` -> `1.0.18` |
| [org.springdoc:springdoc-openapi-starter-webmvc-ui](https://springdoc.org/) ([source](https://github.com/springdoc/springdoc-openapi)) | compile | minor | `2.7.0` -> `2.8.0` |

---

### Release Notes

<details>
<summary>springdoc/springdoc-openapi (org.springdoc:springdoc-openapi-starter-webmvc-ui)</summary>

### [`v2.8.0`](https://github.com/springdoc/springdoc-openapi/blob/HEAD/CHANGELOG.md#280---2025-01-03)

[Compare Source](springdoc/springdoc-openapi@v2.7.0...v2.8.0)

##### Added

-   [#&#8203;2790](springdoc/springdoc-openapi#2790) - Moving to OpenAPI 3.1 as the default implementation for springdoc-openapi
-   [#&#8203;2817](springdoc/springdoc-openapi#2817) - Obey annotations when flattening ParameterObject fields
-   [#&#8203;2826](springdoc/springdoc-openapi#2826) - Make it possible to mark parameters with [@&#8203;RequestParam](https://github.com/RequestParam) annotation to be sent in form instead of query.
-   [#&#8203;2822](springdoc/springdoc-openapi#2822) - Support returning null in ParameterCustomizer
-   [#&#8203;2830](springdoc/springdoc-openapi#2830) - Add support for deprecated fields.
-   [#&#8203;2780](springdoc/springdoc-openapi#2780) - Add Security Schema by AutoConfigure

##### Changed

-   Upgrade spring-boot to 3.4.1
-   Upgrade spring-cloud-function to 4.2.0
-   Upgrade swagger-core to 2.2.27

##### Fixed

-   [#&#8203;2804](springdoc/springdoc-openapi#2804) - Stable release 2.7.0 depends on Spring Cloud Milestone 4.2.0-M1
-   [#&#8203;2828](springdoc/springdoc-openapi#2828) - Required a bean of type 'org.springframework.data.rest.webmvc.mapping.Associations' that could not be found.
-   [#&#8203;2823](springdoc/springdoc-openapi#2823) - Capturing pattern in identical paths only renders the path element of one method
-   [#&#8203;2817](springdoc/springdoc-openapi#2817) - Automatically add required if a field is [@&#8203;notNull](https://github.com/notNull) or [@&#8203;NotBlank](https://github.com/NotBlank).
-   [#&#8203;2814](springdoc/springdoc-openapi#2814) - An unresolvable circular reference with management.endpoint.gateway.enabled=true.
-   [#&#8203;2798](springdoc/springdoc-openapi#2798) - Object schema generated for Unit Kotlin type.
-   [#&#8203;2797](springdoc/springdoc-openapi#2797) - Removing operationId via customizer does not w...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants