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

Missing or misleading information in HasOpenApi and ToSchema instances for streamed responses #22

Open
giulioforesto opened this issue Feb 16, 2022 · 1 comment

Comments

@giulioforesto
Copy link

Issues

I see 3 issues here:

HasOpenApi instance for Stream gives no info that it is a streamed response

It simply copies the one of Verb (see the HasOpenApi instance for Stream)

Therefore we have no information, in the OpenApi schema, that the response for that route is streamed.

ToSchema instance for SourceT is misleading

It explicitly "pretends that it is a [a]", no matter the chosen framing (see here), providing a misleading information to the api schema reader that would expect the return type to be a [a] instead of several a separated by the choses framing. This is particularly true when coupled with the issue above, so the reader has not even the information it is a streamed route.

OpenApi misses specification for streamed responses

This is unrelated to servant-openapi but unless I'm mistaken, the OpenApi spec says nothing about streamed responses, so any indication would be hand made, for example in a description field (see below).

Workaround

I implemented the following custom instance:

instance {-# OVERLAPPING #-} (ToSchema a, Accept ct, Typeable fr, KnownNat st, OpenApiMethod me)
  => HasOpenApi (Stream me st fr ct (SourceIO a)) where
  toOpenApi _ = toOpenApi (Proxy :: Proxy (Verb me st '[ct] (Headers '[] a)))
    & setResponseWith (const (& description .~ desc)) 200 (declareResponse "application/json" (Proxy :: Proxy a))
    where
      desc = pack $ "<b>Streamed response</b><br>\
                    \An empty chunk means that the stream is finished.<br>\
                    \Chunk type: the route return type <code>" ++ show_type (Proxy :: Proxy a) ++ "</code><br>\
                    \Chunk separator: <code>" ++ show_type (Proxy :: Proxy fr) ++ "</code>"
      show_type :: (Typeable b) => b -> String
      show_type = (\\ "Proxy * ") . show . typeOf

Wouldn't it be worth improving these 2 instances?

@maksbotan
Copy link
Collaborator

Do you know how other users of OpenAPI spec get around streaming?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants