Skip to content

Commit 3670a5e

Browse files
authored
Java: Swap linking to interactive codelab (#57)
Both Getting Starting and Streaming are now available as an interactive codelab.
1 parent 5541117 commit 3670a5e

File tree

2 files changed

+21
-913
lines changed

2 files changed

+21
-913
lines changed
Lines changed: 10 additions & 365 deletions
Original file line numberDiff line numberDiff line change
@@ -1,372 +1,17 @@
11
# Getting Started with gRPC-Java
22

3-
|||
4-
| :---- | :---- |
5-
| Summary | Get hands-on with gRPC for Java in this interactive codelab\! Perfect for Java developers new to gRPC, those seeking a refresher, or anyone building distributed systems. No prior gRPC experience needed\! |
6-
| **URL** | devsite/codelabs/docs |
3+
Get hands-on with gRPC for Java in this interactive codelab!
74

8-
# Before you begin
5+
Perfect for Java developers new to gRPC, those seeking a refresher, or anyone
6+
building distributed systems. No prior gRPC experience needed!
97

10-
## **Prerequisites**
8+
### How to use this directory
119

12-
* [JDK](https://jdk.java.net/) version 8 or higher
13-
* We recommend [openjdk temurin v21](https://cloud.google.com/java/docs/setup\#install\_a\_jdk\_java\_development\_kit)
14-
* Clone the [grpc codelab repo](https://github.com/grpc-ecosystem/grpc-codelabs.git)
10+
- [start_here](./start_here/) directory serves as a starting point for the codelab.
11+
- [completed](./completed/) directory showcases the finished code, giving you a peak of how the
12+
final implementation should look like.
1513

16-
```
17-
git clone https://github.com/grpc-ecosystem/grpc-codelabs.git
18-
```
14+
## Codelab
1915

20-
## **What you’ll learn**
21-
22-
* Get hands-on with gRPC for Java in this interactive codelab\! Perfect for Java developers new to gRPC, those seeking a refresher, or anyone building distributed systems. No prior gRPC experience needed\!
23-
* Build a complete gRPC service from scratch, learning:
24-
* Protocol Buffers (protobuf): Define service contracts & data.
25-
* gRPC Code Generation: Auto-generate Java code.
26-
* Client/Server Communication: Implement seamless interactions.
27-
* Testing & Debugging: Ensure reliability & correctness.
28-
* You'll gain:
29-
* A working gRPC service in Java.
30-
* Hands-on experience with Protocol Buffers and code generation.
31-
* Skills to design, build, & test gRPC clients and servers.
32-
* A strong foundation in gRPC for real-world projects.
33-
34-
## **What you’ll need**
35-
36-
* A computer with internet connection
37-
38-
---
39-
40-
# Setup
41-
42-
[Download](https://download-directory.github.io/?url=https%3A%2F%2Fgithub.com%2Fgrpc-ecosystem%2Fgrpc-codelabs%2Ftree%2Fmain%2Fcodelabs%2FGetting\_Started\_with\_gRPC\_Java) the codelab or Clone the codelab repo, if you haven’t yet done so.
43-
To download without using git:
44-
45-
* go to [https://github.com/grpc-ecosystem/grpc-codelabs.git](https://github.com/grpc-ecosystem/grpc-codelabs.git)
46-
* click on \`\<\> Code\`
47-
* select \`Download ZIP\`
48-
49-
Change directory to `codelabs/grpc-java-getting-started/start_here`
50-
51-
Tip: For complete versions of each of the files we are editing, look in the `../complete` directory
52-
53-
# Define proto
54-
55-
Duration: 5:00
56-
57-
Our first step is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers](https://protobuf.dev/overview).
58-
59-
Let’s create a `route_guide.proto` file.
60-
We’ve given you some boiler plate to start with in `src/main/proto/routeguide/route_guide.proto`
61-
62-
Since we’re generating Java code in this example, we’ve specified a `java_package` file option and a name for the Java class in our `.proto`:
63-
64-
```
65-
option java_package = "io.grpc.examples.routeguide";
66-
option java_outer_classname = "RouteGuideProto";
67-
```
68-
69-
## **Define proto Message**
70-
71-
Our `.proto` file contains protocol buffer message type definitions for all the request and response types used in our service methods.
72-
73-
Let’s define the `Point` message type (`a latitude and a longitude, both multiplied by 10**7`):
74-
75-
```
76-
// Points are represented as latitude-longitude pairs in the E7 representation(degrees times 10**7).
77-
// Latitudes should be in the range +/- 90 degrees.
78-
// Longitude should be in the range +/- 180 degrees.
79-
80-
message Point {
81-
int32 latitude = 1;
82-
int32 longitude = 2;
83-
}
84-
```
85-
86-
Let’s also define the `Feature` message type (`A feature names something at a given point`):
87-
88-
```
89-
// A feature names something at a given point.
90-
//
91-
// If a feature could not be named, the name is empty.
92-
93-
message Feature {
94-
// The name of the feature.
95-
string name = 1;
96-
97-
// The point where the feature is detected.
98-
Point location = 2;
99-
}
100-
```
101-
102-
## **Define RouteGuide service**
103-
104-
To define a service, you specify a named service in your `.proto` file:
105-
106-
```
107-
service RouteGuide {
108-
// Definition of the service goes here
109-
}
110-
```
111-
112-
## **Define RPC Method**
113-
114-
Then you define `rpc` methods inside your service definition, specifying their request and response types. In this section of the codelab, let’s define
115-
116-
* A Unary RPC method \- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call.
117-
118-
```
119-
// Obtains the feature at a given position.
120-
rpc GetFeature(Point) returns (Feature) {}
121-
```
122-
123-
---
124-
125-
# Generating client and server code
126-
127-
Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC Java plugin. You need to use the [proto3](https://github.com/google/protobuf/releases) compiler (which supports both proto2 and proto3 syntax) in order to generate gRPC services.
128-
129-
When using Gradle or Maven, the protoc build plugin can generate the necessary code as part of the build. You can refer to the [grpc-java README](https://github.com/grpc/grpc-java/blob/master/README.md) for how to generate code from your own `.proto` files.
130-
131-
We have provided Gradle configuration.
132-
133-
134-
| Note: You may need to do `chmod +x ../gradlew` if you downloaded a zip instead of doing `git clone`. |
135-
| :---- |
136-
137-
From the `start_here` directory enter
138-
139-
```
140-
../gradlew build
141-
```
142-
143-
The following classes are generated from our service definition:
144-
145-
* `Feature.java`, `Point.java` and others which contain all the protocol buffer code to populate, serialize, and retrieve our request and response message types.
146-
* `RouteGuideGrpc.java` which contains (along with some other useful code):
147-
* a base class for `RouteGuide` servers to implement, `RouteGuideGrpc.RouteGuideImplBase`, with all the methods defined in the `RouteGuide` service
148-
* Stub classes for clients to use
149-
150-
---
151-
152-
# Creating the server
153-
154-
Duration: 5:00
155-
156-
First let’s look at how we create a `RouteGuide` server. There are two parts to making our `RouteGuide` service do its job:
157-
158-
* Implementing the service interface generated from our service definition: doing the actual “work” of our service.
159-
* Running a gRPC server to listen for requests from clients and dispatch them to the right service implementation.
160-
161-
## **Implementing RouteGuide**
162-
163-
As you can see, our server has a `RouteGuideService` class that extends the generated `RouteGuideGrpc.RouteGuideImplBase` abstract class:
164-
165-
```java
166-
private static class RouteGuideService extends RouteGuideGrpc.RouteGuideImplBase {
167-
...
168-
}
169-
```
170-
171-
We have provided the following 2 files for initializing your server with features
172-
`./src/main/java/io/grpc/examples/routeguide/RouteGuideUtil.java`
173-
`./src/main/resources/io/grpc/examples/routeguide/route_guide_db.json`
174-
175-
Let us look into a simple RPC implementation in detail
176-
177-
### **Unary RPC**
178-
179-
`RouteGuideService` implements all our service methods, in this case it is just `GetFeature()`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`.
180-
We include `checkFeature`. The most important aspect is creating a `Feature` object
181-
182-
**Feature.newBuilder().setName("").setLocation(location).build();**| // Creates a feature.
183-
---|---
184-
185-
```java
186-
@Override
187-
public void getFeature(Point request, StreamObserver<Feature> responseObserver) {
188-
responseObserver.onNext(checkFeature(request));
189-
responseObserver.onCompleted();
190-
}
191-
```
192-
193-
The `getFeature()` method takes two parameters:
194-
195-
* `Point`: the request
196-
* `StreamObserver<Feature>`: a response observer, which is a special interface for the server to call with its response.
197-
198-
To return our response to the client and complete the call:
199-
200-
1. We construct and populate a `Feature` response object to return to the client, as specified in our service definition. In this example, we do this in a separate private `checkFeature()` method.
201-
2. We use the response observer’s `onNext()` method to return the `Feature`.
202-
3. We use the response observer’s `onCompleted()` method to specify that we’ve finished dealing with the RPC.
203-
204-
---
205-
206-
# Starting the gRPC server
207-
208-
Duration: 5:00
209-
210-
Once we’ve implemented all our service methods, we need to start up a gRPC server so that clients can actually use our service. We include in our boilerplate the creation of the ServerBuilder object:
211-
212-
`ServerBuilder.forPort(port), port, RouteGuideUtil.parseFeatures(featureFile)`
213-
214-
We build the service in the constructor:
215-
216-
1. Specify the port we want to use to listen for client requests using the builder’s `forPort()` method (it will use the wildcard address).
217-
2. Create an instance of our service implementation class `RouteGuideService` and pass it to the builder’s `addService()` method.
218-
3. Call `build()` on the builder to create an RPC server for our service.
219-
220-
The following snippet shows how we create a `ServerBuilder` object.
221-
222-
223-
```java
224-
this(Grpc.newServerBuilderForPort(port, InsecureServerCredentials.create()),
225-
port, RouteGuideUtil.parseFeatures(featureFile));
226-
```
227-
228-
The following snippet shows how we create a server object for our `RouteGuide` service.
229-
230-
```java
231-
/** Create a RouteGuide server using serverBuilder as a base and features as data. */
232-
public RouteGuideServer(ServerBuilder<?> serverBuilder, int port, Collection<Feature> features) {
233-
this.port = port;
234-
server = serverBuilder.addService(new RouteGuideService(features))
235-
.build();
236-
}
237-
```
238-
239-
Implement a start method that calls `start` on the server we created above
240-
241-
```java
242-
public void start() throws IOException {
243-
server.start();
244-
logger.info("Server started, listening on " + port);
245-
}
246-
```
247-
248-
Implement a method to wait for the server to complete so it doesn’t immediately exit.
249-
250-
```java
251-
/** Await termination on the main thread since the grpc library uses daemon threads. */
252-
private void blockUntilShutdown() throws InterruptedException {
253-
if (server != null) {
254-
server.awaitTermination();
255-
}
256-
}
257-
```
258-
259-
As you can see, we build and start our server using a `ServerBuilder`.
260-
261-
In the main method we
262-
263-
1. Create a `RouteGuideServer` instance
264-
2. Call `start()` to activate an RPC server for our service.
265-
3. Wait for the service to be stopped by calling `blockUntilShutdown()`
266-
267-
```java
268-
public static void main(String[] args) throws Exception {
269-
RouteGuideServer server = new RouteGuideServer(8980);
270-
server.start();
271-
server.blockUntilShutdown();
272-
}
273-
```
274-
275-
---
276-
277-
# Creating the client
278-
279-
Duration: 5:00
280-
281-
In this section, we’ll look at creating a client for our `RouteGuide` service. You can see our complete example client code in ../complete/src/main/java/io/grpc/examples/routeguide/RouteGuideClient.java
282-
283-
## **Instantiating a stub**
284-
285-
To call service methods, we first need to create a *stub*. There are two types of stubs, but we only need to use the blocking one for this codelab. The 2 types are:
286-
287-
* a *blocking/synchronous* stub: this means that the RPC call waits for the server to respond, and will either return a response or raise an exception.
288-
* a *non-blocking/asynchronous* stub that makes non-blocking calls to the server, where the response is returned asynchronously. You can make certain types of streaming calls only by using the asynchronous stub.
289-
290-
First we need to create a gRPC *channel* and then use the channel to create our stub.
291-
292-
We could have used a `ManagedChannelBuilder` directly to create the channel.
293-
294-
```java
295-
ManagedChannelBuilder.forAddress(host, port).usePlaintext().build
296-
```
297-
298-
But let’s use a utility method that takes a string with `hostname:port`
299-
300-
```java
301-
Grpc.newChannelBuilder(target, InsecureChannelCredentials.create()).build();
302-
```
303-
304-
Now we can use the channel to create our blocking stub. For this codelab, we only have blocking RPCs, so we use the `newBlockingStub` method provided in the `RouteGuideGrpc` class we generated from our `.proto`.
305-
306-
```java
307-
blockingStub = RouteGuideGrpc.newBlockingStub(channel);
308-
```
309-
310-
## **Calling service methods**
311-
312-
Now let’s look at how we call our service methods.
313-
314-
### **Simple RPC**
315-
316-
Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local method.
317-
318-
We create and populate a request protocol buffer object (in our case `Point`), pass it to the `getFeature()` method on our blocking stub, and get back a `Feature`.
319-
320-
If an error occurs, it is encoded as a `Status`, which we can obtain from the `StatusRuntimeException`.
321-
322-
```java
323-
Point request = Point.newBuilder().setLatitude(lat).setLongitude(lon).build();
324-
325-
Feature feature;
326-
try {
327-
feature = blockingStub.getFeature(request);
328-
} catch (StatusRuntimeException e) {
329-
logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
330-
return;
331-
}
332-
```
333-
334-
The boilerplate logs a message containing the contents based on whether or not there was a feature at the specified point.
335-
336-
---
337-
338-
# Try it out\!
339-
340-
Duration: 2:00
341-
342-
## **To build the codelab**
343-
344-
1. From the `start_here` directory:
345-
346-
```
347-
$ ../gradlew installDist
348-
```
349-
350-
This will compile your code, package it in a jar and create the scripts that run the example. They will be created in the `build/install/start_here/bin/` directory. The scripts are: `route-guide-server` and `route-guide-client`.
351-
352-
The server needs to be running before starting the client.
353-
354-
2. Run the server:
355-
356-
```
357-
$ ./build/install/start_here/bin/route-guide-server
358-
```
359-
360-
3. Run the client:
361-
362-
```
363-
$ ./build/install/start_here/bin/route-guide-client
364-
```
365-
366-
---
367-
368-
# What’s next
369-
370-
* Do the streaming code lab gRPC Java Streaming (../../grpc-java-streaming)
371-
* Learn how gRPC works in [Introduction to gRPC](https://grpc.io/docs/what-is-grpc/introduction/) and [Core concepts](https://grpc.io/docs/what-is-grpc/core-concepts/).
372-
* Explore the [API reference](https://grpc.io/docs/languages/java/api).
16+
Follow the codelab at:
17+
https://codelabs.developers.google.com/grpc/getting-started-grpc-java

0 commit comments

Comments
 (0)