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

feat: http transcoding grpc #1583

Closed
wants to merge 1 commit into from

Conversation

WayneWang12
Copy link

@WayneWang12 WayneWang12 commented Feb 24, 2022

References #1461.

Most code of this commit are from file https://github.com/cloudstateio/cloudstate/blob/master/proxy/core/src/main/scala/io/cloudstate/proxy/HttpApi.scala

Just do some change to make it may work in akka-grpc.

@lightbend-cla-validator

At least one pull request committer is not linked to a user. See https://help.github.com/en/articles/why-are-my-commits-linked-to-the-wrong-user#commits-are-not-linked-to-any-user

@WayneWang12 WayneWang12 force-pushed the feat/grpc_transcoding branch 4 times, most recently from d70d6a6 to 15b6a93 Compare February 24, 2022 14:23
@WayneWang12 WayneWang12 changed the title feat: http transcoding grpc WIP: feat: http transcoding grpc Feb 24, 2022
@WayneWang12 WayneWang12 force-pushed the feat/grpc_transcoding branch 2 times, most recently from 6b3cac4 to 86d2360 Compare February 24, 2022 14:55
@WayneWang12 WayneWang12 changed the title WIP: feat: http transcoding grpc feat: http transcoding grpc Feb 24, 2022
@WayneWang12
Copy link
Author

I've only implement scala mode. I'm not quite familiar with Java.

Also, I think we can make grpc client works for json format http request. That will make akka-grpc usable even we only use protobuf to describe service protocols.

}

val httpApiHandlers = (List.empty[PartialFunction[model.HttpRequest, scala.concurrent.Future[model.HttpResponse]]] @for(method <- service.methods if !method.inputStreaming){ ++ @{method.name}Handler})
.foldLeft(PartialFunction.empty[model.HttpRequest, scala.concurrent.Future[model.HttpResponse]])((acc, p) => acc.orElse(p))
Copy link
Member

Choose a reason for hiding this comment

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

It's very likely that you'll want to use a different method of partial function composition (I remember that I had to do something more custom to make sure that it was well-behaved in the face of many endpoints when I did the Cloudstate version). Otherwise you'll have to do a match linearly against all possible cases for each request.

Copy link
Author

Choose a reason for hiding this comment

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

Yes, you are right. I've changed my implementation. I can get grpc handler and use it, so what I need to do is transforming json http request to grpc request and handle it with grpc handler, then transform grpc response to json http response. Not too efficient, but it might work.

@lightbend-cla-validator

Copy link
Member

@raboof raboof left a comment

Choose a reason for hiding this comment

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

This is already much less intrusive, which is great! I wonder if we could take that even further?

Function.unlift((req: model.HttpRequest) => req.uri.path match {


val httpHandler = akka.grpc.HttpApi.serve(@{service.name}.descriptor, handle _)
Copy link
Member

Choose a reason for hiding this comment

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

This effectively elevates HttpApi.serve to stable API: if a project uses code generated by this version, and updates the Akka gRPC runtime library, we'll have to make sure these new versions of the runtime library still provide that serve function with the same signature and behavior. I'm not sure I'm comfortable with that yet.

I wonder if it would be possible to use this HttpApi from the main client code, so the user can optionally enable it, and we can mark it ApiMayChange to leave room for evolving the API further later?

case model.Uri.Path.Slash(model.Uri.Path.Segment(`prefix`, model.Uri.Path.Slash(model.Uri.Path.Segment(method, model.Uri.Path.Empty)))) =>
Some(handle(spi.onRequest(prefix, method, req), method))
case _ =>
None
})
httpHandler orElse grpcHandler
Copy link
Member

Choose a reason for hiding this comment

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

This also seems potentially tricky: some high-throughput use cases might only care about the gRPC protocol, and hard-coding the HTTP transcoding support here might impact that hot path.

@johanandren
Copy link
Member

Closing this since continued in #1834

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

Successfully merging this pull request may close these issues.

None yet

5 participants