exercise-3

command
v0.0.0-...-07ebbf2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 7, 2022 License: MIT Imports: 7 Imported by: 0

README

gRPC REST Gateway

gRPC-Gateway is a plugin of protoc. It reads a gRPC service definition and generates a reverse-proxy server which translates a RESTful JSON API into gRPC. This server is generated according to custom options in your gRPC definition.

gRPC Gateway Installation

To setup your Go environment, follow the instructions found at https://github.com/grpc-ecosystem/grpc-gateway#installation

Note that go install will install into $GOPATH/bin. In order that buf is able to find the installed plugins, make sure that the directory is in $PATH. If not, just add it: export PATH="$PATH:$(go env GOPATH)/bin"

Code Generation using Buf

The process of generating the required Go sources from the Proto files is a bit tedious when done by hand or calling the protoc compiler on the command line. The tool Buf greatly simplifies the process.

First we need to configure Buf with the correct dependencies and proto source roots. Create a file buf.yaml in the grpc-beer-gateway/ directory with the following content.

version: v1
deps:
  # add proto definitions for Google APIs as dependency
  - buf.build/googleapis/googleapis
  # add proto definitions for gRPC gateway as dependency
  - buf.build/grpc-ecosystem/grpc-gateway

Next we need to configure the different protoc plugins used to generate the required Go source files as well as an OpenAPIv2 definition of the REST interface. Create a file buf.gen.yaml in the grpc-beer-gateway/ directory with the following content.

version: v1
plugins:
  - name: go
    out: gen/go
    opt: paths=source_relative
  - name: go-grpc
    out: gen/go
    opt: paths=source_relative
  - name: grpc-gateway
    out: gen/go
    opt:
      - paths=source_relative
      - generate_unbound_methods=true
  - name: openapiv2
    out: gen/openapiv2

Also create a file buf.work.yaml with the following content:

version: v1
directories:
  - proto

Finally, you have to run buf generate in the grpc-beer-gateway/ directory to generate all the artifacts from the proto file.

Enhance gRPC Service with Google HTTP API options

The gRPC service definition needs to be enhanced with service specific options to configure how the gRPC messages are mapped to and from the HTTP body and path elements. Extend the proto/beer.proto in the grpc-beer-gateway/ directory with the following content:

import "google/api/annotations.proto";

service BeerService {
    // Get the list of all beers
    rpc AllBeers (google.protobuf.Empty) returns (GetBeersResponse) {
        option (google.api.http) = {
            // map complete gRPC response to as HTTP response
            get: "/api/beers"
        };      
    }
    // Get a single beer by Asin
    rpc GetBeer (GetBeerRequest) returns (GetBeerResponse) {
        option (google.api.http) = {
            // map asin path param to asin field in request message
            // map beer field from response message to HTTP response body
            get: "/api/beers/{asin}"
            response_body: "beer"
        };
    }
    // Create a new beer
    rpc CreateBeer (CreateBeerRequest) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            // map complete HTTP body to gRPC request message fields
            post: "/api/beers"
            body: "*"
        };
    }
    // Update an existing beer
    rpc UpdateBeer (UpdateBeerRequest) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            // map asin path param to asin field in request message
            // map HTTP request body to beer field in request message
            put: "/api/beers/{asin}"
            body: "beer"
        };
    }
    // Delete an existing beeer
    rpc DeleteBeer (DeleteBeerRequest) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            // map asin path param to asin field in request message
            delete: "/api/beers/{asin}"
        };
    }
}

After that you have to run buf generate in the grpc-beer-gateway/ directory again.

Additionally, we can generate an OpenAPI v2 definition as well. Again, we need to enhance the proto file with additional options. Extend the proto/beer.proto in the grpc-beer-gateway/ directory with the following content:

import "protoc-gen-openapiv2/options/annotations.proto";

option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
	info: {
		title: "gRPC Beer Gateway";
		version: "1.0";
		contact: {
			name: "Mario-Leander Reimer";
			url: "https://lreimer.github.io";
			email: "mario-leander.reimer@qaware.de";
		};
		license: {
			name: "MIT";
			url: "https://github.com/qaware/from-rest-to-grpc-workshop/blob/master/LICENSE";
		};		
	};
	external_docs: {
		url: "https://github.com/qaware/from-rest-to-grpc-workshop/grpc-beer-gateway";
		description: "Beer Service gRPC Gateway";
	}
	schemes: HTTP;
	schemes: HTTPS;
	consumes: "application/json";
	produces: "application/json";
};

After you have run buf generate in the grpc-beer-gateway/ directory, you will find the generated OpenAPI V2 file in gen/openapiv2/proto. Just paste it at https://editor.swagger.io/ to see if it works.

If your IDE complains that the newly added imports can't be resolved, you can fix this by copying the folders google and protoc-gen-openapiv2 into the proto folder of the grpc-beer-gateway/ directory. For Buf this is not necessary as those dependencies are already listed in the buf.yaml file.

Build and Deploy gRPC Gateway

# local development with Go (requires Go 1.17)
make build

# or containerized build
make image

# build and deploy microservice
# make sure to enable exercise-3 definitions in skaffold.yaml
skaffold dev --no-prune=false --cache-artifacts=false

# alternatively, use Tilt
# make sure to enable exercise-3 definitions in Tiltfile
tilt up

# use a HTTP client to call REST endpoints
http get localhost:18090/api/beers
curl -XGET http://localhost:18090/api/beers

Documentation

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL