Documentation
¶
Index ¶
- Constants
- func Marshal(payload interface{}) ([]byte, error)
- type Document
- type ErrorObject
- type ErrorObjectSource
- type MarshalData
- type MarshalErrors
- type MarshalIncluded
- type MarshalMeta
- type MarshalRelationships
- type MarshalResourceIdentifier
- type ResourceObject
- type ResourceObjectIdentifier
- type UnmarshalData
- type UnmarshalErrors
- type UnmarshalRelationships
- type UnmarshalResourceIdentifier
Examples ¶
Constants ¶
const ContentType = "application/vnd.api+json"
ContentType describes data content type.
Variables ¶
This section is empty.
Functions ¶
func Marshal ¶
Marshal serialize Go struct into []byte JSON API document If the corresponding interfaces are implemented the output will contain, relationships, included, meta and errors.
Example ¶
package main
import (
"fmt"
"github.com/pieoneers/jsonapi-go"
"time"
)
type TestMarshalMeta struct {
Count int `json:"count"`
}
type MarshalBook struct {
ID string `json:"-"`
AuthorID string `json:"-"`
Title string `json:"title"`
PublicationDate time.Time `json:"publication_date"`
}
func (b MarshalBook) GetID() string {
return b.ID
}
func (b MarshalBook) GetType() string {
return "books"
}
func (b MarshalBook) GetData() interface{} {
return b
}
func (b MarshalBook) GetRelationships() map[string]interface{} {
relationships := make(map[string]interface{})
relationships["author"] = jsonapi.ResourceObjectIdentifier{
ID: b.AuthorID,
Type: "authors",
}
return relationships
}
func (b MarshalBook) GetIncluded() []interface{} {
var included []interface{}
for _, author := range authors {
if author.ID == b.AuthorID {
included = append(included, author)
}
}
return included
}
type MarshalBooks []MarshalBook
func (b MarshalBooks) GetData() interface{} {
return b
}
func (b MarshalBooks) GetMeta() interface{} {
return TestMarshalMeta{Count: len(books)}
}
func (b MarshalBooks) GetIncluded() []interface{} {
var included []interface{}
authorsMap := make(map[string]MarshalAuthor)
for _, book := range b {
for _, author := range authors {
if book.AuthorID == author.ID {
authorsMap[author.ID] = author
}
}
}
for _, author := range authorsMap {
included = append(included, author)
}
return included
}
type MarshalAuthor struct {
ID string `json:"-"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
}
func (a MarshalAuthor) GetID() string {
return a.ID
}
func (a MarshalAuthor) GetType() string {
return "authors"
}
func (a MarshalAuthor) GetData() interface{} {
return a
}
func (a MarshalAuthor) GetIncluded() []interface{} {
var included []interface{}
for _, book := range books {
if book.AuthorID == a.ID {
included = append(included, book)
}
}
return included
}
type MarshalAuthors []MarshalAuthor
func (a MarshalAuthors) GetMeta() interface{} {
return TestMarshalMeta{Count: len(authors)}
}
func (a MarshalAuthors) GetData() interface{} {
return a
}
func (a MarshalAuthors) GetIncluded() []interface{} {
var included []interface{}
booksMap := make(map[string]MarshalBook)
for _, author := range a {
for _, book := range books {
if book.AuthorID == author.ID {
booksMap[book.ID] = book
}
}
}
for _, book := range booksMap {
included = append(included, book)
}
return included
}
var (
authors MarshalAuthors
books MarshalBooks
)
func main() {
var publicationDate time.Time
alan := MarshalAuthor{
ID: "1",
FirstName: "Alan A. A.",
LastName: "Donovan",
}
authors = append(authors, alan)
lex := MarshalAuthor{
ID: "2",
FirstName: "Lex",
LastName: "Sheehan",
}
authors = append(authors, lex)
william := MarshalAuthor{
ID: "3",
FirstName: "William",
LastName: "Kennedy",
}
authors = append(authors, william)
publicationDate, _ = time.Parse(time.RFC3339, "2015-01-01T00:00:00Z")
book1 := MarshalBook{
ID: "1",
Title: "Go Programming Language",
AuthorID: alan.ID,
PublicationDate: publicationDate,
}
books = append(books, book1)
publicationDate, _ = time.Parse(time.RFC3339, "2017-11-01T00:00:00Z")
book2 := MarshalBook{
ID: "2",
Title: "Learning Functional Programming in Go",
AuthorID: lex.ID,
PublicationDate: publicationDate,
}
books = append(books, book2)
publicationDate, _ = time.Parse(time.RFC3339, "2015-11-01T00:00:00Z")
book3 := MarshalBook{
ID: "3",
Title: "Go in Action",
AuthorID: william.ID,
PublicationDate: publicationDate,
}
books = append(books, book3)
bookJSON, _ := jsonapi.Marshal(book1)
fmt.Printf("book JSON:\n%v\n", string(bookJSON))
booksJSON, _ := jsonapi.Marshal(books)
fmt.Printf("books JSON:\n%v\n", string(booksJSON))
authorJSON, _ := jsonapi.Marshal(alan)
fmt.Printf("author JSON:\n%v\n", string(authorJSON))
authorsJSON, _ := jsonapi.Marshal(authors)
fmt.Printf("authors JSON:\n%v\n", string(authorsJSON))
}
Types ¶
type Document ¶
type Document struct {
// Document data
Data *documentData `json:"data,omitempty"`
// Document errors
Errors []*ErrorObject `json:"errors,omitempty"`
// Document included
Included []*ResourceObject `json:"included,omitempty"`
// Document meta
Meta json.RawMessage `json:"meta,omitempty"`
}
Document describes Go representation of JSON API document.
func Unmarshal ¶
Unmarshal deserialize JSON API document into Gu sturct If the corresponding interfaces are implemented target will contain data from JSON API document relationships and errors.
Example ¶
package main
import (
"fmt"
"github.com/pieoneers/jsonapi-go"
"time"
)
var bookJSON = []byte(`
{
"data": {
"type": "books",
"id": "1",
"attributes": {
"title": "Go Programming Language",
"publication_date": "2015-01-01T00:00:00Z"
},
"relationships": {
"author": {
"data": {
"type": "authors",
"id": "1"
}
}
}
}
}
`)
var authorJSON = []byte(`
{
"data": {
"type": "authors",
"id": "1",
"attributes": {
"first_name": "Alan A. A.",
"last_name": "Donovan"
}
}
}
`)
var booksJSON = []byte(`
{
"data":
[
{
"type": "books",
"id": "1",
"attributes": {
"title": "Go Programming Language",
"publication_date": "2015-01-01T00:00:00Z"
},
"relationships": {
"author": {
"data": {
"type": "authors",
"id": "1"
}
}
}
},
{
"type": "books",
"id": "2",
"attributes": {
"title": "Learning Functional Programming in Go",
"publication_date": "2017-11-01T00:00:00Z"
},
"relationships": {
"author": {
"data": {
"type": "authors",
"id": "2"
}
}
}
},
{
"type": "books",
"id": "3",
"attributes": {
"title": "Go in Action",
"publication_date": "2015-11-01T00:00:00Z"
},
"relationships": {
"author": {
"data": {
"type": "authors",
"id": "3"
}
}
}
}
]
}
`)
var authorsJSON = []byte(`
{
"data": [
{
"type": "authors",
"id": "1",
"attributes": {
"first_name": "Alan A. A.",
"last_name": "Donovan"
}
},
{
"type": "authors",
"id": "2",
"attributes": {
"first_name": "Lex",
"last_name": "Sheehan"
}
},
{
"type": "authors",
"id": "3",
"attributes": {
"first_name": "William",
"last_name": "Kennedy"
}
}
]
}
`)
type UnmarshalBook struct {
ID string `json:"-"`
Type string `json:"-"`
AuthorID string `json:"-"`
Title string `json:"title"`
PublicationDate time.Time `json:"publication_date"`
}
func (b *UnmarshalBook) SetID(id string) error {
b.ID = id
return nil
}
func (b *UnmarshalBook) SetType(t string) error {
b.Type = t
return nil
}
func (b *UnmarshalBook) SetData(to func(target interface{}) error) error {
return to(b)
}
func (b *UnmarshalBook) SetRelationships(relationships map[string]interface{}) error {
if relationship, ok := relationships["author"]; ok {
b.AuthorID = relationship.(*jsonapi.ResourceObjectIdentifier).ID
}
return nil
}
type UnmarshalBooks []UnmarshalBook
func (b *UnmarshalBooks) SetData(to func(target interface{}) error) error {
return to(b)
}
type UnmarshalAuthor struct {
ID string `json:"-"`
Type string `json:"-"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
}
func (a *UnmarshalAuthor) SetID(id string) error {
a.ID = id
return nil
}
func (a *UnmarshalAuthor) SetType(t string) error {
a.Type = t
return nil
}
func (a *UnmarshalAuthor) SetData(to func(target interface{}) error) error {
return to(a)
}
type UnmarshalAuthors []UnmarshalAuthor
func (a *UnmarshalAuthors) SetData(to func(target interface{}) error) error {
return to(a)
}
func printBook(b UnmarshalBook) {
fmt.Printf("ID:\t%v,\nType:\t%v\nAuthorID:\t%v\nTitle:\t%v\nPublicationDate:\t%v\n", b.ID, b.Type, b.AuthorID, b.Title, b.PublicationDate)
}
func printAuthor(a UnmarshalAuthor) {
fmt.Printf("ID:\t%v,\nType:\t%v\nFirstName:\t%v\nLastName:\t%v\n", a.ID, a.Type, a.FirstName, a.LastName)
}
func main() {
book := UnmarshalBook{}
books := UnmarshalBooks{}
author := UnmarshalAuthor{}
authors := UnmarshalAuthors{}
fmt.Printf("Book\n")
jsonapi.Unmarshal(bookJSON, &book)
printBook(book)
fmt.Printf("\nBooks\n")
jsonapi.Unmarshal(booksJSON, &books)
for _, b := range books {
printBook(b)
}
fmt.Printf("\nAuthor\n")
jsonapi.Unmarshal(authorJSON, &author)
printAuthor(author)
fmt.Printf("\nAuthors\n")
jsonapi.Unmarshal(authorsJSON, &authors)
for _, a := range authors {
printAuthor(a)
}
}
type ErrorObject ¶
type ErrorObject struct {
// Title a short, human-readable summary of the problem.
Title string `json:"title,omitempty"`
// Code application specified value to identify the error.
Code string `json:"code,omitempty"`
// Source an object containing references to the source of the error.
Source ErrorObjectSource `json:"source,omitempty"`
}
ErrorObject JSON API error object https://jsonapi.org/format/#error-objects
type ErrorObjectSource ¶
type ErrorObjectSource struct {
// Pointer a JSON Pointer [RFC6901] to the associated entity in the request document [e.g. "/data" for a primary data object, or "/data/attributes/title" for a specific attribute].
Pointer string `json:"pointer,omitempty"`
}
ErrorObjectSource includes pointer ErrorObject.Source
type MarshalData ¶
type MarshalData interface {
GetData() interface{}
}
MarshalData interface should be implemented to be able get data from Go struct and marshal it.
GetData example:
func(s SomeStruct) GetData() interface{} {
return s
}
type MarshalErrors ¶
type MarshalErrors interface {
GetErrors() []*ErrorObject
}
MarshalErrors interface should be implemented to be able marshal errors into JSON API document.
GetErrors example:
type SomeErrorType struct {
Code string
Title string
Pointer string
}
type SomeErrorTypes []SomeErrorType
func(e SomeErrors) GetErrors() []*jsonapi.ErrorObject {
var errs []*jsonapi.ErrorObject
for _, err := range e {
errs = append(errs, &jsonapi.ErrorObject{
Title: err.Title,
Code: err.Code,
Source: jsonapi.ErrorObjectSource{
Pointer: err.Pointer,
},
})
}
return errs
}
type MarshalIncluded ¶
type MarshalIncluded interface {
GetIncluded() []interface{}
}
MarshalIncluded interface should be implemented to be able marshal JSON API document included.
GetIncluded example:
func(v SomeStruct) GetIncluded() []interface{} {
var included []interface{}
/*
Get some additional data here and put it into `items` variables
`items` data type should implement MarshalResourceIdentifier and MarshalData interface.
*/
for _, item := range items {
included = append(included, item)
}
return included
}
type MarshalMeta ¶
type MarshalMeta interface {
GetMeta() interface{}
}
MarshalMeta interface should be implemented to be able marshal JSON API document meta.
GetMeta example:
type Meta struct {
Count int `json:"count"`
}
func(v SomeStruct) GetMeta() interface{} {
return Meta{ Count: 42 }
}
type MarshalRelationships ¶
type MarshalRelationships interface {
GetRelationships() map[string]interface{}
}
MarshalRelationships interface should be implemented to be able marshal JSON API document relationships.
GetRelationships example:
func(s SomeStruct) GetRelationships() map[string]interface{} {
relationships := make(map[string]interface{})
relationships["relation"] = jsonapi.ResourceObjectIdentifier{
ID: s.RelationID,
Type: "relation-type",
}
return relationships
}
type MarshalResourceIdentifier ¶
MarshalResourceIdentifier interface should be implemented to be able marshal Go struct into JSON API document.
GetID example:
func(s SomeStruct) GetID() string {
return s.ID
}
func(s SomeStruct) GetType() string {
return d.Type
}
or
func(s SomeStruct) GetType() string {
return "some-resource-type"
}
type ResourceObject ¶
type ResourceObject struct {
ResourceObjectIdentifier
// Attributes JSON API document attributes raw data.
Attributes json.RawMessage `json:"attributes,omitempty"`
// Meta JSON API document meta raw data.
Meta json.RawMessage `json:"meta,omitempty"`
// Relationships JSON API document relationships raw data.
Relationships map[string]*relationship `json:"relationships,omitempty"`
}
ResourceObject extends ResourceObjectIdentifier with JSON API document Attributes, Meta and Relationships.
type ResourceObjectIdentifier ¶
ResourceObjectIdentifier JSON API resource object.
func (ResourceObjectIdentifier) GetID ¶
func (roi ResourceObjectIdentifier) GetID() string
GetID method returns ResourceObjectIdentifier ID.
func (ResourceObjectIdentifier) GetType ¶
func (roi ResourceObjectIdentifier) GetType() string
GetType method returns ResourceObjectIdentifier Type.
type UnmarshalData ¶
UnmarshalData interface should be implemented to be able unmarshal data from JSON API document into Go struct.
SetData example:
func(s *SomeStruct) SetData(to func(target interface{}) error) error {
return to(s)
}
NOTE: If you are using SomeStruct collections, you should implement additional data type, e.g.: type SomeStructs []SomeStruct
Then you should implement SetData method for SomeStructs:
func(s *SomeStructs) SetData(to func(target interface{}) error) error {
return to(s)
}
type UnmarshalErrors ¶
type UnmarshalErrors interface {
SetErrors(errors []*ErrorObject) error
}
UnmarshalErrors interface should be implemented to be able unmarshal errors from JSON API document.
SetErrors example:
type SomeError struct {
Code string
Title string
Pointer string
}
type SomeErrors struct {
Errors []SomeError
}
func(v SomeErrors) SetErrors(errs []*jsonapi.ErrorObject) error {
var someErrors []SomeError
for _, err := range errs {
someErrors = append(someErrors, SomeError{
Title: err.Title,
Code: err.Code,
Pointer: err.Source.Pointer,
})
}
v.Errors = someErrors
return nil
}
type UnmarshalRelationships ¶
UnmarshalRelationships interface should be implemented to be able unmarshal JSON API document relationships into Go struct.
SetRelationships example:
func (s *SomeStruct) SetRelationships(relationships map[string]interface{}) error {
if relationship, ok := relationships["relation"]; ok {
s.RealtionID = relationship.(*jsonapi.ResourceObjectIdentifier).ID
}
return nil
}
type UnmarshalResourceIdentifier ¶
UnmarshalResourceIdentifier interface should be implemented to be able unmarshal JSON API document into Go struct.
SetID, SetType examples:
func(s *SomeStruct) SetID(id string) error {
s.ID = id
return nil
}
func(s *SomeStruct) SetType(t string) error {
s.Type = t
return nil
}
or
func(s *SomeStruct) SetType(string) error {
return nil
}