Skip to content
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

[GSoD 2020] Added tutorials directory on gRPC-Gateway #1829

Merged
merged 19 commits into from
Dec 1, 2020
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion docs/docs/faq.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
layout: default
title: FAQ
nav_order: 7
nav_order: 8
---

# FAQ
Expand Down
7 changes: 7 additions & 0 deletions docs/docs/tutorials/Generating stubs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
layout: default
title: Generating stubs
parent: Tutorials
nav_order: 1
has_children: true
---
42 changes: 42 additions & 0 deletions docs/docs/tutorials/Generating stubs/using_buf.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
layout: default
title: Generating stubs using buf
parent: Generating stubs
grand_parent: Tutorials
nav_order: 1
---

## Generating stubs using buf

Buf is configured through a `buf.yaml` file that should be checked in to the root of your repository. Buf will automatically read this file if present. Configuration can also be provided via the command-line flag `--config`, which accepts a path to a `.json` or `.yaml` file, or direct JSON or YAML data.
iamrajiv marked this conversation as resolved.
Show resolved Hide resolved

All Buf operations that use your local `.proto` files as input rely on a valid build configuration. This configuration tells Buf where to search for `.proto` files, and how to handle imports. As opposed to protoc, where all `.proto` files are manually specified on the command-line, buf operates by recursively discovering all `.proto` files under configuration and building them.

The following is an example of all configuration options for the build.
iamrajiv marked this conversation as resolved.
Show resolved Hide resolved

```yml
version: v1beta1
build:
roots:
- proto
- vendor/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis
iamrajiv marked this conversation as resolved.
Show resolved Hide resolved
excludes:
- proto/foo/bar
iamrajiv marked this conversation as resolved.
Show resolved Hide resolved
```

To generate stubs for for multiple languages. Create the file `buf.gen.yaml` at the root of the repository:
iamrajiv marked this conversation as resolved.
Show resolved Hide resolved

```yml
version: v1beta1
plugins:
- name: java
out: java
- name: cpp
out: cpp
iamrajiv marked this conversation as resolved.
Show resolved Hide resolved
```

johanbrandhorst marked this conversation as resolved.
Show resolved Hide resolved
Then run

```sh
buf generate --file ./proto/example.proto
iamrajiv marked this conversation as resolved.
Show resolved Hide resolved
```
johanbrandhorst marked this conversation as resolved.
Show resolved Hide resolved
39 changes: 39 additions & 0 deletions docs/docs/tutorials/Generating stubs/using_protoc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
layout: default
title: Generating stubs using protoc
parent: Generating stubs
grand_parent: Tutorials
nav_order: 2
---

## Generating stubs using protoc

