【问题标题】:Google App Engine Api and Endpoints versioningGoogle App Engine Api 和 Endpoints 版本控制
【发布时间】:2015-01-15 08:40:59
【问题描述】:

我在寻找处理多个问题的正确方法时遇到了一些麻烦 我的应用程序中的 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】:

    端点服务类的编写方式是,一旦定义了公共接口方法,就不能在子类中更改它们。通常你不应该将一个新的 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,并具有独立的服务类定义。将 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 负责在服务接口和实际底层系统之间编组信息,而不是实际的实现。

    虽然为每个新实现显式复制每个方法似乎需要做很多工作,但实际上它通常只是整个服务应该做的一小部分。

    【讨论】:

    • 在第二个例子中应该有class MyBetterService(Service): 但我认为这是最好的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-08
    相关资源
    最近更新 更多