Skip to content

Reworked Go quick start #183

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 16, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
217 changes: 143 additions & 74 deletions content/docs/quickstart/go.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,98 +3,148 @@ title: Go Quick Start
layout: quickstart
short: Go
description: This guide gets you started with gRPC in Go with a simple working example.
protoc-version: 3.11.4
---

### Prerequisites
<style type="text/css">
ol ol { list-style-type: lower-alpha !important; }
</style>

- Go version 1.6 or higher.
### Prerequisites

For installation instructions, see Go's [Getting Started](https://golang.org/doc/install) guide.
- **[Go][]**, any one of the **three latest major** [releases of Go][]. For
installation instructions, see Go's [Getting Started][] guide.

#### gRPC

Use the following command to install gRPC.
Use the following command to install gRPC as a [module][]:

```sh
$ go get -u google.golang.org/grpc
$ export GO111MODULE=on # Enable module-aware mode
$ go get google.golang.org/grpc@{{< param grpc_release_tag >}}
```

#### Protocol Buffers v3
#### Protocol Buffers

Install the protoc compiler that is used to generate gRPC service code. The simplest way to do this is to download pre-compiled binaries for your platform(`protoc-<version>-<platform>.zip`) from here: [https://github.com/google/protobuf/releases](https://github.com/google/protobuf/releases)
While not mandatory, gRPC applications usually leverage [Protocol Buffers][pb]
for service definitions and data serialization, and the example code uses
[proto3][].

* Unzip this file.
* Update the environment variable `PATH` to include the path to the protoc binary file.
1. Install the `protoc` compiler:

Next, install the protoc plugin for Go
1. Download a zip file of the latest version of pre-compiled binaries for
your operating system from [github.com/google/protobuf/releases][]
(`protoc-<version>-<os><arch>.zip`). For example:

```sh
$ go get -u github.com/golang/protobuf/protoc-gen-go
```
```sh
$ PB_REL="https://github.com/protocolbuffers/protobuf/releases"
$ curl -LO $PB_REL/download/v{{< param protoc-version >}}/protoc-{{< param protoc-version >}}-linux-x86_64.zip
```

The compiler plugin, `protoc-gen-go`, will be installed in `$GOBIN`, defaulting
to `$GOPATH/bin`. It must be in your `PATH` for the protocol compiler, protoc,
to find it.
2. Unzip the file under `$HOME/.local` or a directory of your choice. For
example:

```sh
$ export PATH=$PATH:$GOPATH/bin
```
```sh
$ unzip protoc-{{< param protoc-version >}}-linux-x86_64.zip -d $HOME/.local
```

### Download the example
3. Update your environment's path variable to include the path to the
`protoc` executable. For example:

The grpc code that was fetched with `go get google.golang.org/grpc` also contains the examples. They can be found under the examples dir: `$GOPATH/src/google.golang.org/grpc/examples`.
```sh
$ export PATH="$PATH:$HOME/.local/bin"
```

### Build the example
> **MacOS note**: Using [Homebrew][]? Simply run: `brew install protobuf`.

Change to the example directory
2. The `protoc` plugin for Go (`protoc-gen-go`) was installed as a dependency
of the `grpc` module. You can confirm this, or install the plugin, using the
following command:

```sh
$ cd $GOPATH/src/google.golang.org/grpc/examples/helloworld
```
```sh
$ go get github.com/golang/protobuf/protoc-gen-go
```

gRPC services are defined in a `.proto` file, which is used to generate a
corresponding `.pb.go` file. The `.pb.go` file is generated by compiling the
`.proto` file using the protocol compiler: `protoc`.
3. Update your `PATH` so that the `protoc` compiler can find the plugin:

For the purpose of this example, the `helloworld.pb.go` file has already been
generated (by compiling `helloworld.proto`), and can be found in this directory:
`$GOPATH/src/google.golang.org/grpc/examples/helloworld/helloworld`
```sh
$ export PATH="$PATH:$(go env GOPATH)/bin"
```

This `helloworld.pb.go` file contains:
### Copy the example

- Generated client and server code.
- Code for populating, serializing, and retrieving our `HelloRequest` and
`HelloReply` message types.
The example code is part of the `grpc` source, which you fetched by following
steps of the previous section. You'll need a local copy of the example code to
work through this quick start.

1. Choose a suitable working directory, and ensure that it exists:

### Try it!
```sh
$ export MY_EXAMPLES="$HOME/examples"
$ mkdir -p "$MY_EXAMPLES"
```

To compile and run the server and client code, the `go run` command can be used.
In the examples directory:
2. Copy the example source:

```sh
$ go run greeter_server/main.go
```
```sh
$ EX_SRC_DIR="$(go env GOPATH)/pkg/mod/google.golang.org/grpc@{{< param grpc_release_tag >}}/examples"
$ cp -R "$EX_SRC_DIR/helloworld" "$MY_EXAMPLES"
```

From a different terminal:
3. Ensure that the example files are writable since you'll be making changes soon:

```sh
$ go run greeter_client/main.go
```
```sh
$ chmod -R u+w "$MY_EXAMPLES/helloworld"
```

4. Change to the example's directory:

If things go smoothly, you will see the `Greeting: Hello world` in the client side output.
```sh
$ cd "$MY_EXAMPLES/helloworld"
```

5. Setup the example as a module:

```sh
$ go mod init examples/helloworld
```

6. Adjust import paths to reference local packages (rather than those from the
original `google.golang.org/grpc` module):

```sh
$ perl -pi -e 's|google.golang.org/grpc/||g' greeter_{client,server}/main.go
```

### Run the example

From the `$MY_EXAMPLES/helloworld` directory:

1. Compile and execute the server code:

```sh
$ go run greeter_server/main.go
```

2. From a different terminal, compile and execute the client code to see the
client output:

```sh
$ go run greeter_client/main.go
Greeting: Hello world
```

Congratulations! You've just run a client-server application with gRPC.

### Update a gRPC service

Now let's look at how to update the application with an extra method on the
server for the client to call. Our gRPC service is defined using protocol
buffers; you can find out lots more about how to define a service in a `.proto`
file in [What is gRPC?](/docs/guides) and [gRPC Basics:
Go](/docs/tutorials/basic/go/). For now all you need to know is that both the server and the client
"stub" have a `SayHello` RPC method that takes a `HelloRequest` parameter from
the client and returns a `HelloReply` from the server, and that this method
is defined like this:
In this section you'll update the application with an extra server method. The
gRPC service is defined using [protocol buffers][pb]. To learn more about how to
define a service in a `.proto` file see [gRPC Basics:
Go](/docs/tutorials/basic/go). For now, all you need to know is that both the
server and the client stub have a `SayHello()` RPC method that takes a
`HelloRequest` parameter from the client and returns a `HelloReply` from the
server, and that the method is defined like this:

```protobuf
// The greeting service definition.
Expand All @@ -114,12 +164,8 @@ message HelloReply {
}
```

Let's update this so that the `Greeter` service has two methods. Make sure you
are in the same examples dir as above
(`$GOPATH/src/google.golang.org/grpc/examples/helloworld`).

Edit `helloworld/helloworld.proto` and update it with a new `SayHelloAgain`
method, with the same request and response types:
Edit `helloworld/helloworld.proto` and add a new `SayHelloAgain()` method, with
the same request and response types:

```protobuf
// The greeting service definition.
Expand All @@ -141,26 +187,33 @@ message HelloReply {
}
```

### Generate gRPC code
Remember to save the file!

Next we need to update the gRPC code used by our application to use the new
service definition. From the same examples dir as above
(`$GOPATH/src/google.golang.org/grpc/examples/helloworld`):
### Regenerate gRPC code

Before you can use the new service method, you need to recompile the updated
proto file.

From the `$MY_EXAMPLES/helloworld` directory, run the following command:

```sh
$ protoc -I helloworld/ helloworld/helloworld.proto --go_out=plugins=grpc:helloworld
```

This regenerates the helloworld.pb.go with our new changes.
This will regenerate the `helloworld/helloworld.pb.go` file, which contains:

- Code for populating, serializing, and retrieving `HelloRequest` and
`HelloReply` message types.
- Generated client and server code.

### Update and run the application

We now have new generated server and client code, but we still need to implement
and call the new method in the human-written parts of our example application.
You have regenerated server and client code, but you still need to implement
and call the new method in the human-written parts of the example application.

#### Update the server

Edit `greeter_server/main.go` and add the following function to it:
Open `greeter_server/main.go` and add the following function to it:

```go
func (s *server) SayHelloAgain(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
Expand All @@ -170,7 +223,8 @@ func (s *server) SayHelloAgain(ctx context.Context, in *pb.HelloRequest) (*pb.He

#### Update the client

Edit `greeter_client/main.go` to add the following code to the main function.
Open `greeter_client/main.go` to add the following code to the end of the
`main()` function body:

```go
r, err = c.SayHelloAgain(ctx, &pb.HelloRequest{Name: name})
Expand All @@ -180,25 +234,31 @@ if err != nil {
log.Printf("Greeting: %s", r.GetMessage())
```

Remember to save your changes.

#### Run!

Run the client and server like you did before. Execute the following commands
from the `examples/helloworld` directory:

1. Run the server:

```sh
$ go run greeter_server/main.go
```

2. On a different terminal, run the client:
2. From another terminal, run the client. This time, add a name as a
command-line argument:

```sh
$ go run greeter_client/main.go
$ go run greeter_client/main.go Alice
```

You'll see the following output:

```sh
Greeting: Hello world
Greeting: Hello again world
Greeting: Hello Alice
Greeting: Hello again Alice
```

### What's next
Expand All @@ -208,3 +268,12 @@ log.Printf("Greeting: %s", r.GetMessage())
- Work through a more detailed tutorial in [gRPC Basics: Go](/docs/tutorials/basic/go/).
- Explore the gRPC Go core API in its [reference
documentation](https://godoc.org/google.golang.org/grpc).

[github.com/google/protobuf/releases]: https://github.com/google/protobuf/releases
[Getting Started]: https://golang.org/doc/install
[Go]: https://golang.org
[Homebrew]: https://brew.sh
[module]: https://github.com/golang/go/wiki/Modules
[pb]: https://developers.google.com/protocol-buffers
[proto3]: https://developers.google.com/protocol-buffers/docs/proto3
[releases of Go]: https://golang.org/doc/devel/release.html