【问题标题】:Cloud Endpoints with Multiple Services Classes具有多个服务类的云端点
【发布时间】:2013-04-23 05:16:52
【问题描述】:

我开始使用 Google Cloud Endpoints,但在指定多个服务类时遇到了问题。知道如何让它工作吗?

ApiConfigurationError: Attempting to implement service myservice, version v1, with multiple classes that aren't compatible. See docstring for api() for examples how to implement a multi-class API.

这就是我创建端点服务器的方式。

AVAILABLE_SERVICES = [
  FirstService,
  SecondService
]

app = endpoints.api_server(AVAILABLE_SERVICES)

对于每个服务类我都这样做:

@endpoints.api(name='myservice', version='v1', description='MyService API')
class FirstService(remote.Service):
...

@endpoints.api(name='myservice', version='v1', description='MyService API')
class SecondService(remote.Service):
...

这些中的每一个都可以完美地单独工作,但我不确定在组合它们时如何让它们工作。

非常感谢。

【问题讨论】:

标签: python google-app-engine google-cloud-endpoints


【解决方案1】:

正确的方法是创建一个api对象并使用collection

api_root = endpoints.api(name='myservice', version='v1', description='MyService API')

@api_root.collection(resource_name='first')
class FirstService(remote.Service):
  ...


@api_root.collection(resource_name='second')
class SecondService(remote.Service):
  ...

资源名称将被插入到方法名称的前面,以便您可以使用

  @endpoints.method(name='method', ...)
  def MyMethod(self, request):
    ...

而不是

  @endpoints.method(name='first.method', ...)
  def MyMethod(self, request):
    ...

将其放入 API 服务器:

api_root 对象等价于用endpoints.api 修饰的remote.Service 类,因此您可以简单地将其包含在endpoints.api_server 列表中。例如:

application = endpoints.api_server([api_root, ...])

【讨论】:

  • 在这种情况下,您将如何创建 API 服务器?将 [api_root] 传递给 endpoints.api_server 或传递与上述相同的数组(所有服务)不起作用。第一个我得到AttributeError: '_ApiDecorator' object has no attribute 'api_info'。第二个是ApiConfigurationError: SPI registered with multiple classes within one configuration (UsersService and SongsService). Each call to register_spi should only contain the methods from a single class. Call repeatedly for multiple classes.。有什么想法吗?
  • 我试过endpoints.api_server([FirstService, SecondService], restricted=False,起初我以为它可以工作,但没有。尝试注册 api_root 我有同样的错误。
  • 我真正认为不是最好的一种解决方案,我创建了一个继承所有服务类的类,我只注册了这个。我把方法的名字写成“first.method”。
  • 不推荐使用集合,而是使用 api_class
  • @bossylobster Danny 只问你一个问题,如果我的 API classes 驻留在单独的文件中,那么我如何将 api_root 变量发送到所有这些类,以便它们可以用相同的api_root 变量。
【解决方案2】:

如果我没记错的话,您应该为每个服务指定不同的名称,这样您就可以同时访问这两个服务,每个服务都有特定的“地址”。

@endpoints.api(name='myservice_one', version='v1', description='MyService One API')
class FirstService(remote.Service):
...

@endpoints.api(name='myservice_two', version='v1', description='MyService Two API')
class SecondService(remote.Service):
...

【讨论】:

  • 我认为它应该在一个 api 下,但你可能是对的。谢谢:-)
  • 不客气!我所拥有的就是这样,每个服务一个类,上面有这个服务的所有方法。 :)
  • 我明白了这一点,我现在唯一的问题是我必须在我的 javascript 客户端中分别加载每个 API。我想这没什么大不了的,但我宁愿加载它们一次,就是这样。 bossylobster 的答案似乎是我想要的,但似乎并不完全有效。
  • 我从来没有像他说的那样使用“收藏”。我刚刚检查了他的答案,我会尝试一下,并返回任何反馈! :)
  • @bossylobster 答案实际上是正确的,尽管由于 mkhatib 提到的问题,它目前不起作用(我认为这是一个错误,或者我们都在这样做完全错误)。不应将此标记为已接受...
【解决方案3】:

我已成功部署在两个类中实现的单个 api。您可以尝试使用以下 sn-p(几乎直接来自 google documentation):

an_api = endpoints.api(name='library', version='v1.0')

@an_api.api_class(resource_name='shelves')
class Shelves(remote.Service):
...

@an_api.api_class(resource_name='books', path='books')
class Books(remote.Service):
...

APPLICATION = endpoints.api_server([an_api],
                               restricted=False)

【讨论】:

    【解决方案4】:

    对于本地开发,我使用了一种临时解决方法,即禁用异常(我知道我知道...)

    在我的 sdk 中 google_appengine/google/appengine/ext/endpoints/api_backend_service.py 第 97 行附近:

            elif service_class != method_class:
              pass
    #          raise api_config.ApiConfigurationError(
    #              'SPI registered with multiple classes within one '
    #              'configuration (%s and %s).  Each call to register_spi should '
    #              'only contain the methods from a single class.  Call '
    #              'repeatedly for multiple classes.' % (service_class,
    #                                                    method_class))
        if service_class is not None:
    

    结合我正在使用的构造:

    application = endpoints.api_server([FirstService, SecondService, ...])
    

    同样,这在生产中不起作用,在那里你会得到同样的异常。希望这个答案会被未来的修复所淘汰。

    确认它现在已过时(针对 1.8.2 进行测试)。

    【讨论】:

      【解决方案5】:

      如果是 Java ...

      https://developers.google.com/appengine/docs/java/endpoints/multiclass
      

      云并不容易。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-03-22
        • 1970-01-01
        • 2023-03-24
        • 1970-01-01
        • 2020-02-03
        • 1970-01-01
        相关资源
        最近更新 更多