Reputation: 465
I have a python webservice running locally using GAE Python SDK 1.8.3. After annotating the API and generating iOS client classes using Google Cloud Endpoints Service Generator I'm trying to call a remote procedure using it.
If I test my api using API Explorer, everything works just fine.
When I call using the iOS client, the call is received by the webservice, however the request cannot be decoded correctly. This is my first time using the Endpoints API so I don't know what is wrong.
What seems to be happening is that my request object is being wrapped in a "resource" key in the query JSON. Now, when my webservice tries to decode it, it yields a warning saying "No variant found for unrecognized field: resource". And, as my object is wrapped inside this key, it is skipped and never decoded to a message.
When the call is made using the API Explorer the object is not wrapped, so everything works.
This is what I'm doing in my webservice:
@endpoints.method(SearchRequest,
ContactListResponse,
path='search', http_method='post',
name='api.search')
def search(self, request):
user = request.user
number = request.number
This is how I call it from iOS:
GTLMyAPIMessagesSearchRequest * request = [[GTLMyAPIMessagesSearchRequest alloc] init];
request.user = @"+552199881234";
request.number = @"+5521717171";
GTLQueryMyAPI *query = [GTLQueryMyAPI queryForApiSearchWithObject:request];
[service executeQuery:query completionHandler:^(GTLServiceTicket *ticket,
GTLMyAPIMessagesContactListResponse* object,
NSError *error)
{
NSArray* contacts = object.contacts;
}
Am I doing anything incredibly wrong here?
Upvotes: 0
Views: 1005
Reputation: 776
I'm still experimenting but believe this is the proper way (swift) to set up for testing on localhost....
let _service = GTLServiceBackendAPI();
_service.allowInsecureQueries = true;
_service.isRESTDataWrapperRequired = false;
_service.retryEnabled = true;
_service.fetcherService.allowLocalhostRequest = true;
_service.rpcURL = NSURL(string: "http://localhost:8080/_ah/api/rpc?prettyPrint=true")
Upvotes: 0
Reputation: 1223
This is an annoying bug from iOS to Endpoints for local testing. I hope they fix it soon. :)
BTW instead of modifying QGTQueryMyAPI.m (which is a generated file). I do Theo's fix just after I create the query instead. So all of my queries that send data look like this (and I set that one flag to switch from localhost to deployed in other places too).
GTLQueryMyApi *query = [GTLQueryMyApi queryForSearchWithObject:someGtlObject];
if (LOCAL_HOST_TESTING) {
[query setJSON:someGtlObject.JSON];
}
Upvotes: 4
Reputation: 465
Alright! user2697002's answer showed me that this works when the webservice is deployed.
For development to work correctly this is the workaround I did.
The generated API uses a template like this for all queries in GTLQueryMyAPI.m
+ (id)queryForSearchWithObject:(GTLMyAPIMessagesSearchRequest *)object {
if (object == nil) {
GTL_DEBUG_ASSERT(object != nil, @"%@ got a nil object", NSStringFromSelector(_cmd));
return nil;
}
NSString *methodName = @"myapi.search";
GTLQueryMyAPI *query = [self queryWithMethodName:methodName];
query.bodyObject = object;
query.expectedObjectClass = [GTLMyAPIMessagesContactListResponse class];
return query;
}
For this to work on development server one could substitute all these lines
query.bodyObject = object;
With
query.JSON = object.JSON;
This stops from wrapping the JSON in a "resource" field. Somehow I believe this shouldn't be done on deployment release version.
Upvotes: 0
Reputation: 26
This is not a great solution but a patch for now. I have the same problem when doing iOS endpoints localhost testing. However when I use the deployed backend I remove this line and everything is fine.
auth.shouldAuthorizeAllRequests = YES;
The "resource" key wrapping issue only happens when I add the line above to use localhost. So this morning I'm not using localhost, just the deployed version. Let me know if you fix the issue. :) Obviously pointing to the deployed version is not preferred for testing.
Upvotes: 1