How to Integrate Swagger UI with gRPC
What is gRPC? Are you looking to integrate Swagger UI with gRPC? Here is a step-by-step guide to tell you.
What is gRPC
gRPC is an RPC-based framework designed for HTTP2. Therefore, the advantages of gRPC naturally include the advantages of HTTP2: Binary framing for data transmission, Multiplexing, Server push, and Header compression.
What is Swagger
Swagger is a specification and comprehensive framework for generating, describing, invoking, and visualizing RESTful-style web services. The overall goal is to enable clients and file systems to update at the same speed as the server. The methods, parameters, and models of the files are closely integrated into the server-side code, allowing the API to stay in sync consistently. Swagger makes deployment, management, and usage of powerful APIs more accessible than ever before.
How to enable Swagger for gRPC
Prerequisites
Users familiar with gRPC should know that protocol buffer files need to be compiled into .go files using the relevant command-line tools.
Depending on the requirements, different command-line files may be used. Taking the Go language as an example, we generally need the following command-line tools.
In addition to installing the aforementioned command-line tools, we also need to run at least four different commands to compile *.proto files, which can be quite obscure and difficult to understand.
Installation
go get github.com/rookie-ninja/rk-boot
go get github.com/rookie-ninja/rk-grpc
Getting Started
1、Creating API**/v1/greeter.proto**
syntax = "proto3";
package api.v1;
option go_package = "api/v1/greeter";
service Greeter {
rpc Greeter (GreeterRequest) returns (GreeterResponse) {}
}
message GreeterRequest {
string name = 1;
}
message GreeterResponse {
string message = 1;
}
2、Creating API**/v1/gw_mapping.yaml**
type: google.api.Service
config_version: 3
# Please refer google.api.Http in https://github.com/googleapis/googleapis/blob/master/google/api/http.proto file for details.
http:
rules:
- selector: api.v1.Greeter.Greeter
get: /api/v1/greeter
3、Creating buf**.** yaml
version: v1beta1
name: github.com/rk-dev/rk-demo
build:
roots:
- api
4、Creating buf**.** gen.yaml
version: v1beta1
plugins:
# protoc-gen-go needs to be installed, generate go files based on proto files
- name: go
out: api/gen
opt:
- paths=source_relative
# protoc-gen-go-grpc needs to be installed, generate grpc go files based on proto files
- name: go-grpc
out: api/gen
opt:
- paths=source_relative
- require_unimplemented_servers=false
# protoc-gen-grpc-gateway needs to be installed, generate grpc-gateway go files based on proto files
- name: grpc-gateway
out: api/gen
opt:
- paths=source_relative
- grpc_api_configuration=api/v1/gw_mapping.yaml
# protoc-gen-openapiv2 needs to be installed, generate swagger config files based on proto files
- name: openapiv2
out: api/gen
opt:
- grpc_api_configuration=api/v1/gw_mapping.yaml
**5、**Compile the proto file.
$ buf generate
The following files will be created.
$ tree api/gen
api/gen
└── v1
├── greeter.pb.go
├── greeter.pb.gw.go
├── greeter.swagger.json
└── greeter_grpc.pb.go
1 directory, 4 files
6、Creating boot.yaml
grpc:
- name: greeter # Name of grpc entry
port: 8080 # Port of grpc entry
enabled: true # Enable grpc entry
sw:
enabled: true # Enable swagger
jsonPath: "api/gen/v1" # Provide swagger config file path
7、Creating main. go
package main
import (
"context"
"fmt"
"github.com/rookie-ninja/rk-boot"
"github.com/rookie-ninja/rk-grpc/boot"
"github.com/rookie-ninja/rk-demo/api/gen/v1"
"google.golang.org/grpc"
)
// Application entrance.
func main() {
// Create a new boot instance.
boot := rkboot.NewBoot()
// ******
// Register GRPC & Gateway **
// ******
// Get grpc entry with name
grpcEntry := boot.GetEntry("greeter").(*rkgrpc.GrpcEntry)
// Register grpc registration function
grpcEntry.AddRegFuncGrpc(registerGreeter)
// Register grpc-gateway registration function
grpcEntry.AddRegFuncGw(greeter.RegisterGreeterHandlerFromEndpoint)
// Bootstrap
boot.Bootstrap(context.Background())
// Wait for shutdown sig
boot.WaitForShutdownSig(context.Background())
}
// Implementation of [type GrpcRegFunc func(server *grpc.Server)]
func registerGreeter(server *grpc.Server) {
greeter.RegisterGreeterServer(server, &GreeterServer{})
}
// Implementation of grpc service defined in proto file
type GreeterServer struct{}
func (server *GreeterServer) Greeter(ctx context.Context, request *greeter.GreeterRequest) (*greeter.GreeterResponse, error) {
return &greeter.GreeterResponse{
Message: fmt.Sprintf("Hello %s!", request.Name),
}, nil
}
8、Folder Structure
$ tree
.
├── api
│ ├── gen
│ │ └── v1
│ │ ├── greeter.pb.go
│ │ ├── greeter.pb.gw.go
│ │ ├── greeter.swagger.json
│ │ └── greeter_grpc.pb.go
│ └── v1
│ ├── greeter.proto
│ └── gw_mapping.yaml
├── boot.yaml
├── buf.gen.yaml
├── buf.yaml
├── go.mod
├── go.sum
└── main.go
4 directories, 12 files
9、Verification
Visit Swagger:http://localhost:8080/sw
Alternative: Send gRPC Request with Apidog
Apifdoghas launched the gRPC API debugging feature, and we will demonstrate how to create a new gRPC project in Apidog and debug the interface through a sample scenario.
Note: The gRPC interface management feature requires Apidog version 2.3.0 or higher.
Creating a gRPC Project in Apidog
Clicking on the "New Team" button, select the gRPC type, enter the project name, and then click on the "Create" button.
Import .proto File
To import the .proto file that defines the gRPC API's service, methods, and messages, you can either drag and drop the file or use the file's online URL in Apidog. Then click the "Add" button.
Apidog will generate the corresponding API information based on the content of the .proto file. The sample interface includes four types of method calls: Unary, Server Streaming, Client Streaming, and Bidirectional Streaming.
Initiate a Unary Call
Unary call sends one message in request and receives one message in response. gRPC uses Protocol Buffers for serialization, which is more efficient than JSON, and HTTP/2 as its transport protocol with HPACK compression algorithm for Header information, saving bandwidth. This makes it ideal for real-time responses or transmitting small data.
To initiate a unary call, select the "SayHello" method and enter "grpcb.in:9000" in the API address. Then click on the "Generate Automatically" button to generate the request body and click on "Invoke" to view the response.
Server Streaming
As the icon suggests, Server Streaming means sending multiple response data in one request. For example, subscribing to all the transaction price data of stocks within one minute.
Bidirectional Streaming enables persistent bidirectional communication between clients and servers, allowing multiple messages to be transmitted simultaneously. It is commonly used in online games and real-time video call software, and is suitable for real-time communication and large-scale data transmission scenarios. After initiating the call, the client and server will maintain a session and receive real-time responses after sending different request contents.
gRPC API Collaboration
Apidog can render gRPC interface documents that are more suitable for human reading based on .proto files, making it easier to collaborate on interfaces within a team. You can click on the menu button on the right side of the interface to get the collaboration link and share it with other team members to align the debugging method of the interface.