jsonapi

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 23, 2019 License: MIT Imports: 4 Imported by: 0

README

JSONAPI Document Serialization for Go

This library surfaces a simple API for serializing/deserializing JSONAPI documents.

Examples

Serialize a simple resource object
package main

import (
	"fmt"
	"os"

	"github.com/ryanmoran/jsonapi"
)

type Article struct {
	ID    string
	Title string `jsonapi:"title"`
	Body  string `jsonapi:"body"`
}

func (a Article) Type() string {
	return "article"
}

func (a Article) Primary() string {
	return a.ID
}

func main() {
	content, err := jsonapi.Marshal(Article{
		ID:    "1",
		Title: "JSON:API paints my bikeshed!",
		Body:  "The shortest article. Ever.",
	})
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	fmt.Println(string(content))
}
go run main.go
{
  "data": {
    "type": "article",
    "id": "1",
    "attributes": {
      "body": "The shortest article. Ever.",
      "title": "JSON:API paints my bikeshed!"
    }
  }
}
Deserialize a simple resource object
package main

import (
	"fmt"
	"io/ioutil"
	"os"

	"github.com/ryanmoran/jsonapi"
)

type Article struct {
	ID       string
	Title    string `jsonapi:"title"`
	Body     string `jsonapi:"body"`
	AuthorID string
}

func (a Article) Type() string {
	return "article"
}

func (a Article) Primary() string {
	return a.ID
}

func (a *Article) SetPrimary(id string) {
	a.ID = id
}

func main() {
	content, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	var article Article
	err = jsonapi.Unmarshal(content, &article)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	fmt.Printf("%#v\n", article)
}
echo '{
  "data": {
    "type": "article",
    "id": "1",
    "attributes": {
      "body": "The shortest article. Ever.",
      "title": "JSON:API paints my bikeshed!"
    }
  }
}' | go run main.go
main.Article{ID:"1", Title:"JSON:API paints my bikeshed!", Body:"The shortest article. Ever.", AuthorID:""}
Serialize a list of simple resource objects
package main

import (
	"fmt"
	"os"

	"github.com/ryanmoran/jsonapi"
)

type Article struct {
	ID    string
	Title string `jsonapi:"title"`
	Body  string `jsonapi:"body"`
}

func (a Article) Type() string {
	return "article"
}

func (a Article) Primary() string {
	return a.ID
}

func main() {
	content, err := jsonapi.Marshal([]Article{
		{
			ID:    "1",
			Title: "JSON:API paints my bikeshed!",
			Body:  "The shortest article. Ever.",
		},
		{
			ID:    "2",
			Title: "Following up on that short article...",
			Body:  "This article is also pretty short.",
		},
	})
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	fmt.Println(string(content))
}
go run main.go
{
  "data": [
    {
      "type": "article",
      "id": "1",
      "attributes": {
        "body": "The shortest article. Ever.",
        "title": "JSON:API paints my bikeshed!"
      }
    },
    {
      "type": "article",
      "id": "2",
      "attributes": {
        "body": "This article is also pretty short.",
        "title": "Following up on that short article..."
      }
    }
  ]
}
package main

import (
	"fmt"
	"os"

	"github.com/ryanmoran/jsonapi"
)

type Article struct {
	ID       string
	Title    string `jsonapi:"title"`
	Body     string `jsonapi:"body"`
	AuthorID string
}

func (a Article) Type() string {
	return "article"
}

func (a Article) Primary() string {
	return a.ID
}

func (a Article) Links() []jsonapi.Link {
	return []jsonapi.Link{
		{
			Name: "self",
			Href: "/articles/1",
		},
	}
}

func (a Article) Relationships() []jsonapi.Relationship {
	return []jsonapi.Relationship{
		{
			Name: "author",
			Type: jsonapi.SingularRelationship,
			Resource: Person{
				ID: "42",
			},
		},
	}
}

func (a Article) Meta() jsonapi.Meta {
  return jsonapi.Meta{
    "views": 100
  }
}

type Person struct {
	ID string
}

func (p Person) Type() string {
	return "person"
}

func (p Person) Primary() string {
	return p.ID
}

