Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asymmetrical behavior with json.RawMessage-type fields #178

Open
omriharel opened this issue Jul 30, 2019 · 0 comments
Open

Asymmetrical behavior with json.RawMessage-type fields #178

omriharel opened this issue Jul 30, 2019 · 0 comments

Comments

@omriharel
Copy link

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant