Categorygithub.com/DataDog/jsonapi
modulepackage
0.10.0
Repository: https://github.com/datadog/jsonapi.git
Documentation: pkg.go.dev

# README

Go Reference test golangci-lint GitHub release (latest SemVer)

jsonapi

Package jsonapi implements a marshaler/unmarshaler for JSON:API v1.0.

Version

This package is in production use at DataDog and should be considered stable and production ready.

We follow semver and are reserving the v1.0.0 release until:

  • JSON:API v1.1 is released and we evaluate any breaking changes needed (unlikely)
  • Community adoption and feedback are evaluated
  • Continued internal use lets us gain more experience with the package

Quickstart

Take a look at the go reference for more examples and detailed usage information.

Marshaling

jsonapi.Marshal

type Article struct {
    ID    string `jsonapi:"primary,articles"`
    Title string `jsonapi:"attribute" json:"title"`
}

a := Article{ID: "1", Title:"Hello World"}

b, err := jsonapi.Marshal(&a)
if err != nil {
    // ...
}

fmt.Println("%s", string(b))
// {
//     "data": {
//         "id": "1",
//         "type": "articles",
//         "attributes": {
//             "title": "Hello World"
//         }
//     }
// }

Unmarshaling

jsonapi.Unmarshal

body := `{"data":{"id":"1","type":"articles","attributes":{"title":"Hello World"}}}`

type Article struct {
    ID    string `jsonapi:"primary,articles"`
    Title string `jsonapi:"attribute" json:"title"`
}

var a Article
if err := jsonapi.Unmarshal([]byte(body), &a); err != nil {
    // ...
}

fmt.Prints("%s, %s", a.ID, a.Title)
// "1", "Hello World"

Reference

The following information is well documented in the go reference. This section is included for a high-level overview of the features available.

Struct Tags

Like encoding/json jsonapi is primarily controlled by the presence of a struct tag jsonapi. The standard json tag is still used for naming and omitempty.

TagUsageDescriptionAlias
primaryjsonapi:"primary,{type},{omitempty}"Defines the identification field. Including omitempty allows for empty IDs (used for server-side id generation)N/A
attributejsonapi:"attribute"Defines an attribute.attr
relationshipjsonapi:"relationship"Defines a relationship.rel
metajsonapi:"meta"Defines a meta object.N/A

Functional Options

Both jsonapi.Marshal and jsonapi.Unmarshal take functional options.

OptionSupports
jsonapi.MarshalOptionmeta, json:api, includes, document links, sparse fieldsets, name validation
jsonapi.UnmarshalOptionmeta, document links, name validation

Non-String Identifiers

Identification MUST be represented as a string regardless of the actual type in Go. To support non-string types for the primary field you can implement optional interfaces.

You can implement the following on the parent types (that contain non-string fields):

ContextInterface
Marshaljsonapi.MarshalIdentifier
Unmarshaljsonapi.UnmarshalIdentifier

You can implement the following on the field types themselves if they are not already implemented.

ContextInterface
Marshalfmt.Stringer
Marshalencoding.TextMarshaler
Unmarshalencoding.TextUnmarshaler

Order of Operations

Marshaling

  1. Use MarshalIdentifier if it is implemented on the parent type
  2. Use the value directly if it is a string
  3. Use fmt.Stringer if it is implemented
  4. Use encoding.TextMarshaler if it is implemented
  5. Fail

Unmarshaling

  1. Use UnmarshalIdentifier if it is implemented on the parent type
  2. Use encoding.TextUnmarshaler if it is implemented
  3. Use the value directly if it is a string
  4. Fail

Links

Links are supported via two interfaces and the Link type. To include links you must implement one or both of the following interfaces.

TypeInterface
Resource Object LinkLinkable
Resource Object Related Resource LinkLinkableRelation

Alternatives

google/jsonapi

  • exposes an API that looks/feels a lot different than encoding/json
  • has quite a few bugs w/ complex types in attributes
  • doesn't provide easy access to top-level fields like meta
  • allows users to generate invalid JSON:API
  • not actively maintained

