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

Springdoc OpenApi Annotations @ExtensionProperty Not Evaluating Properties from application.yml #2461

Closed
ustadji opened this issue Dec 15, 2023 · 1 comment
Labels
enhancement New feature or request

Comments

@ustadji
Copy link

ustadji commented Dec 15, 2023

I have a spring boot 3.2 project for my microservice and am using the springdoc dependency to ultimately generate an OAS document for consumption by AWS API Gateway (AGW). This service is using a REST API configuration but through VPC Link so I need to ensure that the 'x-amazon-apigateway-integration' extensions are defined in my OAS doc else when I import/re-import into AGW, I have to manually add the VPC links as they get wiped out (not fun)

I have defined properties in my application.yml file as follows:

api:
  base-request-mapping: "" 
  info:
    title: MKMTestWS (Test Microservice API)
    version: "1.0"
    description: "This API exposes endpoints for testing anything"
    termsOfService: "https://www.test.ca/terms"
  server:
    description: "API Server"
    url: "http://localhost:${server.port}"
  tag:
    name: "Test Rest API"
    description: "Test Rest API"
  extensions:
    name: 'x-amazon-apigateway-integration'
    properties:
      type: "http_proxy"
      connectionId: "1rqafw"
      uri: "http://my-vpc/nlb-link"
      passthroughBehavior: "when_no_match"
      connectionType: "VPC_LINK"

I use property placeholders at the class level which picks up some of the values above which works fine - my title, version, description etc. all get evaluated

@OpenAPIDefinition(
		info = @Info(
				title = "${api.info.title}",
				version = "${api.info.version}",
				description = "${api.info.description}",
				termsOfService = "${api.info.termsOfService}",
				contact = @Contact(
						name = "${api.info.contact.name}",
						url = "${api.info.contact.url}",
						email = "${api.info.contact.email}")),
		servers = { @Server(description = "${api.server.description}", url = "${api.server.url}") })
@Tag(name = "${api.tag.name}", description = "${api.tag.description}")
@Slf4j
@CrossOrigin(originPatterns = "*", allowCredentials = "true")
@RestController
@RequestMapping(value = "${api.base-request-mapping}/testcontroller", produces = MediaType.APPLICATION_JSON_VALUE)
public class TestController {
}

Result in OAS 3.x doc evaluates correctly:

{
  "openapi": "3.0.1",
  "info": {
    "title": "MKMTestWS (Test Microservice API)",
    "description": "This API exposes endpoints for testing anything",
    "termsOfService": "https://www.test.ca/terms",
    "contact": {
      "name": "Test ITS",
      "url": "https://www.test.ca",
      "email": "test@test.ca"
    },
    "version": "1.0"
  },

However, when I try and put in property placeholders at the method level within the @operation annotation inside the class, I get the literal string returned.

Code with annotations:

	@Operation(
			summary = "Get Test",
			description = "Get Test",
			extensions = { @Extension(
				name = "${api.extensions.name}",
				properties = { 
                @ExtensionProperty(name = "type", value = "${api.extensions.properties.type}"),
		@ExtensionProperty(name = "connectionId", value = "${api.extensions.properties.connectionId}"),
		@ExtensionProperty(name = "httpMethod", value = "GET"),
		@ExtensionProperty(
		name = "uri",
		value = "${api.extensions.properties.uri}/testcontroller/getTest"),
		@ExtensionProperty(name = "passthroughBehavior", value = "${api.extensions.properties.passthroughBehavior}"),
		@ExtensionProperty(name = "connectionType", value = "${api.extensions.properties.connectionType}") }) })	
	@GetMapping(value = "/getTest")
	@ResponseBody
	public ResponseEntity<StandardApiResponse<GenericResponse>> getTest(
			@RequestParam(required = false) String testParam) throws Exception {
        }

When I generate the OAS 3.x doc, I get literal strings:

        "x-${api.extensions.name}": {
          "passthroughBehavior": "${api.extensions.properties.passthroughBehavior}",
          "connectionId": "${api.extensions.properties.connectionId}",
          "type": "#{type)",
          "httpMethod": "GET",
          "uri": "${api.extensions.properties.uri}/testcontroller/getTest",
          "connectionType": "${api.extensions.properties.connectionType}"
        }

I've tried researching many avenues but all to no avail.

Here are my main relevant dependencies:

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.2.0</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<dependency>
			<groupId>org.springdoc</groupId>
			<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
			<version>2.3.0</version>
		</dependency>

Tried using @value spring boot annotations to resolve the properties but couldn't put variables within the springdoc annotations. Tried single brackets/double etc....

Is this a bug? Or am I doing something wrong?

@bnasslahsen
Copy link
Contributor

bnasslahsen commented Feb 28, 2024

@ustadji,

This is the list of available properties: https://springdoc.org/#can-i-use-spring-property-with-swagger-annotations
This is not a feature built-in in springdoc.
it's an enhancement request and will be available with the next release.
You can already test it using the latest SNAPSHOT.

The support of spring property resolver for @ExtensionProperty by setting springdoc.api-docs.resolve-extensions-properties to true

@bnasslahsen bnasslahsen added the enhancement New feature or request label Feb 28, 2024
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

2 participants