spring-projects / spring-projects/spring-hateoas

Prevent or customize Link objects of models and collections for better API documentation

Open
#2,037 3 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

process: waiting for feedback
Dominant language
Java
Stars
1.1k
Forks
476
PR merge metrics
No merged PRs in 30d

Description

Hello there,
I'd like to document my API project and I am using org.springdoc:springdoc-openapi-starter-common and org.springdoc:springdoc-openapi-starter-webmvc-ui for doing so.
All the schemas in the generated OpenAPI 3.0.1 documentation, includes the schema called Links which follows:

"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"
    }
  }
}

Therefore it is visible in the Swagger UI, as well:
image

My concern with this is that I, as an API provider I don't want to create false hopes in my API consumers that for Links, all the properties (hreflang, title, etc) will be available. Based on this draft, href is the only REQUIRED property, the rest are OPTIONAL.

The thing is, that properties of a given Schema are generated based on the properties of the RepresentationModel (like below), but Link schema generation won't follows this approach. So it would be good, if properties of Link would be generated to the schema based on actual Link properties (or Annotations?) somehow.

@Entity
@Table(name = "customers")
public class Customer extends RepresentationModel<Customer> {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "customerId", nullable = false)
    private Long id;

    @Column(name = "name", nullable = false)
    @Schema(type = "string", example = "My fine ass Company")
    public String name;

//  ... constructors, getters and setters ... 

Also, that would mean, that I might not want a dedicated Link schema because for my Customer object I would like to have href and name properties but for a different object I might want only href.

Connected to this topic, once the definition of custom Links becomes available, I'd like to have the ability to provide example for them. Currently, the only way (that I'm aware of) to do so is the following:

@Entity
@Table(name = "customers")
@Schema(example = "{\"_links\": {\"self\": {\"href\": \"http://<domain:port>/customers\"}}}")
public class Customer extends RepresentationModel<Customer> {

The problem with this approach, that it is completely overrides additional properties and annotations of the RepresentationModel and that would I couldn't rely on the autogeneration of the properties and their Annotations, regarding OpenAPI examples.
image

Summary
  • Are there any way, to override the default Link schema?
  • Is it possible to define Link schema by RepresentationModel?
  • Is it possible to define my own examples for these Links?

My ultimate goal is to provide a straighforward API documentation to my API consumers which in this context means, Swagger UI won't suggest properties of a given Schema that may never be received.

build.gradle
plugins {
  id 'java'
  id 'org.springframework.boot' version '3.1.5'
  id 'io.spring.dependency-management' version '1.1.3'
  id 'org.asciidoctor.jvm.convert' version '3.3.2'
}

group = 'hu.roncsak'
version = '0.0.1-SNAPSHOT'

java {
  sourceCompatibility = '17'
}

repositories {
  mavenCentral()
}

ext {
  set('snippetsDir', file("build/generated-snippets"))
  h2Version = '2.1.214'
  springBootStarterVersion = '3.1.5'
  springOpenApiStarterVersion = '2.2.0'
  springRestDocsMockMvcVersion = '3.0.0'
  springSecurityVersion = '6.1.5'
}

dependencies {
  implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootStarterVersion"
  implementation "org.springframework.boot:spring-boot-starter-data-rest:$springBootStarterVersion"
  implementation "org.springframework.boot:spring-boot-starter-hateoas:$springBootStarterVersion"
  implementation "org.springframework.boot:spring-boot-starter-oauth2-authorization-server:$springBootStarterVersion"
  implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootStarterVersion"
  implementation "org.springframework.boot:spring-boot-starter-security:$springBootStarterVersion"
  implementation "org.springframework.boot:spring-boot-starter-web:$springBootStarterVersion"
  implementation "org.springdoc:springdoc-openapi-starter-common:$springOpenApiStarterVersion"
  implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:$springOpenApiStarterVersion"
  developmentOnly "org.springframework.boot:spring-boot-devtools:$springBootStarterVersion"
  runtimeOnly "com.h2database:h2:$h2Version"
  testImplementation "org.springframework.boot:spring-boot-starter-test:$springBootStarterVersion"
  testImplementation "org.springframework.restdocs:spring-restdocs-mockmvc:$springRestDocsMockMvcVersion"
  testImplementation "org.springframework.security:spring-security-test:$springSecurityVersion"
}

tasks.named('test') {
  outputs.dir snippetsDir
  useJUnitPlatform()
}

tasks.named('asciidoctor') {
  inputs.dir snippetsDir
  dependsOn test
}

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the generated Link schema with the provided build.gradle and inspect how RepresentationModel and Link are represented in the OpenAPI documentation. Define what per-model Link properties, overrides, and examples should be supported, while preserving autogenerated RepresentationModel properties and annotations. Done means Swagger UI exposes only the intended Link properties and examples for each model.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, openapi, spring
Domain
api, documentation
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.