manyminds/api2go/jsonapi

  • has required interfaces
  • interfaces for includes/relationships are hard to understand and verbose to implement
  • allows users to generate invalid JSON:API
  • part of a broader api2go framework ecosystem

# Functions

Marshal returns the json:api encoding of v.
MarshalClientMode enables client mode which skips validation only relevant for servers writing JSON:API responses.
MarshalFields supports sparse fieldsets as defined by https://jsonapi.org/format/1.0/#fetching-sparse-fieldsets.
MarshalInclude includes the json:api encoding of v within Document.Included creating a compound document as defined by https://jsonapi.org/format/#document-compound-documents.
MarshalJSONAPI includes the given meta (must be a map or struct) as Document.JSONAPI.Meta when marshaling.
MarshalLinks includes the given links as Document.Links when marshaling.
MarshalMeta includes the given meta (must be a map or struct) as Document.Meta when marshaling.
MarshalSetNameValidation enables a given level of document member name validation.
Status provides a helper for setting an Error.Status value.
Unmarshal parses the json:api encoded data and stores the result in the value pointed to by v.
UnmarshalLinks copies the Document.Links into the given link.
UnmarshalMeta decodes Document.Meta into the given interface when unmarshaling.
UnmarshalSetNameValidation enables a given level of document member name validation.

# Constants

DefaultValidation verifies that member names are valid according to the spec in https://jsonapi.org/format/#document-member-names.
DisableValidation turns off member name validation for convenience or performance-saving reasons.
StrictValidation verifies that member names are valid according to the spec in https://jsonapi.org/format/#document-member-names, and follow recommendations from https://jsonapi.org/recommendations/#naming.

# Variables

ErrDocumentMissingRequiredMembers indicates that a document does not have at least one required top-level member.
ErrEmptyDataObject indicates that a primary or relationship data member is incorrectly represented by an empty JSON object {}.
ErrEmptyPrimaryField indicates that the id (primary) field is identified but empty.
ErrErrorUnmarshalingNotImplemented indicates that an attempt was made to unmarshal an error document.
ErrMarshalInvalidPrimaryField indicates that the id (primary) fields was invalid.
ErrMissingLinkFields indicates that a LinkObject is not valid.
ErrMissingPrimaryField indicates that the id (primary) field is not identified.
ErrRelationshipMissingRequiredMembers indicates that a relationship does not have at least one required member.
ErrUnmarshalDuplicatePrimaryField indicates that the id (primary) field is duplicated in a struct.
ErrUnmarshalInvalidPrimaryField indicates that the id (primary) fields was invalid.

# Structs

Error represents a JSON:API error object as defined by https://jsonapi.org/format/1.1/#error-objects.
ErrorLink represents a JSON:API error links object as defined by https://jsonapi.org/format/1.1/#error-objects.
ErrorSource represents a JSON:API Error.Source as defined by https://jsonapi.org/format/1.1/#error-objects.
Link is the top-level links object as defined by https://jsonapi.org/format/1.0/#document-top-level.
LinkObject is a links object as defined by https://jsonapi.org/format/1.0/#document-links.
Marshaler is configured internally via MarshalOption's passed to Marshal.
MemberNameValidationError indicates that a document member name failed a validation step.
PartialLinkageError indicates that an incomplete relationship chain was encountered.
TagError indicates that an invalid struct tag was encountered.
TypeError indicates that an unexpected type was encountered.
Unmarshaler is configured internally via UnmarshalOption's passed to Unmarshal.

# Interfaces

Linkable can be implemented to marshal resource object links as defined by https://jsonapi.org/format/1.0/#document-resource-object-links.
LinkableRelation can be implemented to marshal resource object related resource links as defined by https://jsonapi.org/format/1.0/#document-resource-object-related-resource-links.
MarshalIdentifier can be optionally implemented to control marshaling of the primary field to a string.
UnmarshalIdentifier can be optionally implemented to control unmarshaling of the primary field from a string.

# Type aliases

MarshalOption allows for configuration of Marshaling.
MemberNameValidationMode controls how document member names are checked for correctness.
UnmarshalOption allows for configuration of Unmarshaling.