Skip to content

Commit 5207f05

Browse files
committed
Merge pull request #247 from 256dpi/object-initializer
Added InitializeObject hook
2 parents d6781fc + 619ee96 commit 5207f05

File tree

3 files changed

+113
-0
lines changed

3 files changed

+113
-0
lines changed

api.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,12 @@ func (res *resource) handleCreate(c APIContexter, w http.ResponseWriter, r *http
562562
}
563563
newObj := reflect.New(resourceType).Interface()
564564

565+
// Call InitializeObject if available to allow implementers change the object
566+
// before calling Unmarshal.
567+
if initSource, ok := res.source.(ObjectInitializer); ok {
568+
initSource.InitializeObject(newObj)
569+
}
570+
565571
err = jsonapi.Unmarshal(ctx, newObj)
566572
if err != nil {
567573
return NewHTTPError(nil, err.Error(), http.StatusNotAcceptable)

api_interfaces.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,14 @@ type FindAll interface {
4848
FindAll(req Request) (Responder, error)
4949
}
5050

51+
// The ObjectInitializer interface can be implemented to have the ability to change
52+
// a created object before Unmarshal is called. This is currently only called on
53+
// Create as the other actions go through FindOne or FindAll which are already
54+
// controlled by the implementer.
55+
type ObjectInitializer interface {
56+
InitializeObject(interface{})
57+
}
58+
5159
//URLResolver allows you to implement a static
5260
//way to return a baseURL for all incoming
5361
//requests for one api2go instance.

api_object_initializer_test.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package api2go
2+
3+
import (
4+
"net/http"
5+
"net/http/httptest"
6+
"strings"
7+
8+
. "github.com/onsi/ginkgo"
9+
. "github.com/onsi/gomega"
10+
)
11+
12+
type ObjectInitializerResource struct{}
13+
14+
func (s ObjectInitializerResource) InitializeObject(obj interface{}) {
15+
if post, ok := obj.(*Post); ok {
16+
post.Title = "New Title"
17+
}
18+
}
19+
20+
func (s ObjectInitializerResource) FindOne(ID string, req Request) (Responder, error) {
21+
return nil, nil
22+
}
23+
24+
func (s ObjectInitializerResource) Create(obj interface{}, req Request) (Responder, error) {
25+
return &Response{Res: obj, Code: http.StatusCreated}, nil
26+
}
27+
28+
func (s ObjectInitializerResource) Delete(ID string, req Request) (Responder, error) {
29+
return nil, nil
30+
}
31+
32+
func (s ObjectInitializerResource) Update(obj interface{}, req Request) (Responder, error) {
33+
return nil, nil
34+
}
35+
36+
var _ = Describe("Test resource implementing the ObjectInitializer interface", func() {
37+
var (
38+
api *API
39+
rec *httptest.ResponseRecorder
40+
body *strings.Reader
41+
)
42+
BeforeEach(func() {
43+
api = NewAPI("v1")
44+
api.AddResource(Post{}, ObjectInitializerResource{})
45+
rec = httptest.NewRecorder()
46+
body = strings.NewReader(`
47+
{
48+
"data": {
49+
"attributes": {},
50+
"id": "blubb",
51+
"type": "posts"
52+
}
53+
}
54+
`)
55+
})
56+
57+
It("Create", func() {
58+
req, err := http.NewRequest("POST", "/v1/posts", body)
59+
Expect(err).ToNot(HaveOccurred())
60+
api.Handler().ServeHTTP(rec, req)
61+
62+
Expect(rec.Body.String()).To(MatchJSON(`
63+
{
64+
"data": {
65+
"type": "posts",
66+
"id": "blubb",
67+
"attributes": {
68+
"title": "New Title",
69+
"value": null
70+
},
71+
"relationships": {
72+
"author": {
73+
"links": {
74+
"self": "/v1/posts/blubb/relationships/author",
75+
"related": "/v1/posts/blubb/author"
76+
},
77+
"data": null
78+
},
79+
"bananas": {
80+
"links": {
81+
"self": "/v1/posts/blubb/relationships/bananas",
82+
"related": "/v1/posts/blubb/bananas"
83+
},
84+
"data": []
85+
},
86+
"comments": {
87+
"links": {
88+
"self": "/v1/posts/blubb/relationships/comments",
89+
"related": "/v1/posts/blubb/comments"
90+
},
91+
"data": []
92+
}
93+
}
94+
}
95+
}
96+
`))
97+
Expect(rec.Code).To(Equal(http.StatusCreated))
98+
})
99+
})

0 commit comments

Comments
 (0)