gRPC API 版本控制

问题描述 投票:0回答:1

有一种情况,我需要在我的服务器上实现 2 个版本的 grpc API。我该怎么做?

syntax = "proto3";

package greet.v1;

将帮助我向 pb2 自动生成的文件添加版本控制,但我完全不明白如何在同一服务器上组合 pb2(v1 和 v2)。也许有人有 Python 中 grpc 版本控制的例子?或者在一台服务器中使用 2 个版本可能是一种不好的做法,我应该使用另一个 pod 来获取新的 grpc 版本..

python grpc grpc-python
1个回答
0
投票

对于这个弱例子表示歉意。

我假设您在 v1 和 v2 之间进行了重大更改,并且具有以下类似内容:

protos/greet/v1/greet.proto

syntax = "proto3";

// Reflect package in folder path i.e. protos/greet/v1
package greet.v1;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

protos/greet/v2/greet.proto

syntax = "proto3";

// Reflect package in folder path i.e. protos/greet/v1
package greet.v2;

// Reuse (!) 'greet.v1.HelloReply'
import "greet/v1/greet.proto";

service Greeter {
  rpc SayHello (HelloRequest) returns (greet.v1.HelloReply) {}
}

message HelloRequest {
  fixed32  id = 1;
}

并且:

requirements.txt

grpcio==1.62.0
grpcio-reflection==1.62.0
grpcio-tools==1.62.0
protobuf==4.25.3
python3 -m venv venv
source venv/bin/activate

python3 -m pip install --requirement requirements.txt

python3 \
-m grpc_tools.protoc \
--proto_path=${PWD}/protos \
--python_out=${PWD} \
--pyi_out=${PWD} \
--grpc_python_out=${PWD} \
${PWD}/protos/greet/v1/greet.proto \
${PWD}/protos/greet/v2/greet.proto

并且:

main.py

# Python gRPC service reflection
from grpc_reflection.v1alpha import reflection

from concurrent import futures
import grpc

# v1
import greet.v1.greet_pb2 as greet_v1_pb2
import greet.v1.greet_pb2_grpc as greet_v1_pb2_grpc


class GreeterV1(greet_v1_pb2_grpc.GreeterServicer):
    def SayHello(self, request, context):
        return greet_v1_pb2.HelloReply(message=f"Hello {request.name}")

# v2
import greet.v2.greet_pb2 as greet_v2_pb2
import greet.v2.greet_pb2_grpc as greet_v2_pb2_grpc


class GreeterV2(greet_v2_pb2_grpc.GreeterServicer):
    def SayHello(self, request, context):
        return greet_v1_pb2.HelloReply(message=f"Hello {request.id}")


def serve():
    # One service
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))

    # Adds v1 and v2 services
    greet_v1_pb2_grpc.add_GreeterServicer_to_server(GreeterV1(), server)
    greet_v2_pb2_grpc.add_GreeterServicer_to_server(GreeterV2(), server)

    SERVICE_NAMES = (
        greet_v1_pb2.DESCRIPTOR.services_by_name['Greeter'].full_name,
        greet_v2_pb2.DESCRIPTOR.services_by_name['Greeter'].full_name,
    )
    # Adds third service (!)
    reflection.enable_server_reflection(SERVICE_NAMES, server)

    server.add_insecure_port("[::]:50051")
    server.start()
    server.wait_for_termination()

if __name__ == "__main__":
    serve()

并且:

# Enumerate v1 Method
grpcurl -plaintext localhost:50051 list greet.v1.Greeter
greet.v1.Greeter.SayHello

# Invoke v1 Method
grpcurl -plaintext -d '{"name":"Freddie"}' localhost:50051 greet.v1.Greeter.SayHello
{
  "message": "Hello Freddie"
}

# Enumerate v2 Method
grpcurl -plaintext localhost:50051 list greet.v2.Greeter
greet.v2.Greeter.SayHello

# Invoke v2 Method
grpcurl -plaintext -d '{"id":314159265}' localhost:50051 greet.v2.Greeter.SayHello
{
  "message": "Hello 314159265"
}

注意 Python 的 gRPC 反射服务似乎不适用于

describe {method}

© www.soinside.com 2019 - 2024. All rights reserved.