1. Define your [gRPC](https://grpc.io/docs/) service using protocol buffers

`your_service.proto`:

```protobuf
syntax = "proto3";
package your.service.v1;
option go_package = "github.com/yourorg/yourprotos/gen/go/your/service/v1";
message StringMessage {
string value = 1;
}

service YourService {
rpc Echo(StringMessage) returns (StringMessage) {}
}
```
iamrajiv marked this conversation as resolved.
Show resolved Hide resolved

2. Generate gRPC stubs

This step generates the gRPC stubs that you can use to implement the service and consume from clients.

Here's an example of what a `protoc` command might look like to generate Go stubs:

```sh
protoc -I . \
--go_out ./gen/go/ --go_opt paths=source_relative \
--go-grpc_out ./gen/go/ --go-grpc_opt paths=source_relative \
your/service/v1/your_service.proto
```
iamrajiv marked this conversation as resolved.
Show resolved Hide resolved
91 changes: 91 additions & 0 deletions docs/docs/tutorials/basic_arithmetic_grpc_server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
layout: default
title: Creating a Basic Arithmetic gRPC Server
parent: Tutorials
nav_order: 3
---

## Creating a Basic Arithmetic gRPC Server

First look at the `main.go` file of Arithmetic server that will serve on a given port and listening at the endpoint we defined in proto files.
iamrajiv marked this conversation as resolved.
Show resolved Hide resolved

At the top of the file, we define the handlers for our gRPC methods.

Handlers are:

```go
// This is the struct that we will implement all the handlers on
type Server struct {
a *pbExample.Request
b *pbExample.Request
Result *pbExample.Response
}

// This is where you implement the handler for the Add method
func (s *Server) Add(ctx context.Context, request *pbExample.Request) (*pbExample.Response, error) {
a, b := request.GetA(), request.GetB()

result := a + b

return &pbExample.Response{Result: result}, nil
}

// This is where you implement the handler for the Divide method
func (s *Server) Divide(ctx context.Context, request *pbExample.Request) (*pbExample.Response, error) {
a, b := request.GetA(), request.GetB()

result := a / b

return &pbExample.Response{Result: result}, nil
}

// This is where you implement the handler for the Multiply method
func (s *Server) Multiply(ctx context.Context, request *pbExample.Request) (*pbExample.Response, error) {
a, b := request.GetA(), request.GetB()

result := a * b

return &pbExample.Response{Result: result}, nil
}

// This is where you implement the handler for the Subtract method
func (s *Server) Subtract(ctx context.Context, request *pbExample.Request) (*pbExample.Response, error) {
a, b := request.GetA(), request.GetB()

result := a - b

return &pbExample.Response{Result: result}, nil
}
iamrajiv marked this conversation as resolved.
Show resolved Hide resolved
```

Now rest fo `main.go` file are:
iamrajiv marked this conversation as resolved.
Show resolved Hide resolved

```go
func main() {

// Adds gRPC internal logs. This is quite verbose, so adjust as desired!
log := grpclog.NewLoggerV2(os.Stdout, ioutil.Discard, ioutil.Discard)
grpclog.SetLoggerV2(log)

addr := "0.0.0.0:10000"
lis, err := net.Listen("tcp", addr)
if err != nil {
log.Fatalln("Failed to listen:", err)
}

s := grpc.NewServer(
// TODO: Replace with your own certificate!
grpc.Creds(credentials.NewServerTLSFromCert(&insecure.Cert)),
)
pbExample.RegisterArithmeticServiceServer(s, &Server{})

// Serve gRPC Server
log.Info("Serving gRPC on https://", addr)
go func() {
log.Fatal(s.Serve(lis))
}()

err = gateway.Run("dns:///" + addr)
log.Fatalln(err)
}
```
110 changes: 110 additions & 0 deletions docs/docs/tutorials/basic_protos.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
layout: default
title: Creating a basic protos with HTTP annotations
parent: Tutorials
nav_order: 2
---

## Creating a basic protos with HTTP annotations

### Annotating your gRPC .proto file with HTTP bindings and routes

The annotations define how gRPC services map to the JSON request and response. When using protocol buffers, each RPC must define the HTTP method and path using the `google.api.http` annotation.

So you will need to add `import "google/api/annotations.proto";` to the gRPC proto file.

To make a Basic Arithmetic service first we have to define our services in proto files.
johanbrandhorst marked this conversation as resolved.
Show resolved Hide resolved
iamrajiv marked this conversation as resolved.
Show resolved Hide resolved

```proto
syntax="proto3";

package example;

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

// Defines the import path that should be used to import the generated package,
// and the package name.
option go_package = "github.com/iamrajiv/Basic-Arithmetic-gRPC-Server/proto;example";

// These annotations are used when generating the OpenAPI file.
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
info: {
version: "1.0";
};
external_docs: {
url: "https://github.com/iamrajiv/Basic-Arithmetic-gRPC-Server";
description: "Basic-Arithmetic-gRPC-Server";
}
schemes: HTTPS;
};

// This will be our request
message Request {
// First integer in the body of the request
int64 a = 1;
// Second integer in the body of the request
int64 b = 2;
}

// This will be our response
message Response {
// A integer in the body of the response
int64 result = 1;
}

// Here is the overall service where we define all our endpoints
service ArithmeticService {
// Here is our Add method to use as an service
rpc Add(Request) returns (Response){
option (google.api.http) = {
post: "/api/v1/arithmetic/add"
body: "*"
};
};
// Here is our Divide method to use as an service
rpc Divide(Request) returns (Response){
option (google.api.http) = {
post: "/api/v1/arithmetic/div"
body: "*"
};
};
// Here is our Multiply method to use as an service
rpc Multiply(Request) returns (Response){
option (google.api.http) = {
post: "/api/v1/arithmetic/mul"
body: "*"
};
};
// Here is our Subtract method to use as an service
rpc Subtract(Request) returns (Response){
option (google.api.http) = {
post: "/api/v1/arithmetic/sub"
body: "*"
};
};
}
```

### HTTP method and path

- The first key (`post` in this service) corresponds to the HTTP method. RPCs **may** use `get`, `post`, `patch`, or `delete`.
- RPCs **must** use the prescribed HTTP verb for each standard method, as discussed in [AIP-131](https://google.aip.dev/131), [AIP-132](https://google.aip.dev/132), [AIP-133](https://google.aip.dev/133), [AIP-134](https://google.aip.dev/134), and [AIP-135](https://google.aip.dev/135)
- RPCs **should** use the prescribed HTTP verb for custom methods, as discussed in [AIP-136](https://google.aip.dev/136).
- RPCs **should not** use `put` or `custom`.
- The corresponding value represents the URI.
- URIs **must** use the `{foo=bar/*}` syntax to represent a variable that should be populated in the request proto. When extracting a [resource name](https://google.aip.dev/122), the variable **must** include the entire resource name, not just the ID component.
- URIs **must** use the `` character to represent ID components, which matches all URI-safe characters except for `/`. URIs **may** use `*` as the final segment of a URI if matching `/` is required.
- The `body` key defines which field in the request will be sent as the HTTP body. If the body is ``, then this indicates that the request object itself is the HTTP body. The request body is encoded as JSON as defined by protocol buffers' canonical [JSON encoding](https://developers.google.com/protocol-buffers/docs/proto3#json).
- RPCs **must not** define a `body` at all for RPCs that use the `GET` or `DELETE` HTTP verbs.
- RPCs **must** use the prescribed `body` for Create ([AIP-133](https://google.aip.dev/133)) and Update ([AIP-134](https://google.aip.dev/134)) requests.
- RPCs **should** use the prescribed `body` for custom methods ([AIP-136](https://google.aip.dev/136)).
- Fields **should not** use the `json_name` annotation to alter the field name in JSON, unless doing so for backwards-compatibility reasons.

You’ll see some atypical fields in the .proto that are leveraged by grpc-gateway. One of the most important of these fields is the option (google.api.http) where we define what HTTP URL(s) will be used to handle our request.

We also specify POST as the HTTP method we will accept.

Finally, if you have a request body that you expect (typical for POST requests and others), you must use the body field. If you don’t, then the request won’t be passed along to the handler.

Read more about HTTP and gRPC Transcoding on https://google.aip.dev/127.
iamrajiv marked this conversation as resolved.
Show resolved Hide resolved
6 changes: 6 additions & 0 deletions docs/docs/tutorials/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
layout: default
title: Tutorials
nav_order: 7
has_children: true
---
Loading