springwolf / springwolf-core

Automated documentation for event-driven applications built with Spring Boot
https://www.springwolf.dev
Apache License 2.0
248 stars 70 forks source link

Allow for declaration of multiple co-existing AsyncAPIs #805

Open Sheldoras opened 3 months ago

Sheldoras commented 3 months ago

Describe the feature request Currently Springwolf only allows for one AsyncAPI document to be provided by a service. The only limiting option about 'which' channels/operations etc go into said AsyncAPI specification is the base-package property.

Looking at other tools (Springdoc for OpenAPI spec generation for example) they allow for multiple OpenAPI specs to be declared in parallel (say one spec for version 1.0.0 and one for 2.0.0 which are simultaneously supported by a service). It is also possible to filter more finely which endpoints (in the case of OpenAPI) go into which OpenAPI specification.

Motivation If a service wants to support different AsyncAPI versions in parallel, it would be beneficial if two (or more) distinct specifications could be configured, each including only its relevant channels/operations/schemas.

Technical details With Springdoc and OpenAPI this declaration can look like so:

    @Bean
    fun version1(): GroupedOpenApi {
        val version = "1.0"
        return GroupedOpenApi.builder()
            .group(version)
            .displayName("API Version $version")
            .pathsToMatch("/public/v1/**")
            .pathsToMatch("/legacy/v1/**")
            .build()
    }

    @Bean
    fun version2(): GroupedOpenApi {
        val version = "2.0"
        return GroupedOpenApi.builder()
            .group(version)
            .displayName("API Version $version")
            .pathsToMatch("/public/v2/**")
            .pathsToMatch("/legacy/v2/**")
            .pathsToExclude("/public/v2/secret/**")
            .build()
    }

Something equivalent for providing multiple AsyncAPI specifications per service would be fantastic

github-actions[bot] commented 3 months ago

Welcome to Springwolf. Thanks a lot for reporting your first issue. Please check out our contributors guide and feel free to join us on discord.

timonback commented 3 months ago

Hi @Sheldoras,

Great suggestion.

A couple questions for understanding:

  1. How do you plan to group the different endpoints (pathsToMatch in OpenAPI)? Is it only based on the channel name or do you actually intend to group by the actual operation (including the schema, so that you can differentiate between v1 and v2 payloads)?
  2. Have you considered tags within the current document?
  3. Do you wish to group into different documents (group in OpenAPI)?
Sheldoras commented 3 months ago

Hi @timonback,

thanks for considering this!

  1. In our particular scenario grouping by channel name would be sufficient (considering all operations on an included channel part of the document). Additionally it would be great if only payloads (schemas) that are actually part of the operations on included channels would appear in the specification. So if I have a channel '/v1/somedata' to which I publish 'V1Data' payload and a '/v2/somedata' to which I publish 'V2Data' payload and my filter is like '/v1/**' then 'V2Data' should not appear in the specification.
  2. Tagging all the relevant elements in a given document with their appropriate versions is an option in general, however not applicable to our case as we need mutiple documents (due to see 3.)
  3. That is exactly what we would need as our services report their specifications (AsyncAPI and OpenAPI) to a catalog system which expects 'one document per version' for its internal catalogization.

If you have any other question I'm happy to answer them!