diff --git a/_data/authors.yml b/_data/authors.yml index 3dba07ba3..8b51135e6 100644 --- a/_data/authors.yml +++ b/_data/authors.yml @@ -479,4 +479,14 @@ owen-voorhees: adam-ward: name: Adam Ward - about: "Adam Ward is a member of the team at Apple working on Swift tooling." \ No newline at end of file + about: "Adam Ward is a member of the team at Apple working on Swift tooling." + +george-barnett: + name: George Barnett + email: gbarnett@apple.com + github: glbrntt + about: "George Barnett is a member of a team developing Swift server networking libraries in Apple's Cloud Services organisation." + +gus-cairo: + name: Gus Cairo + github: gjcairo diff --git a/_posts/2025-02-14-grpc-swift-2.md b/_posts/2025-02-14-grpc-swift-2.md new file mode 100644 index 000000000..3ddc6c661 --- /dev/null +++ b/_posts/2025-02-14-grpc-swift-2.md @@ -0,0 +1,193 @@ +--- +layout: post +published: true +date: 2025-02-14 10:00:00 +title: Introducing gRPC Swift 2 +author: [george-barnett, gus-cairo] +--- + +Say hello to gRPC Swift 2: a major update that brings first-class concurrency +support and more expressive APIs for a seamless developer experience. + +Inconsistent and poorly documented service APIs create integration headaches for +developers. gRPC is a modern, high-performance framework for building service +APIs, enabling efficient communication between systems over a network. + +Since services may be written with a different language than their clients, most +gRPC services use [Protocol Buffers](https://protobuf.dev/) (or “protobufs”) to +define their APIs and the messages exchanged between clients and servers. +Service contracts are defined in a neutral, cross-platform format using `.proto` +files. This is the foundation of your service, not an artefact of its +implementation. And thanks to the format’s efficient binary serialization, these +messages are typically smaller and faster to process than other standard formats +like JSON. + +gRPC Swift is one of a family of similar tools that use the Protocol Buffers +contract to generate code in the language you’re working with, making it easy to +build clients and servers that adhere to your service contract. And the new gRPC +Swift 2 offers an idiomatic, cross-platform, performant and feature-rich library +for building highly-scalable services. + +This release is a major update that takes advantage of many modern Swift +features for cross-platform services development. When gRPC Swift was first +developed back in 2018, Swift had not yet introduced concurrency features like +[async/await](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/concurrency/), +so it was instead based on SwiftNIO’s event-driven concurrency model. For +developers unfamiliar with these concepts, the prior version of gRPC Swift +presented a steep learning curve. Now that Swift’s modern concurrency model is +fully established, we seized the opportunity to rethink gRPC Swift for today’s +Swift, incorporating lessons learned from our years of use at Apple for building +internet-scale services. + +## Highlights + +* Modern, flexible, and easy-to-use APIs with idiomatic generated code. +* Full support for building services and clients on Linux and Apple platforms. +* Pluggable transports including a high-performance HTTP/2 transport built on + top of [SwiftNIO](https://github.com/apple/swift-nio), and an in-process + transport which is great for testing. +* Smart client features like client-side load balancing, a pluggable name + resolution mechanism and automatic retries. +* A flexible interceptor layer allowing you to implement cross-cutting logic + like authentication, logging, and metrics. + +## Hello, swift.org! + +Consider the canonical "hello world" service with a single API which returns a +greeting. You might define it like this in a `.proto` file: + +```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 can be configured to generate: + +* Service code so you can implement the business logic. +* Client code to make requests against the service. + +Code for messages is generated by +[SwiftProtobuf](https://github.com/apple/swift-protobuf/) and used in +conjunction with the generated gRPC code. + +### Generated Service Code + +The generated code includes a Swift protocol describing the requirements of the +service with one method for each `rpc` in the service definition. To implement +the business logic of your service just implement one of the service protocols. +The example below uses the `SimpleServiceProtocol` which is the highest level +API. If you need more flexibility you can use the `ServiceProtocol` or +`StreamingServiceProtocol` which trade off conciseness for flexibility. + +To start the service you need to create a server configured to use a transport +and an instance of your service: + +```swift +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() + } +} +``` + +### Generated Client Code + +gRPC generates an idiomatic client for you, simplifying service calls. To use +it, first create a raw client and wrap it with the generated client specific to +your service. This generated client provides a type-safe way for you to easily +interact with your service. + +```swift +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) + } + } +} +``` + +## Package Ecosystem + +gRPC Swift 2 was designed with flexibility in mind. It's distributed as a +collection of packages, allowing you to pick and choose the components which +best suit your needs. These features are provided by the following packages: + +* [grpc/grpc-swift](https://github.com/grpc/grpc-swift) provides runtime + abstractions and types. +* [grpc/grpc-swift-nio-transport](https://github.com/grpc/grpc-swift-nio-transport) + implements client and server transports using HTTP/2 and is built on top of + SwiftNIO. +* [grpc/grpc-swift-protobuf](https://github.com/grpc/grpc-swift-protobuf) + integrates with [SwiftProtobuf](https://github.com/apple/swift-protobuf/) to + provide a code generator for services defined in `.proto` files. +* [grpc/grpc-swift-extras](https://github.com/grpc/grpc-swift-extras) includes + common gRPC add-ons, like the reflection and health services, integrations + with [Swift Service + Lifecycle](https://github.com/swift-server/swift-service-lifecycle), and + interceptors to trace RPCs using [OpenTelemetry](https://opentelemetry.io/). + +## Next Steps + +To get started with gRPC Swift 2 check out the [tutorials and +documentation](https://swiftpackageindex.com/grpc/grpc-swift/documentation) +which are hosted on the Swift Package Index, or try out one of the examples in +the [grpc/grpc-swift](https://github.com/grpc/grpc-swift) repository. + +If you have feature requests, want to report a bug, or would like to contribute +to the project then please reach out to us on +[GitHub](https://github.com/grpc/grpc-swift) or join us on the [Swift +forums](https://forums.swift.org/c/related-projects/grpc-swift/). Let’s connect!