1package jsonapi 2 3import ( 4 "fmt" 5 "time" 6) 7 8type BadModel struct { 9 ID int `jsonapi:"primary"` 10} 11 12type ModelBadTypes struct { 13 ID string `jsonapi:"primary,badtypes"` 14 StringField string `jsonapi:"attr,string_field"` 15 FloatField float64 `jsonapi:"attr,float_field"` 16 TimeField time.Time `jsonapi:"attr,time_field"` 17 TimePtrField *time.Time `jsonapi:"attr,time_ptr_field"` 18} 19 20type WithPointer struct { 21 ID *uint64 `jsonapi:"primary,with-pointers"` 22 Name *string `jsonapi:"attr,name"` 23 IsActive *bool `jsonapi:"attr,is-active"` 24 IntVal *int `jsonapi:"attr,int-val"` 25 FloatVal *float32 `jsonapi:"attr,float-val"` 26} 27 28type TimestampModel struct { 29 ID int `jsonapi:"primary,timestamps"` 30 DefaultV time.Time `jsonapi:"attr,defaultv"` 31 DefaultP *time.Time `jsonapi:"attr,defaultp"` 32 ISO8601V time.Time `jsonapi:"attr,iso8601v,iso8601"` 33 ISO8601P *time.Time `jsonapi:"attr,iso8601p,iso8601"` 34 RFC3339V time.Time `jsonapi:"attr,rfc3339v,rfc3339"` 35 RFC3339P *time.Time `jsonapi:"attr,rfc3339p,rfc3339"` 36} 37 38type Car struct { 39 ID *string `jsonapi:"primary,cars"` 40 Make *string `jsonapi:"attr,make,omitempty"` 41 Model *string `jsonapi:"attr,model,omitempty"` 42 Year *uint `jsonapi:"attr,year,omitempty"` 43} 44 45type Post struct { 46 Blog 47 ID uint64 `jsonapi:"primary,posts"` 48 BlogID int `jsonapi:"attr,blog_id"` 49 ClientID string `jsonapi:"client-id"` 50 Title string `jsonapi:"attr,title"` 51 Body string `jsonapi:"attr,body"` 52 Comments []*Comment `jsonapi:"relation,comments"` 53 LatestComment *Comment `jsonapi:"relation,latest_comment"` 54 55 Links Links `jsonapi:"links,omitempty"` 56} 57 58type Comment struct { 59 ID int `jsonapi:"primary,comments"` 60 ClientID string `jsonapi:"client-id"` 61 PostID int `jsonapi:"attr,post_id"` 62 Body string `jsonapi:"attr,body"` 63 64 Links Links `jsonapi:"links,omitempty"` 65} 66 67type Book struct { 68 ID uint64 `jsonapi:"primary,books"` 69 Author string `jsonapi:"attr,author"` 70 ISBN string `jsonapi:"attr,isbn"` 71 Title string `jsonapi:"attr,title,omitempty"` 72 Description *string `jsonapi:"attr,description"` 73 Pages *uint `jsonapi:"attr,pages,omitempty"` 74 PublishedAt time.Time 75 Tags []string `jsonapi:"attr,tags"` 76} 77 78type Blog struct { 79 ID int `jsonapi:"primary,blogs"` 80 ClientID string `jsonapi:"client-id"` 81 Title string `jsonapi:"attr,title"` 82 Posts []*Post `jsonapi:"relation,posts"` 83 CurrentPost *Post `jsonapi:"relation,current_post"` 84 CurrentPostID int `jsonapi:"attr,current_post_id"` 85 CreatedAt time.Time `jsonapi:"attr,created_at"` 86 ViewCount int `jsonapi:"attr,view_count"` 87 88 Links Links `jsonapi:"links,omitempty"` 89} 90 91func (b *Blog) JSONAPILinks() *Links { 92 return &Links{ 93 "self": fmt.Sprintf("https://example.com/api/blogs/%d", b.ID), 94 "comments": Link{ 95 Href: fmt.Sprintf("https://example.com/api/blogs/%d/comments", b.ID), 96 Meta: Meta{ 97 "counts": map[string]uint{ 98 "likes": 4, 99 "comments": 20, 100 }, 101 }, 102 }, 103 } 104} 105 106func (b *Blog) JSONAPIRelationshipLinks(relation string) *Links { 107 if relation == "posts" { 108 return &Links{ 109 "related": Link{ 110 Href: fmt.Sprintf("https://example.com/api/blogs/%d/posts", b.ID), 111 Meta: Meta{ 112 "count": len(b.Posts), 113 }, 114 }, 115 } 116 } 117 if relation == "current_post" { 118 return &Links{ 119 "self": fmt.Sprintf("https://example.com/api/posts/%s", "3"), 120 "related": Link{ 121 Href: fmt.Sprintf("https://example.com/api/blogs/%d/current_post", b.ID), 122 }, 123 } 124 } 125 return nil 126} 127 128func (b *Blog) JSONAPIMeta() *Meta { 129 return &Meta{ 130 "detail": "extra details regarding the blog", 131 } 132} 133 134func (b *Blog) JSONAPIRelationshipMeta(relation string) *Meta { 135 if relation == "posts" { 136 return &Meta{ 137 "this": map[string]interface{}{ 138 "can": map[string]interface{}{ 139 "go": []interface{}{ 140 "as", 141 "deep", 142 map[string]interface{}{ 143 "as": "required", 144 }, 145 }, 146 }, 147 }, 148 } 149 } 150 if relation == "current_post" { 151 return &Meta{ 152 "detail": "extra current_post detail", 153 } 154 } 155 return nil 156} 157 158type BadComment struct { 159 ID uint64 `jsonapi:"primary,bad-comment"` 160 Body string `jsonapi:"attr,body"` 161} 162 163func (bc *BadComment) JSONAPILinks() *Links { 164 return &Links{ 165 "self": []string{"invalid", "should error"}, 166 } 167} 168 169type Company struct { 170 ID string `jsonapi:"primary,companies"` 171 Name string `jsonapi:"attr,name"` 172 Boss Employee `jsonapi:"attr,boss"` 173 Teams []Team `jsonapi:"attr,teams"` 174 People []*People `jsonapi:"attr,people"` 175 FoundedAt time.Time `jsonapi:"attr,founded-at,iso8601"` 176} 177 178type People struct { 179 Name string `jsonapi:"attr,name"` 180 Age int `jsonapi:"attr,age"` 181} 182 183type Team struct { 184 Name string `jsonapi:"attr,name"` 185 Leader *Employee `jsonapi:"attr,leader"` 186 Members []Employee `jsonapi:"attr,members"` 187} 188 189type Employee struct { 190 Firstname string `jsonapi:"attr,firstname"` 191 Surname string `jsonapi:"attr,surname"` 192 Age int `jsonapi:"attr,age"` 193 HiredAt *time.Time `jsonapi:"attr,hired-at,iso8601"` 194} 195 196type CustomIntType int 197type CustomFloatType float64 198type CustomStringType string 199 200type CustomAttributeTypes struct { 201 ID string `jsonapi:"primary,customtypes"` 202 203 Int CustomIntType `jsonapi:"attr,int"` 204 IntPtr *CustomIntType `jsonapi:"attr,intptr"` 205 IntPtrNull *CustomIntType `jsonapi:"attr,intptrnull"` 206 207 Float CustomFloatType `jsonapi:"attr,float"` 208 String CustomStringType `jsonapi:"attr,string"` 209} 210