Skip to content
This repository was archived by the owner on Sep 4, 2025. It is now read-only.

Asymmetrical behavior with json.RawMessage-type fieldsΒ #178

@omriharel

Description

@omriharel

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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions