Skip to content
This repository was archived by the owner on Sep 4, 2025. It is now read-only.
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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions