Package jsonapi implements a marshaler/unmarshaler for JSON:API v1.0.
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
Take a look at the go reference for more examples and detailed usage information.
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"
// }
// }
// }
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"
The following information is well documented in the go reference. This section is included for a high-level overview of the features available.
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
.
Tag | Usage | Description | Alias |
---|---|---|---|
primary | jsonapi:"primary,{type},{omitempty}" |
Defines the identification field. Including omitempty allows for empty IDs (used for server-side id generation) | N/A |
attribute | jsonapi:"attribute" |
Defines an attribute. | attr |
relationship | jsonapi:"relationship" |
Defines a relationship. | rel |
meta | jsonapi:"meta" |
Defines a meta object. | N/A |
Both jsonapi.Marshal and jsonapi.Unmarshal take functional options.
Option | Supports |
---|---|
jsonapi.MarshalOption | meta, json:api, includes, document links, sparse fieldsets, name validation |
jsonapi.UnmarshalOption | meta, name validation |
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):
Context | Interface |
---|---|
Marshal | jsonapi.MarshalIdentifier |
Unmarshal | jsonapi.UnmarshalIdentifier |
You can implement the following on the field types themselves if they are not already implemented.
Context | Interface |
---|---|
Marshal | fmt.Stringer |
Marshal | encoding.TextMarshaler |
Unmarshal | encoding.TextUnmarshaler |
- Use MarshalIdentifier if it is implemented on the parent type
- Use the value directly if it is a string
- Use fmt.Stringer if it is implemented
- Use encoding.TextMarshaler if it is implemented
- Fail
- Use UnmarshalIdentifier if it is implemented on the parent type
- Use encoding.TextUnmarshaler if it is implemented
- Use the value directly if it is a string
- Fail
Links are supported via two interfaces and the Link type. To include links you must implement one or both of the following interfaces.
Type | Interface |
---|---|
Resource Object Link | Linkable |
Resource Object Related Resource Link | LinkableRelation |
- 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
- 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