I am starting to use Google Cloud Endpoints and I am running in a problem when specifying multiple services classes. Any idea how to get this working?
ApiCon
For local development I'm using a temporary workaround, which is to disable the exception (I know I know...)
In my sdk in google_appengine/google/appengine/ext/endpoints/api_backend_service.py
around line 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:
In combination with that I'm using the construct:
application = endpoints.api_server([FirstService, SecondService, ...])
Again, this won't work in production, you'll get the same exception there. Hopefully this answer will be obsoleted by a future fix.
Confirmed it's now obsolete (tested against 1.8.2).
If I'm not mistaken, you should give different names to each service, so you'll be able to access both, each one with the specific "address".
@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):
...
The correct way is to create an api
object and use the 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):
...
where resource name would be inserted in front of method names so that you could use
@endpoints.method(name='method', ...)
def MyMethod(self, request):
...
instead of
@endpoints.method(name='first.method', ...)
def MyMethod(self, request):
...
The api_root
object is equivalent to a remote.Service
class decorated with endpoints.api
, so you can simply include it in the endpoints.api_server
list. For example:
application = endpoints.api_server([api_root, ...])
If it was Java ...
https://developers.google.com/appengine/docs/java/endpoints/multiclass
cloudn't be easier.
I've managed to successfuly deploy single api implemented in two classes. You can try using following snippet (almost directly from 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)