NIO-based gRPC Swift

Pitch

Include gRPC-Swift among the official and recommended SSWG projects.

Motivation

gRPC enables high-performance open standards-based interoperability for Swift services with services written in other languages.

Quoting grpc.io: "gRPC is a modern open source high performance RPC framework that can run in any environment. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking and authentication. It is also applicable in last mile of distributed computing to connect devices, mobile applications and browsers to backend services."

gRPC has proven useful to many companies and development teams, and its support in multiple languages has made it a popular framework for RPC services. The gRPC-Swift project was jointly developed by teams at Google, Apple, Lyft, and independent software developer Timing, and has proven useful for building applications at scales seen by all of these contributors.

We believe that including gRPC-Swift among officially-recognized SSWG projects and officially-recognized gRPC implementations will move both gRPC and Swift forward as great systems for distributed application development.

Project Composition

The gRPC-Swift project includes a runtime, a code generator, an extensive suite of tests, and examples of both mobile and server-side applications using gRPC with Swift.

28 Likes

YES please, I don't see any reason not to add it. Especially given that the implementation looks really good!

4 Likes

A huge +1 from me: gRPC is an extremely important protocol, and it is exciting to have a good, almost entirely Swift implementation. It seems like a no-brainer to me.

6 Likes

Yes gRPC is definitely on-topic here!

Great to see that the package already uses the swift-log package we created. Is using swift-metrics on the roadmap too?

One topic of conversation might be about the level of API provided. I haven't looked at grpc-swift in detail but I see it offers a public class Server for starting a gRPC server. SwiftNIO doesn't provide that level of API for HTTP, rather it provides the building blocks for others to build an API for an HTTP server. So as well as providing the ChannelHandlers etc. for gRPC this package also provides some higher level API. I'll be interested to hear whether others think that's OK for SSWG packages.

4 Likes

Plus one from me :-) Useful addition to the sswg recommended projects portfolio. I hope to muster up some more time to go over the APIs in some more depth in the near future...

umm, I am not for this but am for the need of data center rpc services. the idea of gRPC is yes, gr8, but proto buff, no as swift's codable types are very powerful on its own which is contingent upon community to create solutions.

+1 this would be a great addition. it extends the application level protocol options and aligned with the “cloud native” nature of swift

2 Likes

Not at the moment; down the line I think it would be a useful addition though.

True, although AsyncHTTPClient does this, albeit for a client. We haven't gone out of our way to preclude users from taking the handlers we provide and creating their own gRPC server but I imagine there are a bunch of ways we could make this easier (i.e. something similar to configureHTTP2Pipeline in NIO HTTP2).

We have a handy tutorial which covers most of it if you can't wait until the proposal :wink:

3 Likes

Big +1, gRPC is often an obvious protocol choice and having this part of SSWG makes perfect sense.

1 Like

This is a strong addition to SSWG, great to see grpc-swift hit the milestone when it can be pitched. Well done everyone involved.

2 Likes

it's will be great !

Yes! I've been waiting a long time for this. Congratulations to the grpc-swift team as the project nears the 1.0 milestone.

2 Likes

I have written a small library called CombineGRPC that provides Combine framework integration for gRPC Swift. I would love to have some feedback if anybody is willing to take a look.

You can use it to make gRPC calls and implement server side RPC handlers using Combine publishers. All RPC types are supported. Here is a simple bidirectional streaming example. Protobuf:

syntax = "proto3";

service EchoService {
  rpc SayItBack (stream EchoRequest) returns (stream EchoResponse);
}

message EchoRequest {
  string message = 1;
}

message EchoResponse {
  string message = 1;
}

Server side implementation, where EchoProvider is generated by gRPC Swift:

class EchoServiceProvider: EchoProvider {  

  // Bidirectional streaming RPC that echoes back each request message
  func sayItBack(context: StreamingResponseCallContext<EchoResponse>)
    -> EventLoopFuture<(StreamEvent<EchoRequest>) -> Void>
  {
    handle(context) { requests in
      requests
        .map { req in
          EchoResponse.with { $0.message = req.message }
        }
        .setFailureType(to: GRPCStatus.self)
        .eraseToAnyPublisher()
    }
  }
}

Here's how you make RPC calls on the client side. EchoServiceClient is generated by gRPC Swift:

let echoClient = EchoServiceClient(connection: ClientConnection(configuration: configuration))
let grpc = GRPCExecutor()  // Can optionally be configured with retry policy and CallOptions

let requests = Publishers
  .Sequence(sequence: repeatElement(EchoRequest.with { $0.message = "hello"}, count: 10))
  .eraseToAnyPublisher()

grpc.call(echoClient.sayItBack)(requests)
  .filter { $0.message == "hello" }
  .count()
  .sink(receiveValue: { count in
    assert(count == 10)
  })
Terms of Service

Privacy Policy

Cookie Policy