-
Notifications
You must be signed in to change notification settings - Fork 218
Asymmetrical behavior with json.RawMessage-type fieldsΒ #178
Description
Hi,
First of all, thanks for this fantastic library.
I'm writing about inconsistent behavior that I run into when working with structs that have arbitrary JSON data as one of their fields. Specifically, I am unable to use UnmarshalPayload
with a JSON:API request body containing the struct's representation. Interestingly enough, I am able to use MarshalPayload
on such a struct if I construct it myself.
Below is a complete code example demonstrating the issue I'm facing:
package main
import (
"bytes"
"encoding/json"
"fmt"
"github.com/google/jsonapi"
)
type CustomType struct {
ID uint `json:"id" jsonapi:"primary,custom_type"`
RawField json.RawMessage `json:"raw" jsonapi:"attr,raw"`
}
const rawBody = `{
"data": {
"type": "custom_type",
"id": "1234",
"attributes": {
"raw": [1, 2, 3]
}
}
}`
func main() {
ct := &CustomType{}
// Try parsing a JSONAPI representation of our struct - fails
if err := jsonapi.UnmarshalPayload(bytes.NewBufferString(rawBody), ct); err != nil {
fmt.Printf("Error parsing input payload: %v\n", err)
} else {
fmt.Printf("Parsed custom type: %v\n", ct)
}
// Compose and serialize a custom type with raw JSON data encoded in it - succeeds
ct2 := &CustomType{
RawField: json.RawMessage(`{"a": "b"}`),
}
b := bytes.NewBuffer(nil)
jsonapi.MarshalPayload(b, ct2)
fmt.Printf("Marhsalled custom type: %s", b)
// Try to feed that same data back into a struct - fails
if err := jsonapi.UnmarshalPayload(b, ct2); err != nil {
fmt.Printf("Error parsing previously marshalled payload: %v\n", err)
}
}
And its output:
Error parsing input payload: data is not a jsonapi representation of '*main.CustomType'
Marhsalled custom type: {"data":{"type":"custom_type","id":"5000","attributes":{"raw":{"a":"b"}}}}
Error parsing marshalled payload: Invalid type provided
AFAIK, JSON:API's standard allows for deeply nested structs or arrays as part of a resource's attributes, as long as they don't contain links or relationships embedded within them. This is indeed my use-case.
I'd be happy to confirm if this behavior is meant to be supported in both directions, and if it is, whether I'm misusing the library or there's a bug that needs fixing. I'll gladly contribute a fix if the latter is true.
Thank you very much!