RPC: post or get and how is the payload handled?

I have a couple of simple RPC functions registered in a Go module. They work fine and return data when called. What they have in common though is that they don’t accept any parameters or other data. I’m at a loss as to how that is supposed to work.

The signature of my function is the normal:

func myStuff(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error) {
...
}

But whatever I do, the payload is empty. The RPC calls are using HTTP GET calls, but passing a body in a GET call is not really something that’s encouraged. But I’ve tried adding a body, but that doesn’t seem to get delivered. Adding parameters to the URL like: /v2/rpc/myStuff?id=foo also doesn’t work and payload is empty.

If I try a POST I see that my function is not called and Nakama returns an error:

{
    "error":"json: cannot unmarshal object into Go value of type string",
    "message":"json: cannot unmarshal object into Go value of type string",
    "code":3
}

What does this mean? Does the server log what it received somewhere? I’m running with debug logging turned on. Or is this a case where the server does own broken JSON validation somehow?

Hm, also, does anyone read these forums? I seem to be pretty alone here.

RPC functions absolutely support both GET and POST, the server does not expect you to send a request body along with a GET request.

Nakama does not explicitly log incoming RPC payloads, what you’re seeing is an error caused by invalid input. You can see curl examples of RPC function calls in the docs.

Note especially the escaping of payloads, but you will likely want to set the unwrap=true query parameter to allow you to send arbitrary unescaped data as the RPC payload.

1 Like

I read that part, but it talks about server to server communication so I didn’t think it was applicable. Adding unwrap to my URL seems to be the thing.

A short mention in the docs about POST and GET would be nice though, now it’s mostly up to trial and error.

“both GET and POST” - i think this is not (no longer?) correct. I try to access a RPC via GET and it does not work.

I use the nakama-js library and there is the “rpcHttpKey” function that internally uses the “rpcFunc2” function that makes a GET call and i’m not sure why it would, because when a session-token is used, it makes a POST call (and that works fine!).

The “payload” query param seems to be ignored in the GET case, making httpkey-requests totally pointless and the library actually useless. I may be doing something wrong, but i can’t find any hint in the documentation.

Example:

Consider the following RPC: (typescript runtime)

initializer.registerRpc('pong',  (ctx, logger, nk, payload) => {
  return JSON.stringify({ my_payload_is: payload });
});

This POST call works:

$ curl "http://127.0.0.1:7350/v2/rpc/pong?http_key=defaulthttpkey" -H 'Content-Type: application/json' -H 'Accept: application/json' -X POST -d "\"money\""
{"payload":"{\"my_payload_is\":\"money\"}"}

however this doesn’t:

$ curl "http://127.0.0.1:7350/v2/rpc/pong?http_key=defaulthttpkey&payload=\"money\"" -H 'Content-Type: application/json' -H 'Accept: application/json' -X GET
{"payload":"{\"my_payload_is\":\"\"}"}

This is related: Javascript - rpcHttpKey function always transfers payload using query params, instead of the utilizing the body · Issue #133 · heroiclabs/nakama-js · GitHub

So question: is it a Bug or Feature?

Edit: So i found this issue Client-sent payloads are empty server-side when calling a client RPC function that uses a GET request (RpcFunc2) · Issue #400 · heroiclabs/nakama · GitHub and they say it is actually a feature :thinking:

@dela I believe it is part of the HTTP spec that GET requests should not contain a body but query params only, so even if the request contains one, the server will ignore it.

i came to that conclusion aswell after looking into the last linked issue.

Nevertheless, the function client.rpcHttpKey(httpKey, id, input) is a. poorly documented and b. the input parameter is useless (as described above).

i would suggest this fix: :wink: rpcHttpKey function uses POST now by delasource · Pull Request #163 · heroiclabs/nakama-js · GitHub