前言

本文记录了grpc-gateway的简单使用。

定义proto

先来看看最常规的

syntax = "proto3";

package protos;

service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
} message HelloRequest {
string name = 1;
} message HelloReply {
string message = 1;
}

然后加入gateway等相关的内容

syntax = "proto3";

package protos;

// 1 导入 gateway 相关的proto 以及 swagger 相关的 proto
import "google/api/annotations.proto";
import "protoc-gen-swagger/options/annotations.proto"; // 2 定义 swagger 相关的内容
option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
info: {
title: "grpc gateway sample";
version: "1.0";
license: {
name: "MIT";
};
};
schemes: HTTP;
}; service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {
// 3 标识接口路由
option (google.api.http) = {
post: "/hello_world"
body: "*"
};
}
} message HelloRequest {
string name = 1;
} message HelloReply {
string message = 1;
}

从proto生成文件

执行下面的三个命令。

protoc -I . --go_out=plugins=grpc:. hello.proto
protoc -I . --grpc-gateway_out=logtostderr=true:. hello.proto
protoc -I . --swagger_out=logtostderr=true:. hello.proto

实现service和启动service

实现

package services

import (
"context"
pb "grpc-sample/protos"
"log"
) type server struct{} func NewServer() *server {
return &server{}
} func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
log.Println("request: ", in.Name)
return &pb.HelloReply{Message: "hello, " + in.Name}, nil
}

启动

package main

import (
"google.golang.org/grpc"
pb "grpc-sample/protos"
"grpc-sample/services"
"log"
"net"
) const (
PORT = ":9192"
) func main() {
lis, err := net.Listen("tcp", PORT) if err != nil {
log.Fatalf("failed to listen: %v", err)
} s := grpc.NewServer()
pb.RegisterGreeterServer(s, services.NewServer())
log.Println("rpc services started, listen on localhost:9192")
s.Serve(lis)
}

整合 swagger

先下载swagger ui的静态文件。

把这些文件打包成go文件。

go-bindata --nocompress -pkg swagger -o gateway/swagger/datafile.go third_party/swagger-ui/...

9M。。。

写 gateway

package main

import (
"github.com/elazarl/go-bindata-assetfs"
"log"
"net/http"
"path"
"strings" "github.com/golang/glog"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"golang.org/x/net/context"
"google.golang.org/grpc"
swagger "grpc-sample/gateway/swagger"
gw "grpc-sample/protos"
) func run() error {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel() gwmux, err := newGateway(ctx)
if err != nil {
panic(err)
} mux := http.NewServeMux()
mux.Handle("/", gwmux)
mux.HandleFunc("/swagger/", serveSwaggerFile)
serveSwaggerUI(mux) log.Println("grpc-gateway listen on localhost:8080")
return http.ListenAndServe(":8080", mux)
} func newGateway(ctx context.Context) (http.Handler, error) {
opts := []grpc.DialOption{grpc.WithInsecure()} gwmux := runtime.NewServeMux()
if err := gw.RegisterGreeterHandlerFromEndpoint(ctx, gwmux, ":9192", opts); err != nil {
return nil, err
} return gwmux, nil
} func serveSwaggerFile(w http.ResponseWriter, r *http.Request) {
if !strings.HasSuffix(r.URL.Path, "swagger.json") {
log.Printf("Not Found: %s", r.URL.Path)
http.NotFound(w, r)
return
} p := strings.TrimPrefix(r.URL.Path, "/swagger/")
p = path.Join("../protos", p) log.Printf("Serving swagger-file: %s", p) http.ServeFile(w, r, p)
} func serveSwaggerUI(mux *http.ServeMux) {
fileServer := http.FileServer(&assetfs.AssetFS{
Asset: swagger.Asset,
AssetDir: swagger.AssetDir,
Prefix: "third_party/swagger-ui",
})
prefix := "/swagger-ui/"
mux.Handle(prefix, http.StripPrefix(prefix, fileServer))
} func main() {
defer glog.Flush() if err := run(); err != nil {
glog.Fatal(err)
}
}

结果如下:

总结

通过grpc-gateway的方式来访问grpc服务,还是挺方便的,不过性能会有所折损。

参考

https://segmentfault.com/a/1190000013513469

