Skip to content

_links property schema using Spring Data REST is array instead of object #2359

Closed
@clementdenis

Description

@clementdenis

Describe the bug

When working with Spring Data REST, the generated schema is an array of links, instead of a map of links (object with additionalProperties of type Link).
This bug is similar to #1090, but as it happens on the latest version (2.2.0), I'm opening a new one.

Here is a quick analysis of the problem:

  • Spring Data REST serializes fields of type org.springframework.hateoas.Links as an object using
    org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer
  • But SpringDoc sees org.springframework.hateoas.Links as a collection of org.springframework.hateoas.Link,
    so it generates an array schema of #/components/schemas/Link instead
  • OpenApiHateoasLinksCustomizer should be able to help (needs to be registered though), but as the generated schema references #/components/schemas/Link directly instead of referencing a #/components/schemas/Links schema, it's useless

Workaround

I could customize the generated spec to fix the _links properties with this:

@Bean
GlobalOpenApiCustomizer linksCustomizer(SpringDocConfigProperties springDocConfigProperties) {
    OpenApiHateoasLinksCustomizer linksCustomizer = new OpenApiHateoasLinksCustomizer(springDocConfigProperties);
    return openApi -> {
        //replace generated _links array schema with a reference to Links schema
        openApi.getComponents().getSchemas().forEach((__, schema) -> {
            Map properties = schema.getProperties();
            if (properties != null && properties.containsKey("_links")) {
                properties.put("_links", new ObjectSchema().$ref(AnnotationsUtils.COMPONENTS_REF + "Links"));
            }
        });
       //adds the missing Links schema
        linksCustomizer.customise(openApi);
    };
}

To Reproduce

Generate an OpenAPI spec including entities manages through Spring DATA REST repositories, using latest versions of Spring Boot (3.1.3), Spring Data (2023.0.2), SpringDoc (2.2.0).

The generated schema for "links" properties (in collection or entity models) is like this:

"_links": {
    "type": "array",
    "items": {
      "$ref": "#/components/schemas/Link"
    }
 }

The Link schema in itself is OK:

"Link": {
  "title": "Link",
  "type": "object",
  "properties": {
    "href": {
      "type": "string"
    },
    "hreflang": {
      "type": "string"
    },
    "title": {
      "type": "string"
    },
    "type": {
      "type": "string"
    },
    "deprecation": {
      "type": "string"
    },
    "profile": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "templated": {
      "type": "boolean"
    }
  }
}

Expected behavior

The generated schema for _links properties should be:

"_links" : {
  "$ref" : "#/components/schemas/Links"
}

and the Links schema should exist:

"Links" : {
  "type" : "object",
  "additionalProperties" : {
    "$ref" : "#/components/schemas/Link"
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions