400 bad request error When trying to call custom RPC

Description

I am very new to Nakama , I started playing around Nakama and tried to access Nakama by rpc.

we are started using Nakama for our game dev purposes

When trying to call custom RPC registered using sling client in go its failing and returning "400 with bad request " error in the response from nakama

i am trying to access the rpc function i registered in nakama as “create_match_table”

the code is given below. i was trying with sling http requests

even I tried with simple http request , but no luck, the code is given for the http post request

func main() {
url := "http://127.0.0.1:7350/v2/rpc/create_match_table?http_key=defalutkey"
fmt.Println("URL:>", url)

payloadbuff := []byte(`{\"house_id\":\"mega\",\"tour_id\":\"devtourId\",\"table_config\":{\"nakama_table_label\":\"pokertable\",\"small_blind\":25,\"min_buy_in\":20,\"max_buy_in\":40,\"table_start_min_player_count\":2,\"table_start_max_player_count\":6,\"inr_conv_rate\":0.2}}`)
req, err := http.NewRequest("POST", url, bytes.NewBuffer(payloadbuff))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
	panic(err)
}
defer resp.Body.Close()

fmt.Println("response Status:", resp.Status)
fmt.Println("response Headers:", resp.Header)
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println("response Body:", string(body))

}`

output :

response Status: 400 Bad Request
response Headers: map[Cache-Control:[no-store, no-cache, must-revalidate] Content-Type:[application/x-gzip] Date:[Sat, 07 Mar 2020 14:04:24 GMT] Vary:[Accept-Encoding]]
response Body: {“error”:“json: cannot unmarshal object into Go value of type string”,“message”:“json: cannot unmarshal object into Go value of type string”,“code”:3}

i don’t really understand why this error is coming ,is it because of payload is in string format in nakama function signature?, the code that i wrote in nakama under this rpc function call back also not hitting?

but when i am trying with simple curl request it is working fine

 curl "http://127.0.0.1:7350/v2/rpc/create_match_table?http_key=defalutkey"      -d '"{\"house_id\":\"mega\",\"tour_id\":\"devtbel\":\"pokertable\",\"small_blind\":25,\"min_buy_in\":20,\"max_buy_in\":40,\"table_start_min_player_count\":2,\"table_start_max_player_count\":6,\"inr_conv_rate\":0.2}}"'      -H 'Content-Type: application/json'      -H 'Accept: application/json'

any help would be really appreciated

part from that I am trying to use

// Execute a Lua function on the server.
RpcFunc(ctx context.Context, in *api.Rpc, opts ...grpc.CallOption) (*api.Rpc, error)

function to call my custom rpc , why there is a httpkey in response as well

I am new to this as well , if there any link to custom code , like how to dial securely

Details

*Nakama:“Node”,“name”:“nakama1”,“version”:“2.7.0+d5e0b5bb”,“runtime”:“go1.13”,“cpu”:4,“proc”:4}

  • Database: "CockroachDB CCL v19.1.2 (x86_64-unknown-linux-gnu, built 2019/06/07 17:32:15, go1.11.6)
  • Environment name and version: docker
  • Operating System and version: Mac osx

this error got fixed when i tried with unwrap=true , that i found in gitter community.

but there is some difficulty in unmarshaling the data in game sever side .

i was using .

 err := json.Unmarshal([]byte(payload), in)

but giving

“Error”: “invalid character ‘\\’ looking for beginning of object key string”,

so how i will wrap it back ?

any help would be great, thanks in advance

@JunaidMkdn I think lets step back and clear up any confusion. First of all we have two ways to initiate an RPC request:

  1. The first is as an authenticated user with a session token. This is how all of our open-source client sdks make requests to execute custom logic on the server.
  2. The second is with the http key as a server to server (S2S) function call. This is useful if you have other custom game services written or need to interact with 3rd party services as well as webhooks.

i don’t really understand why this error is coming ,is it because of payload is in string format in nakama function signature?, the code that i wrote in nakama under this rpc function call back also not hitting?

The reason your code worked over cURL but not with your Go code is because the content body you’ve written to the server is not the same. In the cURL example you’ve used:

'"{\"house_id\":\"mega\",\"tour_id\":\"devtbel\":\"pokertable\",\"small_blind\":25,\"min_buy_in\":20,\"max_buy_in\":40,\"table_start_min_player_count\":2,\"table_start_max_player_count\":6,\"inr_conv_rate\":0.2}}"'

In your Go code you’ve used a JSON payload whereas with cURL its an escaped JSON string as input. A quick example of the difference is:

var foo = {"bar": true};
var json = JSON.stringify(foo); output -> "{\"bar\":true}"
JSON.stringify(json); output -> "\"{\\\"bar\\\":true}\""

The reason the input needs to be escaped as a regular string is because the server uses Protobuf internally and Protobuf has no concept of JSON. The input is essentially a string field that gets parsed into a JSON object by the server. This is why you see the error:

json: cannot unmarshal object into Go value of type string

In a recent version of the server we added a query parameter option called unwrap which does not go through the Protobuf layer in the server and can accept a JSON object as input. From your example in cURL this would look like:

curl "http://127.0.0.1:7350/v2/rpc/create_match_table?http_key=defaulthttpkey&unwrap=true" --data '{ "house_id": "mega", "tour_id": "someid", "devtbel": "pokertable", "small_blind": 25, "min_buy_in": 20, "max_buy_in": 40, "table_start_min_player_count": 2, "table_start_max_player_count": 6, "inr_conv_rate": 0.2 }'

Please take careful note of the structure of the JSON --data passed to the RPC function and also note I’ve tested against the Nakama 2.11.0 release but it will work with any version newer than the 2.7.0 release.

thanks for the support

I can’t tell if this is sincere or not but you should not expect the forums to give you instant responses to your questions. It’s a community so please act with grace and kindness or you will be banned.

@novabyte,
I’m sorry I made you feel that way. i didn’t mean it , i really understand why my code is not working and i got the reason from gitter.im / heroiclab/nakama community, that is why i thanked ,i am just getting started with it… anyway thank you again for your detailed explanation:)

No worries @JunaidMkdn. I’m glad its solved :+1:

1 Like