2013-04-23 24 views
5

Zaczynam używać Google Cloud Endpoints i pojawia się problem podczas określania wielu klas usług. Masz pomysł, jak to działa?Chmury punktów końcowych z wieloma klasami usług

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. 

W ten sposób tworzę swój serwer punktu końcowego.

AVAILABLE_SERVICES = [ 
    FirstService, 
    SecondService 
] 

app = endpoints.api_server(AVAILABLE_SERVICES) 

i dla każdej klasy usług Robię to:

@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): 
... 

Każda z tych prac doskonale osobno, ale nie jestem pewien, jak je zdobyć pracę przy ich łączeniu.

Wielkie dzięki.

+0

Spójrz na to https://developers.google.com/appengine/docs/python/endpoints/create_api#creating_an_api_implemented_with_multiple_classes] –

Odpowiedz

6

Prawidłowe sposobem jest utworzenie obiektu api i użyć 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): 
    ... 

gdzie nazwa zasobu zostanie wstawiony przed nazwami metod, tak aby można było korzystać z

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

zamiast

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

Wyrażając to serwer API:

Przedmiotem api_root jest odpowiednikiem remote.Service klasy ozdobione endpoints.api, więc można po prostu umieścić go na liście endpoints.api_server. Na przykład:

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

w jaki sposób utworzysz serwer API w tym przypadku? Przekazanie [api_root] do endpoints.api_server lub przekazanie tej samej tablicy co powyżej (wszystkie usługi) nie działa. Otrzymuję obiekt AttributeError: Obiekt _ApiDecorator nie ma atrybutu 'api_info'' dla pierwszego. I 'ApiConfigurationError: SPI zarejestrowane z wieloma klasami w ramach jednej konfiguracji (UsersService i SongsService). Każde wywołanie register_spi powinno zawierać tylko metody z jednej klasy. Zadzwoń wielokrotnie dla wielu klas. "Na sekundę. Dowolny pomysł? – mkhatib

+0

Próbowałem 'endpoints.api_server ([FirstService, SecondService], restricted = False', w pierwszej chwili myślałem, że to działa, ale tak się nie stało Próbuję zarejestrować api_root Mam ten sam błąd –

+0

Jedno rozwiązanie, które Naprawdę wierzę, że nie jest najlepszy, stworzyłem jedną klasę, która dziedziczy wszystkie klasy usług i rejestruję tylko ten. Nazewnictwo metod jako "first.method" –

2

Jeśli się nie mylę, powinieneś nadać różne nazwy każdej usłudze, abyś mógł uzyskać dostęp do obu, podając konkretny "adres".

@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): 
... 
+0

myślałem, że to powinien znajdować się pod jednym api, ale możesz mieć rację. Dzięki :-) – mkhatib

+0

Nie ma za co! To, co mam, to tak, jedna klasa na usługę, z wszystkimi metodami tej usługi. :) –

+0

Poszedłem z tym, moim jedynym problemem jest teraz, że musiałbym załadować każdy interfejs API w moim kliencie javascript osobno. Myślę, że nie jest to wielka sprawa, ale wolałbym je raz załadować i to wszystko. Odpowiedź szefa wygląda tak, jak chcę, ale nie działa dokładnie. – mkhatib

0

rozwoju lokalnego Używam tymczasowe obejście problemu, jakim jest wyłączenie wyjątku (wiem, wiem ...)

W moim SDK w google_appengine/google/appengine/ext/endpoints/api_backend_service.py wokół linii 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: 

W połączeniu z tym, że m stosując konstrukt:

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

Ponownie, t jego nie będzie działać w produkcji, dostaniesz tam ten sam wyjątek. Mam nadzieję, że ta odpowiedź zostanie zastąpiona przez przyszłą poprawkę.

Potwierdzono, że jest już przestarzały (testowany pod 1.8.2).

0

Jeśli było Java ...

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

cloudn't być łatwiejsze.

1

Udało mi się wdrożyć pojedyncze API wdrożone w dwóch klasach.Można spróbować użyć następujący fragment (niemal bezpośrednio z 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) 
Powiązane problemy