zoukankan      html  css  js  c++  java
  • 使用 JSON 协议的 gRPC

    JSON payload 实现简易的请求和响应的内省。

    介绍

    大家经常说 gRPC 是基于 Google Protocol Buffers payload 格式的,然而这不完全正确。gRPC payload 的默认格式是 Protobuf,但是 gRPC-Go 的实现中也对外暴露了 Codec interface ,它支持任意的 payload 编码。我们可以使用任何一种格式,包括你自己定义的二进制格式、flatbuffers、或者使用我们今天要讨论的 JSON ,作为请求和响应。

    服务端准备

    我已经基于 JSON payload 实现grpc/encoding.Codec,创建了一个示例库。服务端的准备工作仅仅像引入一个包那样简单;

    import _ "github.com/johanbrandhorst/grpc-json-example/codec"
    

    这行代码注册了一个基于 json 内容的子类型 JSON Codec,我们在后面会看到这对于方便记忆很重要。

    Request 示例

    gRPC 客户端

    使用 gRPC 客户端,你只需要使用合适的内容子类型作为 grpc.DialOption 来初始化:

    import "github.com/johanbrandhorst/grpc-json-example/codec"
    func main() {
        conn := grpc.Dial("localhost:1000",
            grpc.WithDefaultCallOptions(grpc.CallContentSubtype(codec.JSON{}.Name())),
        )
    }
    

    示例库代码包含有完整示例的客户端

    cURL

    更有趣的是,现在我们可以用 cURL 写出请求(和读取响应)!请求示例:

    $ Echo -en 'x00x00x00x00x17{"id":1,"role":"ADMIN"}' | curl -ss -k --http2 
            -H "Content-Type: application/grpc+json" 
            -H "TE:trailers" 
            --data-binary @- 
            https://localhost:10000/example.UserService/AddUser | od -bc
    0000000 000 000 000 000 002 173 175
                    002   {   }
    0000007
    $ Echo -en 'x00x00x00x00x17{"id":2,"role":"GUEST"}' | curl -ss -k --http2 
            -H "Content-Type: application/grpc+json" 
            -H "TE:trailers" 
            --data-binary @- 
            https://localhost:10000/example.UserService/AddUser | od -bc
    0000000 000 000 000 000 002 173 175
                    002   {   }
    0000007
    $ Echo -en 'x00x00x00x00x02{}' | curl -k --http2 
            -H "Content-Type: application/grpc+json" 
            -H "TE:trailers" 
            --data-binary @- 
            --output - 
            https://localhost:10000/example.UserService/ListUsers
    F{"id":1,"role":"ADMIN","create_date":"2018-07-21T20:18:21.961080119Z"}F{"id":2,"role":"GUEST","create_date":"2018-07-21T20:18:29.225624852Z"}
    

    解释

    使用 cURL 发送请求需要手动把 gRPC HTTP2 message payload header 加到 payload:

    'x00x00x00x00x17{"id":1,"role":"ADMIN"}'
    #<-->----------------------------------------- Compression boolean (1 byte)
    #    <-------------->------------------------- Payload size (4 bytes)
    #                    <--------------------->-- JSON payload
    

    请求头必须包含 TE 和正确的 Content-Type

    -H "Content-Type: application/grpc+json" -H "TE:trailers"
    

    Content-Type 头中 application/grpc+ 后的字符串需要与服务端注册的 codec 的 Name() 相吻合。这就是内容子类.

    endpoint 需要与 proto 包的名字、服务和方法三者的名字都匹配:

    https://localhost:10000/example.UserService/AddUser
    

    响应头与请求头一致:

    '       002   {   }'
    #<-->------------------------ Compression boolean (1 byte)
    #    <------------>---------- Payload size (4 bytes)
    #                     <--->-- JSON payload
    

    总结

    我们已经展示了我们可以轻易地在 gRPC 中使用 JSON payload,甚至可以用 JSON payload 直接发送 cURL 请求到我们的 gRPC 服务,没有代理,没有 grpc 网关,除了引入一个必要的包也没有其他的准备工作。

    如果你对本文感兴趣,或者有任何问题和想法,请在 @johanbrandhorst 上或 在 Gophers Slack jbrandhorst 下联系我。很高兴听到你的想法。


    via: https://jbrandhorst.com/post/grpc-json/

    作者:Johan Brandhorst 译者:lxbwolf 校对:polaris1119

    本文由 GCTT 原创编译,Go语言中文网 荣誉推出

  • 相关阅读:
    11C++11通用为本,专用为末_2
    10C++11通用为本,专用为末_1
    09C++11保证稳定性和兼容性
    21变量名的力量_2
    NOIP2018 游记
    CF767C 经典的树形DP
    CF1A Theatre Square
    洛谷P1720 月落乌啼算钱
    洛谷P3388 缩点
    NOIP2017D2T1 奶酪 洛谷P3958
  • 原文地址:https://www.cnblogs.com/polaris1119/p/13498828.html
Copyright © 2011-2022 走看看