func main() {
	content, err := jsonapi.Marshal(Article{
		ID:       "1",
		Title:    "JSON:API paints my bikeshed!",
		Body:     "The shortest article. Ever.",
		AuthorID: "42",
	})
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	fmt.Println(string(content))
}
go run main.go
{
  "data": {
    "type": "article",
    "id": "1",
    "attributes": {
      "body": "The shortest article. Ever.",
      "title": "JSON:API paints my bikeshed!"
    },
    "links": {
      "self": {
        "href": "/articles/1"
      }
    },
    "relationships": {
      "author": {
        "data": {
          "type": "person",
          "id": "42"
        }
      }
    },
    "meta": {
      "views": 100
    }
  }
}
Deserialize a resource object with relationships
package main

import (
	"fmt"
	"io/ioutil"
	"os"

	"github.com/ryanmoran/jsonapi"
)

type Article struct {
	ID       string
	Title    string `jsonapi:"title"`
	Body     string `jsonapi:"body"`
	AuthorID string
}

func (a Article) Type() string {
	return "article"
}

func (a Article) Primary() string {
	return a.ID
}

func (a *Article) SetPrimary(id string) {
	a.ID = id
}

func (a *Article) AssignRelationships(relationships []jsonapi.Relationship) {
	for _, relationship := range relationships {
		if relationship.Name == "author" {
			a.AuthorID = relationship.Resource.Primary()
		}
	}
}

func main() {
	content, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	var article Article
	err = jsonapi.Unmarshal(content, &article)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	fmt.Printf("%#v\n", article)
}
echo '{
  "data": {
    "type": "article",
    "id": "1",
    "attributes": {
      "body": "The shortest article. Ever.",
      "title": "JSON:API paints my bikeshed!"
    },
    "links": {
      "self": {
        "href": "/articles/1"
      }
    },
    "relationships": {
      "author": {
        "data": {
          "type": "person",
          "id": "42"
        }
      }
    }
  }
}
' | go run main.go
main.Article{ID:"1", Title:"JSON:API paints my bikeshed!", Body:"The shortest article. Ever.", AuthorID:"42"}

Documentation

Index

Constants

View Source
const ContentType = "application/vnd.api+json"

Variables

This section is empty.

Functions

func Marshal

func Marshal(v interface{}) ([]byte, error)

func NewDecodeError

func NewDecodeError(v interface{}, message string) error

func NewEncodeError

func NewEncodeError(v interface{}, message string) error

func NewNotDecodableError

func NewNotDecodableError(v interface{}) error

func NewNotEncodableError

func NewNotEncodableError(v interface{}) error

func Unmarshal

func Unmarshal(data []byte, v interface{}) error

Types

type Decodable

type Decodable interface {
	Type() string
	SetPrimary(id string)
}

type DecodeAttributes

type DecodeAttributes struct {
	// contains filtered or unexported fields
}

func NewDecodeAttributes

func NewDecodeAttributes(d Decodable) DecodeAttributes

func (DecodeAttributes) UnmarshalJSON

func (da DecodeAttributes) UnmarshalJSON(data []byte) error

type DecodeDocument

type DecodeDocument struct {
	// contains filtered or unexported fields
}

func NewDecodeDocument

func NewDecodeDocument(d Decodable) DecodeDocument

func (DecodeDocument) UnmarshalJSON

func (dd DecodeDocument) UnmarshalJSON(data []byte) error

type DecodeError

type DecodeError struct {
	// contains filtered or unexported fields
}

func (DecodeError) Error

func (e DecodeError) Error() string

type DecodePayload

type DecodePayload struct {
	// contains filtered or unexported fields
}

func NewDecodePayload

func NewDecodePayload(v interface{}) DecodePayload

func (DecodePayload) UnmarshalJSON

func (dp DecodePayload) UnmarshalJSON(data []byte) error

type DecodeRelationships

type DecodeRelationships struct {
	// contains filtered or unexported fields
}

func NewDecodeRelationships

func NewDecodeRelationships(d Decodable) DecodeRelationships

func (DecodeRelationships) UnmarshalJSON

func (dr DecodeRelationships) UnmarshalJSON(data []byte) error

type DecodeResourceLinkage

type DecodeResourceLinkage struct {
	ResourceType string
	ID           string
}

func (DecodeResourceLinkage) Primary

func (drl DecodeResourceLinkage) Primary() string

func (DecodeResourceLinkage) Type

func (drl DecodeResourceLinkage) Type() string

type DecodeResourceObject

type DecodeResourceObject struct {
	// contains filtered or unexported fields
}

func NewDecodeResourceObject

func NewDecodeResourceObject(d Decodable) DecodeResourceObject

