Skip to content

Commit 4c6357d

Browse files
authored
Update tutorials to use the build plugin (#2178)
Motivation: The examples have been updated to use the build plugin; so too should the tutorials. Modifications: Update tutorials to use the build plugin. Result: Better tutorials.
1 parent f7261ad commit 4c6357d

File tree

7 files changed

+124
-54
lines changed

7 files changed

+124
-54
lines changed

Sources/GRPCCore/Documentation.docc/Tutorials/Hello-World/Hello-World.tutorial

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,28 @@
2828
@Section(title: "Run a gRPC application") {
2929
Let's start by running the existing Greeter application.
3030

31+
As a prerequisite you must have the Protocol Buffers compiler (`protoc`) installed. You can
32+
find the instructions for doing this in the [gRPC Swift Protobuf
33+
documentation](https://swiftpackageindex.com/grpc/grpc-swift-protobuf/documentation/grpcprotobuf/installing-protoc).
34+
The remainder of this tutorial assumes you installed `protoc` and it's available in
35+
your `$PATH`.
36+
37+
You may notice that the `swift` commands are all prefixed with `PROTOC_PATH=$(which protoc)`,
38+
this is to let the build system know where `protoc` is located so that it can generate stubs
39+
for you. You can read more about it in the [gRPC Swift Protobuf
40+
documentation](https://swiftpackageindex.com/grpc/grpc-swift-protobuf/documentation/grpcprotobuf/generating-stubs).
41+
3142
@Steps {
3243
@Step {
33-
In a terminal run `swift run hello-world serve` to start the server. By default it'll start
34-
listening on port 31415.
44+
In a terminal run `PROTOC_PATH=$(which protoc) swift run hello-world serve` to start the
45+
server. By default it'll start listening on port 31415.
3546

3647
@Code(name: "Console.txt", file: "hello-world-sec02-step01.txt")
3748
}
3849

3950
@Step {
40-
In another terminal run `swift run hello-world greet` to create a client, connect
41-
to the server you started and send it a request and print the response.
51+
In another terminal run `PROTOC_PATH=$(which protoc) swift run hello-world greet` to create
52+
a client, connect to the server you started and send it a request and print the response.
4253

4354
@Code(name: "Console.txt", file: "hello-world-sec02-step02.txt")
4455
}
@@ -75,19 +86,19 @@
7586
}
7687

7788
@Section(title: "Update and run the application") {
78-
You need to regenerate the stubs as the service definition has changed. To do this run the
79-
following command from the _root of the checked out repository_:
80-
81-
```console
82-
dev/protos/generate.sh
83-
```
89+
You need to regenerate the stubs as the service definition has changed. As you're using
90+
the Swift Package Manager Build Plugin for gRPC Swift the gRPC code is automatically
91+
generated if necessary when you build the example. You can learn more about generating stubs in
92+
the <doc:Generating-stubs> article.
8493

85-
To learn how to generate stubs check out the <doc:Generating-stubs> article.
86-
87-
Now that the stubs have been updated you need to implement and call the new method in the
88-
human-written parts of your application.
8994

9095
@Steps {
96+
@Step {
97+
Run `PROTOC_PATH=$(which protoc) swift build` to build the example. This will fail
98+
because the service no longer implements all of the methods declared in the `.proto` file.
99+
Let's fix that!
100+
}
101+
91102
@Step {
92103
Open `Serve.swift` in the `Subcommands` directory.
93104

@@ -114,13 +125,14 @@
114125

115126
@Step {
116127
Just like we did before, open a terminal and start the server by
117-
running `swift run hello-world serve`
128+
running `PROTOC_PATH=$(which protoc) swift run hello-world serve`
118129

119130
@Code(name: "Console.txt", file: "hello-world-sec04-step05.txt")
120131
}
121132

122133
@Step {
123-
In a separate terminal run `swift run hello-world greet` to call the server.
134+
In a separate terminal run `PROTOC_PATH=$(which protoc) swift run hello-world greet` to
135+
call the server.
124136

125137
@Code(name: "Console.txt", file: "hello-world-sec04-step06.txt")
126138
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// swift-tools-version: 6.0
2+
import PackageDescription
3+
4+
let package = Package(
5+
name: "RouteGuide",
6+
platforms: [.macOS(.v15)],
7+
dependencies: [
8+
.package(url: "https://github.com/grpc/grpc-swift.git", from: "2.0.0-beta.3"),
9+
.package(url: "https://github.com/grpc/grpc-swift-protobuf.git", from: "1.0.0-beta.3"),
10+
.package(url: "https://github.com/grpc/grpc-swift-nio-transport.git", from: "1.0.0-beta.3"),
11+
],
12+
targets: [
13+
.executableTarget(
14+
name: "RouteGuide",
15+
dependencies: [
16+
.product(name: "GRPCCore", package: "grpc-swift"),
17+
.product(name: "GRPCNIOTransportHTTP2", package: "grpc-swift-nio-transport"),
18+
.product(name: "GRPCProtobuf", package: "grpc-swift-protobuf"),
19+
],
20+
plugins: [
21+
.plugin(name: "GRPCProtobufGenerator", package: "grpc-swift-protobuf")
22+
]
23+
)
24+
]
25+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"generate": {
3+
"clients": true,
4+
"servers": true,
5+
"messages": true
6+
}
7+
}

Sources/GRPCCore/Documentation.docc/Tutorials/Route-Guide/Resources/route-guide-sec05-step00-package.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ let package = Package(
77
dependencies: [
88
.package(url: "https://github.com/grpc/grpc-swift.git", from: "2.0.0-beta.3"),
99
.package(url: "https://github.com/grpc/grpc-swift-protobuf.git", from: "1.0.0-beta.3"),
10+
.package(url: "https://github.com/grpc/grpc-swift-nio-transport.git", from: "1.0.0-beta.3"),
1011
],
1112
targets: [
1213
.executableTarget(
@@ -15,6 +16,9 @@ let package = Package(
1516
.product(name: "GRPCCore", package: "grpc-swift"),
1617
.product(name: "GRPCNIOTransportHTTP2", package: "grpc-swift-nio-transport"),
1718
.product(name: "GRPCProtobuf", package: "grpc-swift-protobuf"),
19+
],
20+
plugins: [
21+
.plugin(name: "GRPCProtobufGenerator", package: "grpc-swift-protobuf")
1822
]
1923
)
2024
]

Sources/GRPCCore/Documentation.docc/Tutorials/Route-Guide/Resources/route-guide-sec05-step01-package.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ let package = Package(
1919
],
2020
resources: [
2121
.copy("route_guide_db.json")
22+
],
23+
plugins: [
24+
.plugin(name: "GRPCProtobufGenerator", package: "grpc-swift-protobuf")
2225
]
2326
)
2427
]

Sources/GRPCCore/Documentation.docc/Tutorials/Route-Guide/Resources/route-guide-sec05-step02-package.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ let package = Package(
2121
],
2222
resources: [
2323
.copy("route_guide_db.json")
24+
],
25+
plugins: [
26+
.plugin(name: "GRPCProtobufGenerator", package: "grpc-swift-protobuf")
2427
]
2528
)
2629
]

Sources/GRPCCore/Documentation.docc/Tutorials/Route-Guide/Route-Guide.tutorial

Lines changed: 54 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,17 @@
2020
Before we can write any code we need to create a new Swift Package and configure it
2121
to depend on gRPC Swift.
2222

23+
As a prerequisite you must have the Protocol Buffers compiler (`protoc`) installed. You can
24+
find the instructions for doing this in the [gRPC Swift Protobuf
25+
documentation](https://swiftpackageindex.com/grpc/grpc-swift-protobuf/documentation/grpcprotobuf/installing-protoc).
26+
The remainder of this tutorial assumes you installed `protoc` and it's available in
27+
your `$PATH`.
28+
29+
You may notice that the `swift` commands are all prefixed with `PROTOC_PATH=$(which protoc)`,
30+
this is to let the build system know where `protoc` is located so that it can generate stubs
31+
for you. You can read more about it in the [gRPC Swift Protobuf
32+
documentation](https://swiftpackageindex.com/grpc/grpc-swift-protobuf/documentation/grpcprotobuf/generating-stubs).
33+
2334
@Steps {
2435
@Step {
2536
Create a new directory called for the package called `RouteGuide`.
@@ -84,6 +95,24 @@
8495

8596
@Code(name: "Package.swift", file: "route-guide-sec01-step08-description.swift")
8697
}
98+
99+
@Step {
100+
We'll also add a build plugin. This allows the build system to generate gRPC code at build
101+
time rather than having to generate it with separate tooling.
102+
103+
@Code(name: "Package.swift", file: "route-guide-sec01-step09-plugin.swift")
104+
}
105+
106+
@Step {
107+
A configuration file is required so that the plugin knows what to generate. Create
108+
a JSON file in the `Sources/Protos` directory called `grpc-swift-proto-generator-config.json`
109+
with this content.
110+
111+
The name of the file (`grpc-swift-proto-generator-config.json`) is important: the plugin
112+
looks for files matching this name in the source directory of your target.
113+
114+
@Code(name: "Sources/Protos/grpc-swift-proto-generator-config.json", file: "route-guide-sec01-step10-plugin-config.json")
115+
}
87116
}
88117
}
89118

@@ -93,16 +122,26 @@
93122

94123
@Steps {
95124
@Step {
96-
Create a new empty file in the `Protos` directory called `route_guide.proto`. We'll use
97-
the "proto3" syntax and our service will be part of the "routeguide" package.
125+
Create a new directory in the `Sources/Protos` directory called `routeguide`
126+
using `mkdir Sources/Protos/routeguide`.
127+
}
128+
129+
@Step {
130+
Create a new empty file in the `Sources/Protos/routeguide` directory
131+
called `route_guide.proto`. We'll use the "proto3" syntax and our service will be part of
132+
the "routeguide" package.
98133

99-
@Code(name: "Protos/route_guide.proto", file: "route-guide-sec02-step01-import.proto")
134+
It's good practice to organize your `.proto` files according to the package they are
135+
declared in, that's why we created the `routeguide` directory to match the "routeguide"
136+
package name.
137+
138+
@Code(name: "Sources/Protos/routeguide/route_guide.proto", file: "route-guide-sec02-step01-import.proto")
100139
}
101140

102141
@Step {
103142
To define a service we create a named `service` in the `.proto` file.
104143

105-
@Code(name: "Protos/route_guide.proto", file: "route-guide-sec02-step02-service.proto")
144+
@Code(name: "Sources/Protos/routeguide/route_guide.proto", file: "route-guide-sec02-step02-service.proto")
106145
}
107146

108147
@Step {
@@ -113,7 +152,7 @@
113152
A *unary RPC* where the client sends a request to the server using the stub
114153
and waits for a response to come back, just like a normal function call.
115154

116-
@Code(name: "Protos/route_guide.proto", file: "route-guide-sec02-step03-unary.proto")
155+
@Code(name: "Sources/Protos/routeguide/route_guide.proto", file: "route-guide-sec02-step03-unary.proto")
117156
}
118157

119158
@Step {
@@ -123,7 +162,7 @@
123162
example, you specify a server-side streaming method by placing the `stream`
124163
keyword before the *response* type.
125164

126-
@Code(name: "Protos/route_guide.proto", file: "route-guide-sec02-step04-server-streaming.proto")
165+
@Code(name: "Sources/Protos/routeguide/route_guide.proto", file: "route-guide-sec02-step04-server-streaming.proto")
127166
}
128167

129168
@Step {
@@ -133,7 +172,7 @@
133172
and return its response. You specify a client-side streaming method by placing
134173
the `stream` keyword before the *request* type.
135174

136-
@Code(name: "Protos/route_guide.proto", file: "route-guide-sec02-step05-client-streaming.proto")
175+
@Code(name: "Sources/Protos/routeguide/route_guide.proto", file: "route-guide-sec02-step05-client-streaming.proto")
137176
}
138177

139178
@Step {
@@ -146,53 +185,30 @@
146185
stream is preserved. You specify this type of method by placing the `stream`
147186
keyword before both the request and the response.
148187

149-
@Code(name: "Protos/route_guide.proto", file: "route-guide-sec02-step06-bidi-streaming.proto")
188+
@Code(name: "Sources/Protos/routeguide/route_guide.proto", file: "route-guide-sec02-step06-bidi-streaming.proto")
150189
}
151190

152191
@Step {
153192
The `.proto` file also contains the Protocol Buffers message type definitions for all
154193
request and response messages used by the service.
155194

156-
@Code(name: "Protos/route_guide.proto", file: "route-guide-sec02-step07-messages.proto")
195+
@Code(name: "Sources/Protos/routeguide/route_guide.proto", file: "route-guide-sec02-step07-messages.proto")
157196
}
158197
}
159198
}
160199

161200
@Section(title: "Generating client and server code") {
162201
Next we need to generate the gRPC client and server interfaces from our `.proto`
163-
service definition. We do this using the Protocol Buffer compiler, `protoc`, with
164-
two plugins: one with support for Swift (via [Swift Protobuf](https://github.com/apple/swift-protobuf))
165-
and the other for gRPC. This section assumes you already have `protoc` installed.
202+
service definition. As we're using the build plugin we just need to build our project.
166203

167204
To learn more about generating code check out the <doc:Generating-stubs> article.
168205

169206
@Steps {
170207
@Step {
171-
First we need to build the two plugins for `protoc`, `protoc-gen-swift` and
172-
`protoc-gen-grpc-swift`.
173-
174-
@Code(name: "Console", file: "route-guide-sec03-step01-protoc-plugins.txt")
175-
}
176-
177-
@Step {
178-
We'll generate the code into a separate directory within `Sources` called `Generated` which
179-
we need to create first.
180-
181-
@Code(name: "Console", file: "route-guide-sec03-step02-mkdir.txt")
182-
}
183-
184-
@Step {
185-
Now run `protoc` to generate the messages. This will create
186-
`Sources/Generated/route_guide.pb.swift`.
187-
188-
@Code(name: "Console", file: "route-guide-sec03-step03-gen-messages.txt")
189-
}
190-
191-
@Step {
192-
Run `protoc` again to generate the service code. This will create
193-
`Sources/Generated/route_guide.grpc.swift`.
208+
Build the project using `PROTOC_PATH=$(which protoc) swift build`.
194209

195-
@Code(name: "Console", file: "route-guide-sec03-step04-gen-grpc.txt")
210+
If you are using Xcode or another IDE then you'll need to set the environment variable
211+
appropriately.
196212
}
197213
}
198214
}
@@ -464,13 +480,13 @@
464480

465481
@Steps {
466482
@Step {
467-
In one terminal run `swift run RouteGuide --server` to start the server.
483+
In one terminal run `PROTOC_PATH=$(which protoc) swift run RouteGuide --server` to start the server.
468484

469485
@Code(name: "Console", file: "route-guide-sec07-step01-server.txt")
470486
}
471487

472488
@Step {
473-
In another terminal run `swift run RouteGuide` to run the client program.
489+
In another terminal run `PROTOC_PATH=$(which protoc) swift run RouteGuide` to run the client program.
474490

475491
@Code(name: "Console", file: "route-guide-sec07-step02-client.txt")
476492
}

0 commit comments

Comments
 (0)