diff --git a/jsonapi.go b/jsonapi.go index 243cf6c..ae76f08 100644 --- a/jsonapi.go +++ b/jsonapi.go @@ -20,7 +20,7 @@ type JsonApiNode struct { type JsonApiResponse struct { Data *JsonApiNode `json:"data"` - Included []*JsonApiNode `json:"included"` + Included []*JsonApiNode `json:"included,omitempty"` } func CreateJsonApiResponse(model interface{}) (*JsonApiResponse, error) { @@ -30,8 +30,19 @@ func CreateJsonApiResponse(model interface{}) (*JsonApiResponse, error) { } resp := &JsonApiResponse{Data: rootNode} + + uniqueIncluded := make(map[string]*JsonApiNode) + + for i, n := range included { + k := fmt.Sprintf("%s,%s", n.Type, n.Id) + if uniqueIncluded[k] == nil { + uniqueIncluded[k] = n + } else { + included = append(included[:i], included[i+1:]...) + } + } + resp.Included = included - // TODO make Included unique return resp, nil } @@ -96,6 +107,17 @@ func visitModelNode(model interface{}) (*JsonApiNode, []*JsonApiNode, error) { err = err } } else { + relationship, _, err := visitModelNode(fieldValue.Interface()) + if err == nil { + shallowNode := *relationship + shallowNode.Attributes = nil + + included = append(included, relationship) + + node.Relationships[args[1]] = &shallowNode + } else { + err = err + } } } else { diff --git a/jsonapi_test.go b/jsonapi_test.go index 8428e8c..2469ba6 100644 --- a/jsonapi_test.go +++ b/jsonapi_test.go @@ -14,9 +14,10 @@ type Post struct { } type Blog struct { - Id int `jsonapi:"primary,blogs"` - Title string `jsonapi:"attr,title"` - Posts []Post `jsonapi:"relation,posts"` + Id int `jsonapi:"primary,blogs"` + Title string `jsonapi:"attr,title"` + Posts []Post `jsonapi:"relation,posts"` + CurrentPost Post `jsonapi:"relation,current_post"` } func TestHasPrimaryAnnotation(t *testing.T) { @@ -35,6 +36,11 @@ func TestHasPrimaryAnnotation(t *testing.T) { Body: "Bas", }, }, + CurrentPost: Post{ + Id: 1, + Title: "Foo", + Body: "Bar", + }, } resp, err := CreateJsonApiResponse(testModel)