func (DecodeResourceObject) UnmarshalJSON

func (dro DecodeResourceObject) UnmarshalJSON(data []byte) error

type Encodable

type Encodable interface {
	Type() string
	Primary() string
}

func ToEncodable

func ToEncodable(v interface{}) (Encodable, error)

type EncodeAttributes

type EncodeAttributes map[string]interface{}

func NewEncodeAttributes

func NewEncodeAttributes(m interface{}) EncodeAttributes

type EncodeDocument

type EncodeDocument struct {
	Data   json.Marshaler `json:"data,omitempty"`
	Errors Errors         `json:"errors,omitempty"`
}

func NewErrorsEncodeDocument

func NewErrorsEncodeDocument(errors Errors) (EncodeDocument, error)

func NewMultipleEncodeDocument

func NewMultipleEncodeDocument(m interface{}) (EncodeDocument, error)

func NewSingularEncodeDocument

func NewSingularEncodeDocument(m interface{}) (EncodeDocument, error)

type EncodeError

type EncodeError struct {
	// contains filtered or unexported fields
}

func (EncodeError) Error

func (e EncodeError) Error() string
type EncodeLinks map[string]Link
func NewEncodeLinks(m interface{}) EncodeLinks

type EncodeMeta added in v0.2.0

type EncodeMeta map[string]interface{}

func NewEncodeMeta added in v0.2.0

func NewEncodeMeta(m interface{}) EncodeMeta

type EncodePayload

type EncodePayload struct {
	// contains filtered or unexported fields
}

func NewEncodePayload

func NewEncodePayload(m interface{}) EncodePayload

func (EncodePayload) MarshalJSON

func (ep EncodePayload) MarshalJSON() ([]byte, error)

type EncodeRelationships

type EncodeRelationships map[string]RelationshipDocument

func NewEncodeRelationships

func NewEncodeRelationships(m interface{}) EncodeRelationships

type EncodeResourceLinkage

type EncodeResourceLinkage struct {
	Type string
	ID   string
}

func NewEncodeResourceLinkage

func NewEncodeResourceLinkage(e Encodable) EncodeResourceLinkage

func (EncodeResourceLinkage) MarshalJSON

func (erl EncodeResourceLinkage) MarshalJSON() ([]byte, error)

type EncodeResourceLinkages

type EncodeResourceLinkages []EncodeResourceLinkage

func (EncodeResourceLinkages) MarshalJSON

func (erl EncodeResourceLinkages) MarshalJSON() ([]byte, error)

type EncodeResourceObject

type EncodeResourceObject struct {
	Type          string
	ID            string
	Attributes    EncodeAttributes
	Links         EncodeLinks
	Relationships EncodeRelationships
	Meta          EncodeMeta
}

func NewEncodeResourceObject

func NewEncodeResourceObject(encodable Encodable) EncodeResourceObject

func (EncodeResourceObject) MarshalJSON

func (ero EncodeResourceObject) MarshalJSON() ([]byte, error)

type EncodeResourceObjects

type EncodeResourceObjects []EncodeResourceObject

func (EncodeResourceObjects) MarshalJSON

func (ero EncodeResourceObjects) MarshalJSON() ([]byte, error)

type Error

type Error struct {
	ID     string `json:"id,omitempty"`
	Status Status `json:"status,omitempty"`
	Code   string `json:"code,omitempty"`
	Title  string `json:"title,omitempty"`
	Detail string `json:"detail,omitempty"`
}

type Errors

type Errors []Error
type Link struct {
	Name string `json:"-"`
	Href string `json:"href"`
}

type Linkable

type Linkable interface {
	Links() []Link
}

type Meta added in v0.2.0

type Meta map[string]interface{}

type Metable added in v0.2.0

type Metable interface {
	Meta() Meta
}

type Relatable

type Relatable interface {
	Relationships() []Relationship
}

type Relationship

type Relationship struct {
	Name     string
	Type     RelationshipType
	Resource Encodable
}

type RelationshipDocument

type RelationshipDocument struct {
	Data json.Marshaler `json:"data"`
}

type RelationshipType

type RelationshipType int
const (
	Unknown RelationshipType = iota
	SingularRelationship
	MultiRelationship
)

type RelationshipsAssignable

type RelationshipsAssignable interface {
	AssignRelationships([]Relationship)
}

type Status

type Status int

func (Status) MarshalJSON

func (s Status) MarshalJSON() ([]byte, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL