Google App Engine Api和端点版本控制

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

我在我的应用程序中找到正确的方法来处理多个版本的remote.Service api时遇到了一些麻烦。

class MyService(Service):
   @endpoints.method(
        endpoints.ResourceContainer(
            something=protorpc.messages.StringField(1, required=True),
        ),
        message_types.VoidMessage,
    )
    def do_stuff(self, request):
        ... implement do_stuff ...

class MyBetterService(MyService):
    @endpoints.method(
        endpoints.ResourceContainer(
            some_other_name=protorpc.messages.StringField(1, required=True),
        ),
        message_types.VoidMessage,
    )
    def do_stuff(self, request):
        # ...other way of doing stuff
        return message_types.VoidMessage()

在尝试创建库时出现此错误:

protorpc.remote.ServiceDefinitionError: Do not use method decorator when overloading remote method do_stuff on service MyBetterService.

在下一版API中是否有覆盖方法的方法?

重写方法可能需要其他请求参数?

是否有可能在现有API中只添加一个不同版本的端点?

python google-app-engine google-cloud-endpoints
1个回答
3
投票

编写端点服务类,一旦定义了公共接口方法,就不能在子类中更改它们。 通常,您不应该将类的新API版本定义为子类,除非它精确地超级设置超类的接口。

在新版本是超集的情况下,您可以使用重新定义的接口方法,这将自动继承父方法的属性。 例如:

class MyService(Service):
   @endpoints.method(
        endpoints.ResourceContainer(
            something=protorpc.messages.StringField(1, required=True),
        ),
        message_types.VoidMessage,
    )
    def do_stuff(self, request):
        ... implement do_stuff ...

class MyBetterService(MyService):
    def do_stuff(self, request):
        # ...other way of doing stuff
        return message_types.VoidMessage()

   @endpoints.method(
        endpoints.ResourceContainer(
            something=protorpc.messages.IntegerField(1, required=True),
        ),
        message_types.VoidMessage,
    )
    def do_more_stuff(self, request):
        ... implement do_more_stuff ...

无法更改do_stuff()的输入类型。

在实践中,新的API版本应该被视为与新API相同并且具有独立的Service类定义。 将API真正视为一个接口。 虽然两个类不应该共享具有常见API方法定义的基类,但这并不意味着两个类现在可以共享一组通用的函数类。

当我构建服务时,我已经将API版本实现为单独的类,即使我必须复制许多方法签名。 但是,在服务下面,我实现了一个对象系统,它完全独立于接口和API消息类型执行相同的操作。 这允许两个API版本共享实现的重要部分。

例如:

from mysystem import MyImplementation

class MyService(Service):
   @endpoints.method(
        endpoints.ResourceContainer(
            something=protorpc.messages.StringField(1, required=True),
        ),
        message_types.VoidMessage,
    )
    def do_stuff(self, request):
      MyImplementation.do_stuff(request.something)

class MyBetterService(Service):
   @endpoints.method(
        endpoints.ResourceContainer(
            something=protorpc.messages.IntegerField(1, required=True),
        ),
        message_types.VoidMessage,
    )
    def do_stuff(self, request):
      MyImplementation.do_stuff(self.lookup_string(request.something))

在这个模型中,我认为API负责在服务接口和实际底层系统之间编组信息,而不是实际的实现。

虽然为每个新实现明确地复制每个方法可能看起来很多工作,但实际上它通常只是整个服务应该做的一小部分。

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