I'm new to Go and have been trying virtually everything to get my Google Endpoint that's run by Go, to receive a POST with JSON for verification, and then store that in Google Datastore.
Golang endpoint package https://github.com/GoogleCloudPlatform/go-endpoints
Here's an example of the JSON I'm trying to POST to my Go endpoint:
{\"json\": {\"orderId\": \"123456789.12341234\",\"packageName\":\"com.company.name\",\"productId\":\"productName\",\"purchaseTime\": 1410655975266,\"purchaseState\": 0,\"purchaseToken\": \"tokenData\"},\"signature\": \"signatureData\"}
Here's an example of my Golang code for Google endpoints:
type RawReceipt struct {
Key *datastore.Key `json:"id" datastore:"-"`
Receipt json.RawMessage `json:"json"`
}
func ReceiveJson(c endpoints.Context, rec *RawReceipt) error {
k := datastore.NewIncompleteKey(c, "DatastoreTest", nil)
_, err := datastore.Put(c, k, rec)
return err
}
Pseudo code of what I'm trying to accomplish:
var data below will need to contain {\"orderId\": \"123456789.12341234\",\"packageName\":\"com.company.name\",\"productId\":\"productName\",\"purchaseTime\": 1410655975266,\"purchaseState\": 0,\"purchaseToken\": \"tokenData\"},\"signature\": \"signatureData\"}
func Json(rawJson *RawJson) {
data := rawJson["json"]
signature := rawJson["signature"]
if Verify(jsonData, jsonSignature) {
// Store into Datastore
// The storing part works, just need to get the right data into it
k := datastore.NewIncompleteKey(c, "DatastoreTest", nil)
_, err := datastore.Put(c, k, rec)
return err
}
}
func Verify (jsonData *JData, jsonSignature, *Jsig) bool {
//I got this part working just fine.
if fail or err return false, else true
}
I need to be able to grab the values from the keys json and signature so I can pass
{\"json\": {\"orderId\": \"123456789.12341234\",\"packageName\":\"com.company.name\",\"productId\":\"productName\",\"purchaseTime\": 1410655975266,\"purchaseState\": 0,\"purchaseToken\": \"tokenData\"}
to the verification method and the signature
\"signature\": \"signatureData\"
as the other parameter to the verification method as well.
Whats weird is that if I look at the value rec.Receipt, the JSON is out of order e.g. productId is now at the bottom instead of its original position.
And the last thing I need to happen is to take the entire JSON and store that in the Google Datastore.
As a side note, I've been going at this for about 3 days now reading though the documentations, looking at other stackoverflow questions, and have been trying anything to get this work.
Any and all your help(s) is greatly appreciated!
I don't have experience with Google App Engine, but it seems as though your core problem here is with deserializing the JSON so that you can just fetch the "signature" field?
You can json.Unmarshal
the data into a map[string]interface{}
and refer to the signature
field of that map like so:
package main
import (
"encoding/json"
"fmt"
)
const data = `{
"json": {
"orderId": "123456789.12341234",
"packageName": "com.company.name",
"productId": "productName",
"purchaseState": 0,
"purchaseTime": 1410655975266,
"purchaseToken": "tokenData"
},
"signature": "signatureData"
}`
func main() {
receipt := make(map[string]interface{})
json.Unmarshal([]byte(data), &receipt)
signature, ok := receipt["signature"].(string)
if !ok {
fmt.Println("type assertion failed")
return
}
fmt.Println(signature)
}
In that same example you can do fmt.Printf("%#v ", receipt)
which will show you that receipt["json"]
is another map[string]interface{}
. With this you could refer to the fields in json
as:
foo, ok := receipt["json"].(map[string]interface{})
// ... assertion checking, etc.
orderId, ok := foo["orderId"].(string)
// ... assertion checking again
Not sure about storing the JSON in Google Datastore. Give their example here a peek.
As an aside I don't think that Go makes any guarantees about the ordering of key-value pairs so you shouldn't assume that they are going to retain their ordering.
Json as data type is not supported data type
So you have couple of option how to store your data
as @Lander suggested, unmarshal your data and store it as object.
Create RawMessage and store it as []byte.
I cant figure out on another way to do it?