Skip to content

Commit

Permalink
added ObjectInitializer interface
Browse files Browse the repository at this point in the history
  • Loading branch information
256dpi committed May 15, 2016
1 parent 0f0aba6 commit af9c788
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 0 deletions.
6 changes: 6 additions & 0 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,12 @@ func (res *resource) handleCreate(c APIContexter, w http.ResponseWriter, r *http
}
newObj := reflect.New(resourceType).Interface()

// Call InitializeObject if available to allow implementers change the object
// before calling Unmarshal.
if initSource, ok := res.source.(ObjectInitializer); ok {
initSource.InitializeObject(newObj)
}

err = jsonapi.Unmarshal(ctx, newObj)
if err != nil {
return NewHTTPError(nil, err.Error(), http.StatusNotAcceptable)
Expand Down
8 changes: 8 additions & 0 deletions api_interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ type FindAll interface {
FindAll(req Request) (Responder, error)
}

// The ObjectInitializer interface can be implemented to have the ability to change
// a created object before Unmarshal is called. This is currently only called on
// Create as the other actions go through FindOne or FindAll which are already
// controlled by the implementer.
type ObjectInitializer interface {
InitializeObject(interface{})
}

//URLResolver allows you to implement a static
//way to return a baseURL for all incoming
//requests for one api2go instance.
Expand Down
99 changes: 99 additions & 0 deletions api_object_initializer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package api2go

import (
"net/http"
"net/http/httptest"
"strings"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

type ObjectInitializerResource struct{}

func (s ObjectInitializerResource) InitializeObject(obj interface{}) {
if post, ok := obj.(*Post); ok {
post.Title = "New Title"
}
}

func (s ObjectInitializerResource) FindOne(ID string, req Request) (Responder, error) {
return nil, nil
}

func (s ObjectInitializerResource) Create(obj interface{}, req Request) (Responder, error) {
return &Response{Res: obj, Code: http.StatusCreated}, nil
}

func (s ObjectInitializerResource) Delete(ID string, req Request) (Responder, error) {
return nil, nil
}

func (s ObjectInitializerResource) Update(obj interface{}, req Request) (Responder, error) {
return nil, nil
}

var _ = Describe("Test resource implementing the ObjectInitializer interface", func() {
var (
api *API
rec *httptest.ResponseRecorder
body *strings.Reader
)
BeforeEach(func() {
api = NewAPI("v1")
api.AddResource(Post{}, ObjectInitializerResource{})
rec = httptest.NewRecorder()
body = strings.NewReader(`
{
"data": {
"attributes": {},
"id": "blubb",
"type": "posts"
}
}
`)
})

It("Create", func() {
req, err := http.NewRequest("POST", "/v1/posts", body)
Expect(err).ToNot(HaveOccurred())
api.Handler().ServeHTTP(rec, req)

Expect(rec.Body.String()).To(MatchJSON(`
{
"data": {
"type": "posts",
"id": "blubb",
"attributes": {
"title": "New Title",
"value": null
},
"relationships": {
"author": {
"links": {
"self": "/v1/posts/blubb/relationships/author",
"related": "/v1/posts/blubb/author"
},
"data": null
},
"bananas": {
"links": {
"self": "/v1/posts/blubb/relationships/bananas",
"related": "/v1/posts/blubb/bananas"
},
"data": []
},
"comments": {
"links": {
"self": "/v1/posts/blubb/relationships/comments",
"related": "/v1/posts/blubb/comments"
},
"data": []
}
}
}
}
`))
Expect(rec.Code).To(Equal(http.StatusCreated))
})
})

0 comments on commit af9c788

Please sign in to comment.