Skip to content

Commit 4814f9b

Browse files
committed
detect array unmarshal into struct
also fixed example descriptions and added a new test for example
1 parent b06e1c9 commit 4814f9b

File tree

5 files changed

+53
-4
lines changed

5 files changed

+53
-4
lines changed

examples/crud_example.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ To play with this example server you can run some of the following curl requests
55
In order to demonstrate dynamic baseurl handling for requests, apply the --header="REQUEST_URI:https://www.your.domain.example.com" parameter to any of the commands.
66
77
Create a new user:
8-
curl -X POST http://localhost:31415/v0/users -d '{"data" : [{"type" : "users" , "attributes": {"user-name" : "marvin"}}]}'
8+
curl -X POST http://localhost:31415/v0/users -d '{"data" : {"type" : "users" , "attributes": {"user-name" : "marvin"}}}'
99
1010
List users:
1111
curl -X GET http://localhost:31415/v0/users
@@ -22,10 +22,10 @@ Delete:
2222
curl -vX DELETE http://localhost:31415/v0/users/2
2323
2424
Create a chocolate with the name sweet
25-
curl -X POST http://localhost:31415/v0/chocolates -d '{"data" : [{"type" : "chocolates" , "attributes": {"name" : "Ritter Sport", "taste": "Very Good"}}]}'
25+
curl -X POST http://localhost:31415/v0/chocolates -d '{"data" : {"type" : "chocolates" , "attributes": {"name" : "Ritter Sport", "taste": "Very Good"}}}'
2626
2727
Create a user with a sweet
28-
curl -X POST http://localhost:31415/v0/users -d '{"data" : [{"type" : "users" , "attributes": {"user-name" : "marvin"}, "relationships": {"sweets": {"data": [{"type": "chocolates", "id": "1"}]}}}]}'
28+
curl -X POST http://localhost:31415/v0/users -d '{"data" : {"type" : "users" , "attributes": {"user-name" : "marvin"}, "relationships": {"sweets": {"data": [{"type": "chocolates", "id": "1"}]}}}}'
2929
3030
List a users sweets
3131
curl -X GET http://localhost:31415/v0/users/1/sweets

examples/crud_example_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,32 @@ var _ = Describe("CrudExample", func() {
426426
`))
427427
})
428428

429+
It("Directly loading the sweets", func() {
430+
req, err := http.NewRequest("GET", "/v0/users/1/sweets", nil)
431+
Expect(err).ToNot(HaveOccurred())
432+
api.Handler().ServeHTTP(rec, req)
433+
Expect(rec.Code).To(Equal(http.StatusOK))
434+
Expect(rec.Body.String()).To(MatchJSON(`
435+
{
436+
"meta": {
437+
"author": "The api2go examples crew",
438+
"license": "wtfpl",
439+
"license-url": "http://www.wtfpl.net"
440+
},
441+
"data": [
442+
{
443+
"type": "chocolates",
444+
"id": "1",
445+
"attributes": {
446+
"name": "Ritter Sport",
447+
"taste": "Very Good"
448+
}
449+
}
450+
]
451+
}
452+
`))
453+
})
454+
429455
It("The relationship route works too", func() {
430456
req, err := http.NewRequest("GET", "/v0/users/1/relationships/sweets", nil)
431457
Expect(err).ToNot(HaveOccurred())

examples/model/model_user.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ func (u User) GetReferencedStructs() []jsonapi.MarshalIdentifier {
6666
func (u *User) SetToManyReferenceIDs(name string, IDs []string) error {
6767
if name == "sweets" {
6868
u.ChocolatesIDs = IDs
69+
return nil
6970
}
7071

7172
return errors.New("There is no to-many relationship with the name " + name)
@@ -75,6 +76,7 @@ func (u *User) SetToManyReferenceIDs(name string, IDs []string) error {
7576
func (u *User) AddToManyIDs(name string, IDs []string) error {
7677
if name == "sweets" {
7778
u.ChocolatesIDs = append(u.ChocolatesIDs, IDs...)
79+
return nil
7880
}
7981

8082
return errors.New("There is no to-many relationship with the name " + name)

jsonapi/unmarshal.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,11 @@ func Unmarshal(data []byte, target interface{}) error {
103103
}
104104

105105
if ctx.Data.DataArray != nil {
106-
targetType := reflect.TypeOf(target).Elem().Elem()
106+
targetSlice := reflect.TypeOf(target).Elem()
107+
if targetSlice.Kind() != reflect.Slice {
108+
return fmt.Errorf("Cannot unmarshal array to struct target %s", targetSlice)
109+
}
110+
targetType := targetSlice.Elem()
107111
targetPointer := reflect.ValueOf(target)
108112
targetValue := targetPointer.Elem()
109113

jsonapi/unmarshal_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,23 @@ var _ = Describe("Unmarshal", func() {
203203
Expect(err.Error()).To(Equal("target must be a ptr"))
204204
})
205205

206+
It("errors if json array cannot be unmarshaled into a struct", func() {
207+
json := []byte(`
208+
{
209+
"data": [{
210+
"type": "simplePosts",
211+
"attributes": {
212+
"title": "something"
213+
}
214+
}]
215+
}
216+
`)
217+
var post SimplePost
218+
err := Unmarshal(json, &post)
219+
Expect(err).To(HaveOccurred())
220+
Expect(err.Error()).To(Equal("Cannot unmarshal array to struct target jsonapi.SimplePost"))
221+
})
222+
206223
Context("slice fields", func() {
207224
It("unmarshal slice fields with single entry correctly", func() {
208225
sliceJSON := []byte(`

0 commit comments

Comments
 (0)