gRPC+gRPC Gateway+swagger小记的更多相关文章

  1. AWS API Gateway Swagger定义

    导出Swagger接口定义文件 在AWS API Gateway界面上,可以导出swagger接口定义文件. 而后利用Node js swagger-ui 依赖,生成swagger接口地址 Cloud ...

  2. LNMP : 502 Bad Gateway 解决小记,真正的原因

    站点搬迁到新的server.原先一直都是LAMP.如今改为LNMP. 将重写文件 htaccess改成 nginx的 conf.放到了站点.可仅仅能打开首页,其它重写页面一打开都是不停的载入. 载入等 ...

  3. gRPC helloworld service, RESTful JSON API gateway and swagger UI

    概述 本篇博文完整讲述了如果通过 protocol buffers 定义并启动一个 gRPC 服务,然后在 gRPC 服务上提供一个 RESTful JSON API 的反向代理 gateway,最后 ...

  4. protobuffer、gRPC、restful gRPC的相互转化

    转自:https://studygolang.com/articles/12510 文档 grpc中文文档 grpc-gateway,restful和grpc转换库 protobuf 官网 proto ...

  5. gRPC错误码 http状态码 provide your APIs in both gRPC and RESTful style at the same time

    How gRPC error codes map to HTTP status codes in the response https://github.com/grpc-ecosystem/grpc ...

  6. 如何在 Knative 中部署 WebSocket 和 gRPC 服务?

    作者 | 冬岛  阿里云容器平台工程师 导读:虽然说 Knative 默认就支持 WebSocket 和 gRPC,但在使用中会发现,有时想要把自己的 WebSocket 或 gRPC 部署到 Kna ...

  7. gRPC应用C++

    1.  gRPC简述 RPC,远程方法调用,就是像调用本地方法一样调用远程方法. gRPC是Google实现的一种RPC框架,基于HTTP/2标准设计,带来诸如双向流.流控.头部压缩.单 TCP 连接 ...

  8. 使用nestjs集成grpc具体操作

    两个程序中, 提供grpc服务的称为服务端, 调用grpc服务的为客户端, 以下是grpc服务端和客户端的代码编写     1. 创建两个nestjs项目demo1(端口: 3000)和demo2(端 ...

  9. gRPC学习之一:在CentOS7部署和设置GO

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

随机推荐

  1. element-ui 中Switch的用法

    在element-ui中,如果你想知道Switch是开还是关,使用事件 @change="getchange(value2)" 它会输出true或者false.true代表的是开, ...

  2. Github(第一次尝试)

    重要提示:项目中的文件最好最好不要出现中文,尤其是复杂的中文文件名. 前提:本地已经用git 管理 一个测试项目(项目一),分支为master. 1.注册 github: http://git.osc ...

  3. JavaScript-----14.内置对象 Array()和String()

    5. 数组对象 5.1数组的创建 之前提到过数组的创建方式 字面量 new Array() //创建数组的两种方式 //1.利用数组字面量 var arr = [1, 2, 3]; console.l ...

  4. Windows下使用virtualenv创建虚拟环境

    操作系统 : windowns10_x64Python版本:3.6.8virtualenv版本:16.7.7virtualenvwrapper版本:1.2.5 方式一:直接使用virtualenv 1 ...

  5. vue路由传参和获取参数

    参考链接 https://router.vuejs.org/zh/guide/essentials/passing-props.html#%E5%B8%83%E5%B0%94%E6%A8%A1%E5% ...

  6. Python3---标准库---urllib

    前言 该文章主要说明Python3 标准库urllib的使用. 修改时间:20191216 修改时间:20191217 修改时间:20191218 添加urllib.parse.urlencode,u ...

  7. Set a Many-to-Many Relationship设置多对多关系 (EF)

    In this lesson, you will learn how to set relationships between business objects. For this purpose, ...

  8. vue-svgicon基本使用

    在项目开发中,经常会用到svg图标,之前用的都是vue-svg-icon,最近在npm中搜索svg图标解析插件,发现vue-svgicon用的相对较多,对比以下,vue-svgicon用法较为灵活,方 ...

  9. vue发送ajax请求

    一.vue-resource 1.简介 一款vue插件,用于处理ajax请求,vue1.x时广泛应用,现不被维护. 2.使用流程 step1:安装 [命令行输入] npm install vue-re ...

  10. JS If...Else

    JS If...Else 条件语句用于基于不同的条件来执行不同的动作. 条件语句 通常在写代码时,您总是需要为不同的决定来执行不同的动作.您可以在代码中使用条件语句来完成该任务. 在 JavaScri ...