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)) }
Output:
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) } }
Output:
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 }