quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.87k stars 2.71k forks source link

OpenAPI Extension (smallrye) produces wrong schema for Flow based return types #44773

Open tomislaveric opened 3 days ago

tomislaveric commented 3 days ago

Describe the bug

The openAPI extension (smallrye) is producing new objects, which doesn't exist. It combines Flow with the type name and is generating a new object, FlowTypeName.

Expected behavior

My expectation would be, that the $ref: "#/components/schemas/FlowFoobar" is $ref: "#/components/schemas/Foobar".

Actual behavior

When you, for example, use Flow<Foobar> as return type, the generator creates a new object called: FlowFoobar. Or when a Flow<String> becomes a FlowString object. And when i add the annotation: @RestStreamElementType(MediaType.APPLICATION_JSON) The output stays the same.

class GreetingResource {
    @GET
    @Produces(MediaType.SERVER_SENT_EVENTS)
    @RestStreamElementType(MediaType.APPLICATION_JSON)
    fun hello(): Flow<String> {
        return flow {
            Foobar("Hello")
        }
    }
}

data class Foobar(val data: String)
components:
  schemas:
    FlowString:
      type: object
paths:
  /hello:
    get:
      responses:
        "200":
          description: OK
          content:
            text/event-stream:
              schema:
                $ref: "#/components/schemas/FlowFoobar"
      summary: Hello
      tags:
      - Greeting Resource

How to Reproduce?

Open the project from the zip file. Trigger a quarkus-dev-build. Check the generated openapi/openapi.yaml file.

Output of uname -a or ver

24.1.0

Output of java -version

openjdk version "22.0.2" 2024-07-16

Quarkus version or git rev

3.17.0

Build tool (ie. output of mvnw --version or gradlew --version)

gradle 8.9

Additional information

Example code to reproduce code-with-quarkus.zip

quarkus-bot[bot] commented 3 days ago

/cc @EricWittmann (openapi), @Ladicek (smallrye), @MikeEdgar (openapi), @jmartisk (smallrye), @phillip-kruger (openapi,smallrye), @radcortez (smallrye)

MikeEdgar commented 3 days ago

@tomislaveric this is by design. Since Flow is a generic type, creating a schema with that name would very likely result in a clash for types of Flow with different type arguments. Is it causing a technical issue or is it just that it's unexpected?

andreas-eberle commented 3 days ago

Hi Mike,

I think the issue is a bit different. Flow is basically similar to Multi; it's just the Kotlin way of providing a cold stream of elements. So if you do this the Java way, you would use Mutli<String> or Multi<SomeObject>. And then you would not expect the type of the event stream to be MutliString or MultiSomeObject.

The same applies to the Flow here. It is not part of the actual result, it is the stream that will provide the single elements of the result. And the schema of the elements would then be String or SomeObject.

In that sense, I think the generated schema is wrong.

MikeEdgar commented 3 days ago

Ok, I see. Yes I agree then. We'll need to make the change in smallrye-open-api for it.