隆重推出 gRPC Swift 2

向 gRPC Swift 2 问好:这是一次重大更新,带来了顶级的并发支持和更具表现力的 API,以实现无缝的开发者体验。

服务 API 文档不一致且记录不完善,给开发者带来了集成难题。gRPC 是一个现代、高性能的框架,用于构建服务 API,实现系统之间通过网络进行高效通信。

由于服务可能使用与其客户端不同的语言编写,因此大多数 gRPC 服务使用 Protocol Buffers(或 “protobufs”)来定义其 API 以及客户端和服务器之间交换的消息。服务契约以中立、跨平台的格式使用 .proto 文件定义。这是您服务的基础,而不是其实现的产物。并且由于该格式高效的二进制序列化,这些消息通常比其他标准格式(如 JSON)更小且处理速度更快。

gRPC Swift 是一系列类似工具之一,这些工具使用 Protocol Buffers 契约以您正在使用的语言生成代码,从而可以轻松构建符合您的服务契约的客户端和服务器。而新的 gRPC Swift 2 为构建高度可扩展的服务提供了一个符合语言习惯、跨平台、高性能且功能丰富的库。

此版本是一次重大更新,它利用了许多现代 Swift 功能进行跨平台服务开发。当 gRPC Swift 最初于 2018 年开发时,Swift 尚未引入 async/await 等并发功能,因此它基于 SwiftNIO 的事件驱动并发模型。对于不熟悉这些概念的开发者来说,先前版本的 gRPC Swift 提出了陡峭的学习曲线。现在 Swift 的现代并发模型已经完全确立,我们抓住了机会,为今天的 Swift 重新思考 gRPC Swift,并融入了我们在 Apple 多年使用它构建互联网规模服务的经验教训。

亮点

你好,swift.org!

考虑一个规范的 “hello world” 服务,它具有一个返回问候语的 API。您可以在 .proto 文件中像这样定义它

syntax = "proto3";

service GreetingService {
  // Returns a personalized greeting.
  rpc SayHello(SayHelloRequest) returns (SayHelloResponse);
}

message SayHelloRequest {
  // The name of the person to greet.
  string name = 1;
}

message SayHelloResponse {
  // The personalized greeting message.
  string message = 1;
}

gRPC 可以配置为生成

消息的代码由 SwiftProtobuf 生成,并与生成的 gRPC 代码结合使用。

生成的服务代码

生成的代码包括一个 Swift 协议,描述了服务的需求,服务定义中的每个 rpc 对应一个方法。要实现服务的业务逻辑,只需实现其中一个服务协议。下面的示例使用了 SimpleServiceProtocol,它是最高级别的 API。如果您需要更高的灵活性,可以使用 ServiceProtocolStreamingServiceProtocol,它们以简洁性换取灵活性。

要启动服务,您需要创建一个配置为使用传输和服务实例的服务器

import GRPCCore
import GRPCNIOTransportHTTP2

struct Greeter: GreetingService.SimpleServiceProtocol {
  func sayHello(
    request: SayHelloRequest,
    context: ServerContext
  ) async throws -> SayHelloResponse {
    return SayHelloResponse.with {
      $0.message = "Hello, \(request.name)!"
    }
  }
}

@main
struct GreeterServer {
  static func main() async throws {
    // Create a plaintext server using the SwiftNIO based HTTP/2 transport
    // listening on 128.0.0.1:8080.
    let server = GRPCServer(
      transport: .http2NIOPosix(
        address: .ipv4(host: "127.0.0.1", port: 8080),
        transportSecurity: .plaintext
      ),
      services: [Greeter()]
    )

    // Start serving indefinitely.
    try await server.serve()
  }
}

生成的客户端代码

gRPC 为您生成符合语言习惯的客户端,从而简化服务调用。要使用它,首先创建一个原始客户端,并使用特定于您服务的生成的客户端包装它。这个生成的客户端为您提供了一种类型安全的方式,以便您可以轻松地与您的服务进行交互。

import GRPCCore
import GRPCNIOTransportHTTP2

@main
struct SayHello {
  static func main() async throws {
    // Create a plaintext client using the SwiftNIO based HTTP/2 transport
    // connecting to a service listening on 128.0.0.1:8080.
    try await withGRPCClient(
      transport: .http2NIOPosix(
        target: .dns(host: "127.0.0.1", port: 8080),
        transportSecurity: .plaintext
      )
    ) { client in
      let greeter = GreetingService.Client(wrapping: client)
      let greeting = try await greeter.sayHello(.with { $0.name = "swift.org" })
      print(greeting.message)
    }
  }
}

软件包生态系统

gRPC Swift 2 在设计时就考虑了灵活性。它以软件包集合的形式分发,允许您挑选和选择最适合您需求的组件。这些功能由以下软件包提供:

后续步骤

要开始使用 gRPC Swift 2,请查看 Swift Package Index 上托管的教程和文档,或者尝试 grpc/grpc-swift 仓库中的示例之一。

如果您有功能请求、想要报告错误或想要为项目做出贡献,请在 GitHub 上联系我们,或在 Swift 论坛上加入我们。让我们连接起来!