Pauli Savolainen
Pauli Savolainen

Reputation: 61

Deserialization error using Google cloud endpoint JS api Client

I have set up a local appengine with endpoints. Using CURL I test the endponts succesfully like this:

C:\Program Files>curl.exe --header "Content-Type: application/json" -X POST -d "{g:\"test\",u:1,l:{x:1,y:1}}" http://localhost:8888/_ah/api/myapp/v1/move

The response I get is as expected:

{
    "g" : "test",
    "u" : 1,
    "l" : {
        "x" : 1,
        "y" : 1
    }
}

When I go to my JS client and attempt to do the same, weird things start to happen. Apparently the nested element "l" fails to deserialize when calling the endpoint from Javascript. I wonder why that is?

This is the error message I get in the console:

500 (Can not deserialize instance of java.lang.String out of START_OBJECT token  at [Source: N/A; line: -1, column: -1]) 

Here's my JS function that calls my endpoint.

function init() {
    var myapp = 'http://localhost:8888/_ah/api';
    gapi.client.load('myapp', 'v1', function() {
        var payload = {g:"Test",u:0,l:{x:4,y:4}};
        gapi.client.myapp.unit.move(payload).execute(function(resp) {
            console.log(resp);
        });
    }, myapp);
}

The payload sent to the server is:

[{"jsonrpc":"2.0","id":"gapiRpc","method":"myapp.unit.move","params":{"g":"Test","u":0,"l":{"x":4,"y":4}},"apiVersion":"v1"}]

When I remove the l:{x:4,y:4} from the payload my endpoint gets called just fine.

Seems that I am doing something wrong but what?

See also Owned entity causing json serialization error in Google javascript api client

Upvotes: 4

Views: 412

Answers (1)

bossylobster
bossylobster

Reputation: 10163

Python:

This seems to be an issue with the Java backend, for Python endpoints, I implemented an API that uses a class called Total to hold the data:

from protorpc import messages

class LeftRight(messages.Message):
    x = messages.IntegerField(1)
    y = messages.IntegerField(2)

class Total(messages.Message):
    g = messages.StringField(1)
    u = messages.IntegerField(2)
    l = messages.MessageField(LeftRight, 3)

and then has a dummy Endpoint which just returns back the Total object it received

...
@endpoints.method(Total, Total,
                  path='total', http_method='POST',
                  name='total.total')
def total(self, request):
    return request

and it works perfectly using essentially the same Javascript you included.

I incorporated this into our sample application in a branch I made in my fork. For the specifics, see the commit. NOTE: I made a subsequent commit to get rid of Auth/https so it runs in dev_appserver.

Java:

TBD

Upvotes: 1

Related Questions