前言

本文记录了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. 使用navicat连接只开放内网ip连接的数据库

    无法通过Navicat来连接MySQL,比较常见的两种问题? 服务器上自己安装的MySQL数据库,且未开通外网登录账号 直接购买服务商的MySQL数据库不创建公网访问,只有内网访问   背景: 公司数 ...

  2. JavaScript-双层for循环打印九九乘法表

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. mysqlbinlog-Note

    binlog_format = mixedlog-bin = /data/mysql/mysql-binexpire_logs_days = 7 #binlog过期清理时间max_binlog_siz ...

  4. FreeRTOS操作系统教程发布,支持F103,F407和F429,配套145个例子,1200页教程

    前言说明:1. 首先感谢大家对我们安富莱电子的支持. 2. FreeRTOS最大的优势就是开源免费,商业使用的话不需要用户公开源代码,也不存在任何版权问题,是当前小型嵌入式操作系统   市场使用率最高 ...

  5. CountDownLatch原理分析

    CountDownLatch原理分析 CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程执行完后再执行.例如,应用程序的主线程希望在负责启动框架服务的线程已经启动 ...

  6. 搞定vscode编写java(手把手篇)

    1: 下载VSCODE 本来我写过一个 vscode 编写java 帖子,但是 还是很多人私信我,下面写一个手把手教程 原文地址: https://www.cnblogs.com/dgwblog/p/ ...

  7. java8-CompleableFuture的使用1

    背景 硬件的极速发展,多核心CPU司空见惯:分布式的软件架构司空见惯: 功能API大多采用混聚的方式把基础服务的内容链接在一起,方便用户生活. 抛出了两个问题: 如何发挥多核能力: 切分大型任务,让每 ...

  8. SpringBoot2.0 整合 JWT 框架,解决Token跨域验证问题

    本文源码:GitHub·点这里 || GitEE·点这里 一.传统Session认证 1.认证过程 1.用户向服务器发送用户名和密码. 2.服务器验证后在当前对话(session)保存相关数据. 3. ...

  9. router-view 与 动态组件 区别

    提问:router-view 可以页面跳转,使用 is特性 也可以进行页面跳转,有什么区别? 参考链接 https://segmentfault.com/q/1010000010750059

  10. Spring Boot 2 快速教程:WebFlux Restful CRUD 实践(三)

    摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 这是泥瓦匠的第102篇原创 03:WebFlux Web CR ...