GoogleCloudPlatform / go-endpoints

Cloud Endpoints for Go
https://go-endpoints.appspot.com
Apache License 2.0
255 stars 56 forks source link

method parameters not parsed for calls from iOS clients (using the "rpc" protocol) to dev_appserver #106

Open eliasnaur opened 9 years ago

eliasnaur commented 9 years ago

This service method:

type QuizAnswers struct {
        QuizID  string `json:"quiz_id"`
        Answers []int  `json:"answers"`
}

func (gs *RQService) SubmitAnswers(c context.Context, r *QuizAnswers) (*QuizResult, error)

works fine with rest-based clients (javascript, Android) but fails to fill out the parameter r on calls to dev_appserver from iOS clients (using the rpc protocol).

I'm calling the API like this:

        GTLRqQuizAnswers *quizAnswers = [[GTLRqQuizAnswers alloc] init];
        quizAnswers.answers = [NSArray arrayWithArray:self.givenAnswers];
        quizAnswers.quizId = self.quiz.desc.identifier;
        GTLQueryRq *query = [GTLQueryRq queryForAnswersSubmitWithObject:quizAnswers];
        [[AppDelegate endpointsService] executeQuery:query completionHandler:^(GTLServiceTicket *ticket, GTLRqQuizResult *result, NSError *error) {
            NSLog(@"result = %@", result);
        }];

It works fine on the production server.

One hint is a debug line from the go-endpoints library. This is the line from dev_appserver:

SPI request body: {"resource": {"quiz_id": "1234", "answers": [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1]}}

while this is the output from production:

SPI request body: {"quiz_id":"1234","answers":[0,0,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1],"resource":{"quiz_id":"1234","answers":[0,0,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1]}}

Notice that the arguments only appear under the "resource" key on dev_appserver, while the arguments appear directly in the "request body" in production. As far as I can see from the go-endpoints source, the arguments are marshaled from the body directly, ignoring "resource".

I'm sorry for not providing an end-to-end example, but app engine endpoints are difficult to set up, especially with iOS clients. If there is anything else you need, don't hesitate to ask. Also notify if the bug belongs to dev_appserver, in which case I'll forward this report to the appengine issue tracker.

FWIW, this is the equivalent curl invocation for the API call, fetched with wireshark:

curl -H 'Content-type: application/json-rpc' --data '{"method":"rq.answers.submit","id":"gtl_42","jsonrpc":"2.0","params":{"resource":{"quiz_id":"1234","answers":[0,0,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1]}},"apiVersion":"v1"}' http://localhost:8080/_ah/api/rpc?prettyPrint=false

I confirmed that replacing http://localhost with https://.appspot.com results in a properly unmarshaled parameter r.