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

Special support for byte stream on endpoint api in/out #2145

Merged
merged 2 commits into from
May 7, 2023

Conversation

vigoo
Copy link
Contributor

@vigoo vigoo commented May 5, 2023

Resolves #2141

@@ -24,6 +24,6 @@ private[codec] trait ContentCodecs {
def content[A](implicit schema: Schema[A]): ContentCodec[A] =
HttpCodec.Content(schema)

def contentStream[A](implicit schema: Schema[A]): ContentCodec[ZStream[Any, Nothing, A]] =
def contentStream[A](implicit schema: Schema[A]): ContentCodec[ZStream[Any, Throwable, A]] =
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this should not be changed and the input stream's errors should be handled somehow before passing the stream to the implementation, but I did not see an obvious place to do that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should definitely not be changed.

The reason is that an endpoint handler cannot deal with Throwable errors. It only knows about typed errors, which are part of the protocol itself. Throwable errors indicate something fatal happened: for example, that an element of the stream was improperly encoded. No recovery is possible at the level of the endpoint handler. So it's a defect and must be handled as a fallback higher up (request handler, HTTP).

Headers(Header.ContentType(MediaType.application.json))
} else throw new IllegalStateException("A request on a REST endpoint should have at most one body")
if (isByteStream(flattened.content)) {
Headers(Header.ContentType(MediaType.application.`octet-stream`)) // TODO: customizable content type
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be able to attach a custom media type to the body codec somehow, not sure if it should be part of this PR or not

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be part of this PR. Basically, store an Option[MediaType] inside the codec, and add variants that allow it to be specified (overridden) when the content codec is specified.

@@ -517,13 +517,13 @@ object HttpCodec
def withIndex(index: Int): Content[A] = copy(index = index)
}
private[http] final case class ContentStream[A](schema: Schema[A], index: Int = 0)
extends Atom[HttpCodecType.Content, ZStream[Any, Nothing, A]] {
extends Atom[HttpCodecType.Content, ZStream[Any, Throwable, A]] {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, this should be Nothing and we should orDie on throwables.

if (jsonEncoders.length == 0) Headers.empty
else if (jsonEncoders.length == 1) {
Headers(Header.ContentType(MediaType.application.json))
} else throw new IllegalStateException("A request on a REST endpoint should have at most one body")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This, btw, is where the multi-part stuff would go.


private def isByteStream(codecs: Chunk[BodyCodec[_]]): Boolean =
if (codecs.length == 1) {
codecs.headOption match {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

headOption boxes. You already know there is one, so do codecs(0).

Copy link
Member

@jdegoes jdegoes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good! Just a few changes and we can get this merged. 💪

@codecov-commenter
Copy link

codecov-commenter commented May 5, 2023

Codecov Report

Patch coverage: 90.00% and project coverage change: -0.14 ⚠️

Comparison is base (8c59155) 66.87% compared to head (307d8f6) 66.73%.

📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2145      +/-   ##
==========================================
- Coverage   66.87%   66.73%   -0.14%     
==========================================
  Files         141      141              
  Lines        6040     6268     +228     
  Branches      256      259       +3     
==========================================
+ Hits         4039     4183     +144     
- Misses       2001     2085      +84     
Impacted Files Coverage Δ
...http/src/main/scala/zio/http/codec/HttpCodec.scala 48.68% <ø> (-1.68%) ⬇️
...main/scala/zio/http/codec/internal/BodyCodec.scala 45.45% <0.00%> (-4.55%) ⬇️
.../src/main/scala/zio/http/codec/ContentCodecs.scala 75.00% <75.00%> (+25.00%) ⬆️
...tp/src/main/scala/zio/http/endpoint/Endpoint.scala 48.45% <89.28%> (+17.45%) ⬆️
...scala/zio/http/codec/internal/EncoderDecoder.scala 92.66% <95.00%> (+0.75%) ⬆️
...scala/zio/http/codec/internal/AtomizedCodecs.scala 91.17% <100.00%> (+3.29%) ⬆️

... and 3 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@jdegoes jdegoes merged commit 5e8472a into main May 7, 2023
@jdegoes jdegoes deleted the endpoint-api-bytestream branch May 7, 2023 09:41
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

Successfully merging this pull request may close these issues.

Support binary element types for Endpoint API
3 participants