Skip to content

Commit a4b1c6a

Browse files
committed
remove ContentMarshaler
1 parent 15d4b3e commit a4b1c6a

File tree

7 files changed

+86
-323
lines changed

7 files changed

+86
-323
lines changed

api.go

Lines changed: 51 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"strconv"
1414
"strings"
1515

16-
"github.com/golang/gddo/httputil"
1716
"github.com/manyminds/api2go/jsonapi"
1817
"github.com/manyminds/api2go/routing"
1918
)
@@ -182,20 +181,20 @@ func (p paginationQueryParams) getLinks(r *http.Request, count uint, info inform
182181
}
183182

184183
type notAllowedHandler struct {
185-
marshalers map[string]ContentMarshaler
184+
API *API
186185
}
187186

188187
func (n notAllowedHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
189188
err := NewHTTPError(nil, "Method Not Allowed", http.StatusMethodNotAllowed)
190189
w.WriteHeader(http.StatusMethodNotAllowed)
191-
handleError(err, w, r, n.marshalers)
190+
n.API.handleError(err, w, r)
192191
}
193192

194193
type resource struct {
195194
resourceType reflect.Type
196195
source CRUD
197196
name string
198-
marshalers map[string]ContentMarshaler
197+
api *API
199198
}
200199

201200
// middlewareChain executes the middleeware chain setup
@@ -210,7 +209,7 @@ func (api *API) allocateDefaultContext() APIContexter {
210209
return &APIContext{}
211210
}
212211

213-
func (api *API) addResource(prototype jsonapi.MarshalIdentifier, source CRUD, marshalers map[string]ContentMarshaler) *resource {
212+
func (api *API) addResource(prototype jsonapi.MarshalIdentifier, source CRUD) *resource {
214213
resourceType := reflect.TypeOf(prototype)
215214
if resourceType.Kind() != reflect.Struct && resourceType.Kind() != reflect.Ptr {
216215
panic("pass an empty resource struct or a struct pointer to AddResource!")
@@ -239,7 +238,7 @@ func (api *API) addResource(prototype jsonapi.MarshalIdentifier, source CRUD, ma
239238
resourceType: resourceType,
240239
name: name,
241240
source: source,
242-
marshalers: marshalers,
241+
api: api,
243242
}
244243

245244
requestInfo := func(r *http.Request, api *API) *information {
@@ -287,7 +286,7 @@ func (api *API) addResource(prototype jsonapi.MarshalIdentifier, source CRUD, ma
287286
err := res.handleIndex(c, w, r, *info)
288287
api.contextPool.Put(c)
289288
if err != nil {
290-
handleError(err, w, r, marshalers)
289+
api.handleError(err, w, r)
291290
}
292291
})
293292

@@ -299,7 +298,7 @@ func (api *API) addResource(prototype jsonapi.MarshalIdentifier, source CRUD, ma
299298
err := res.handleRead(c, w, r, params, *info)
300299
api.contextPool.Put(c)
301300
if err != nil {
302-
handleError(err, w, r, marshalers)
301+
api.handleError(err, w, r)
303302
}
304303
})
305304

@@ -317,7 +316,7 @@ func (api *API) addResource(prototype jsonapi.MarshalIdentifier, source CRUD, ma
317316
err := res.handleReadRelation(c, w, r, params, *info, relation)
318317
api.contextPool.Put(c)
319318
if err != nil {
320-
handleError(err, w, r, marshalers)
319+
api.handleError(err, w, r)
321320
}
322321
}
323322
}(relation))
@@ -331,7 +330,7 @@ func (api *API) addResource(prototype jsonapi.MarshalIdentifier, source CRUD, ma
331330
err := res.handleLinked(c, api, w, r, params, relation, *info)
332331
api.contextPool.Put(c)
333332
if err != nil {
334-
handleError(err, w, r, marshalers)
333+
api.handleError(err, w, r)
335334
}
336335
}
337336
}(relation))
@@ -344,7 +343,7 @@ func (api *API) addResource(prototype jsonapi.MarshalIdentifier, source CRUD, ma
344343
err := res.handleReplaceRelation(c, w, r, params, relation)
345344
api.contextPool.Put(c)
346345
if err != nil {
347-
handleError(err, w, r, marshalers)
346+
api.handleError(err, w, r)
348347
}
349348
}
350349
}(relation))
@@ -359,7 +358,7 @@ func (api *API) addResource(prototype jsonapi.MarshalIdentifier, source CRUD, ma
359358
err := res.handleAddToManyRelation(c, w, r, params, relation)
360359
api.contextPool.Put(c)
361360
if err != nil {
362-
handleError(err, w, r, marshalers)
361+
api.handleError(err, w, r)
363362
}
364363
}
365364
}(relation))
@@ -372,7 +371,7 @@ func (api *API) addResource(prototype jsonapi.MarshalIdentifier, source CRUD, ma
372371
err := res.handleDeleteToManyRelation(c, w, r, params, relation)
373372
api.contextPool.Put(c)
374373
if err != nil {
375-
handleError(err, w, r, marshalers)
374+
api.handleError(err, w, r)
376375
}
377376
}
378377
}(relation))
@@ -388,7 +387,7 @@ func (api *API) addResource(prototype jsonapi.MarshalIdentifier, source CRUD, ma
388387
err := res.handleCreate(c, w, r, info.prefix, *info)
389388
api.contextPool.Put(c)
390389
if err != nil {
391-
handleError(err, w, r, marshalers)
390+
api.handleError(err, w, r)
392391
}
393392
})
394393

@@ -399,7 +398,7 @@ func (api *API) addResource(prototype jsonapi.MarshalIdentifier, source CRUD, ma
399398
err := res.handleDelete(c, w, r, params)
400399
api.contextPool.Put(c)
401400
if err != nil {
402-
handleError(err, w, r, marshalers)
401+
api.handleError(err, w, r)
403402
}
404403
})
405404

@@ -410,7 +409,7 @@ func (api *API) addResource(prototype jsonapi.MarshalIdentifier, source CRUD, ma
410409
err := res.handleUpdate(c, w, r, params)
411410
api.contextPool.Put(c)
412411
if err != nil {
413-
handleError(err, w, r, marshalers)
412+
api.handleError(err, w, r)
414413
}
415414
})
416415

@@ -431,6 +430,19 @@ func buildRequest(c APIContexter, r *http.Request) Request {
431430
return req
432431
}
433432

433+
func (res *resource) marshalResponse(resp interface{}, w http.ResponseWriter, status int, r *http.Request) error {
434+
filtered, err := filterSparseFields(resp, r)
435+
if err != nil {
436+
return err
437+
}
438+
result, err := json.Marshal(filtered)
439+
if err != nil {
440+
return err
441+
}
442+
writeResult(w, result, status, res.api.ContentType)
443+
return nil
444+
}
445+
434446
func (res *resource) handleIndex(c APIContexter, w http.ResponseWriter, r *http.Request, info information) error {
435447
pagination := newPaginationQueryParams(r)
436448
if pagination.isValid() {
@@ -449,7 +461,7 @@ func (res *resource) handleIndex(c APIContexter, w http.ResponseWriter, r *http.
449461
return err
450462
}
451463

452-
return respondWithPagination(response, info, http.StatusOK, paginationLinks, w, r, res.marshalers)
464+
return res.respondWithPagination(response, info, http.StatusOK, paginationLinks, w, r)
453465
}
454466
source, ok := res.source.(FindAll)
455467
if !ok {
@@ -461,7 +473,7 @@ func (res *resource) handleIndex(c APIContexter, w http.ResponseWriter, r *http.
461473
return err
462474
}
463475

464-
return respondWith(response, info, http.StatusOK, w, r, res.marshalers)
476+
return res.respondWith(response, info, http.StatusOK, w, r)
465477
}
466478

467479
func (res *resource) handleRead(c APIContexter, w http.ResponseWriter, r *http.Request, params map[string]string, info information) error {
@@ -473,7 +485,7 @@ func (res *resource) handleRead(c APIContexter, w http.ResponseWriter, r *http.R
473485
return err
474486
}
475487

476-
return respondWith(response, info, http.StatusOK, w, r, res.marshalers)
488+
return res.respondWith(response, info, http.StatusOK, w, r)
477489
}
478490

479491
func (res *resource) handleReadRelation(c APIContexter, w http.ResponseWriter, r *http.Request, params map[string]string, info information, relation jsonapi.Reference) error {
@@ -499,7 +511,7 @@ func (res *resource) handleReadRelation(c APIContexter, w http.ResponseWriter, r
499511
rel.Meta = meta
500512
}
501513

502-
return marshalResponse(rel, w, http.StatusOK, r, res.marshalers)
514+
return res.marshalResponse(rel, w, http.StatusOK, r)
503515
}
504516

505517
// try to find the referenced resource and call the findAll Method with referencing resource id as param
@@ -530,7 +542,7 @@ func (res *resource) handleLinked(c APIContexter, api *API, w http.ResponseWrite
530542
return err
531543
}
532544

533-
return respondWithPagination(response, info, http.StatusOK, paginationLinks, w, r, res.marshalers)
545+
return res.respondWithPagination(response, info, http.StatusOK, paginationLinks, w, r)
534546
}
535547

536548
source, ok := resource.source.(FindAll)
@@ -542,7 +554,7 @@ func (res *resource) handleLinked(c APIContexter, api *API, w http.ResponseWrite
542554
if err != nil {
543555
return err
544556
}
545-
return respondWith(obj, info, http.StatusOK, w, r, res.marshalers)
557+
return res.respondWith(obj, info, http.StatusOK, w, r)
546558
}
547559
}
548560

@@ -554,7 +566,7 @@ func (res *resource) handleLinked(c APIContexter, api *API, w http.ResponseWrite
554566
}
555567

556568
func (res *resource) handleCreate(c APIContexter, w http.ResponseWriter, r *http.Request, prefix string, info information) error {
557-
ctx, err := unmarshalRequest(r, res.marshalers)
569+
ctx, err := unmarshalRequest(r)
558570
if err != nil {
559571
return err
560572
}
@@ -595,7 +607,7 @@ func (res *resource) handleCreate(c APIContexter, w http.ResponseWriter, r *http
595607
// handle 200 status codes
596608
switch response.StatusCode() {
597609
case http.StatusCreated:
598-
return respondWith(response, info, http.StatusCreated, w, r, res.marshalers)
610+
return res.respondWith(response, info, http.StatusCreated, w, r)
599611
case http.StatusNoContent:
600612
w.WriteHeader(response.StatusCode())
601613
return nil
@@ -614,7 +626,7 @@ func (res *resource) handleUpdate(c APIContexter, w http.ResponseWriter, r *http
614626
return err
615627
}
616628

617-
ctx, err := unmarshalRequest(r, res.marshalers)
629+
ctx, err := unmarshalRequest(r)
618630
if err != nil {
619631
return err
620632
}
@@ -655,7 +667,7 @@ func (res *resource) handleUpdate(c APIContexter, w http.ResponseWriter, r *http
655667
response = internalResponse
656668
}
657669

658-
return respondWith(response, information{}, http.StatusOK, w, r, res.marshalers)
670+
return res.respondWith(response, information{}, http.StatusOK, w, r)
659671
case http.StatusAccepted:
660672
w.WriteHeader(http.StatusAccepted)
661673
return nil
@@ -680,7 +692,7 @@ func (res *resource) handleReplaceRelation(c APIContexter, w http.ResponseWriter
680692
return err
681693
}
682694

683-
body, err := unmarshalRequest(r, res.marshalers)
695+
body, err := unmarshalRequest(r)
684696
if err != nil {
685697
return err
686698
}
@@ -730,7 +742,7 @@ func (res *resource) handleAddToManyRelation(c APIContexter, w http.ResponseWrit
730742
return err
731743
}
732744

733-
body, err := unmarshalRequest(r, res.marshalers)
745+
body, err := unmarshalRequest(r)
734746
if err != nil {
735747
return err
736748
}
@@ -802,7 +814,7 @@ func (res *resource) handleDeleteToManyRelation(c APIContexter, w http.ResponseW
802814
return err
803815
}
804816

805-
body, err := unmarshalRequest(r, res.marshalers)
817+
body, err := unmarshalRequest(r)
806818
if err != nil {
807819
return err
808820
}
@@ -883,7 +895,7 @@ func (res *resource) handleDelete(c APIContexter, w http.ResponseWriter, r *http
883895
"meta": response.Metadata(),
884896
}
885897

886-
return marshalResponse(data, w, http.StatusOK, r, res.marshalers)
898+
return res.marshalResponse(data, w, http.StatusOK, r)
887899
case http.StatusAccepted:
888900
w.WriteHeader(http.StatusAccepted)
889901
return nil
@@ -901,7 +913,7 @@ func writeResult(w http.ResponseWriter, data []byte, status int, contentType str
901913
w.Write(data)
902914
}
903915

904-
func respondWith(obj Responder, info information, status int, w http.ResponseWriter, r *http.Request, marshalers map[string]ContentMarshaler) error {
916+
func (res *resource) respondWith(obj Responder, info information, status int, w http.ResponseWriter, r *http.Request) error {
905917
data, err := jsonapi.MarshalToStruct(obj.Result(), info)
906918
if err != nil {
907919
return err
@@ -912,10 +924,10 @@ func respondWith(obj Responder, info information, status int, w http.ResponseWri
912924
data.Meta = meta
913925
}
914926

915-
return marshalResponse(data, w, status, r, marshalers)
927+
return res.marshalResponse(data, w, status, r)
916928
}
917929

918-
func respondWithPagination(obj Responder, info information, status int, links jsonapi.Links, w http.ResponseWriter, r *http.Request, marshalers map[string]ContentMarshaler) error {
930+
func (res *resource) respondWithPagination(obj Responder, info information, status int, links jsonapi.Links, w http.ResponseWriter, r *http.Request) error {
919931
data, err := jsonapi.MarshalToStruct(obj.Result(), info)
920932
if err != nil {
921933
return err
@@ -927,39 +939,18 @@ func respondWithPagination(obj Responder, info information, status int, links js
927939
data.Meta = meta
928940
}
929941

930-
return marshalResponse(data, w, status, r, marshalers)
942+
return res.marshalResponse(data, w, status, r)
931943
}
932944

933-
func unmarshalRequest(r *http.Request, marshalers map[string]ContentMarshaler) ([]byte, error) {
945+
func unmarshalRequest(r *http.Request) ([]byte, error) {
934946
defer r.Body.Close()
935947
data, err := ioutil.ReadAll(r.Body)
936948
if err != nil {
937949
return nil, err
938950
}
939-
// Todo: custom content unmarshaler is broken atm
940-
//result := map[string]interface{}{}
941-
//marshaler, _ := selectContentMarshaler(r, marshalers)
942-
//err = marshaler.Unmarshal(data, &result)
943-
//if err != nil {
944-
//return nil, err
945-
//}
946951
return data, nil
947952
}
948953

949-
func marshalResponse(resp interface{}, w http.ResponseWriter, status int, r *http.Request, marshalers map[string]ContentMarshaler) error {
950-
marshaler, contentType := selectContentMarshaler(r, marshalers)
951-
filtered, err := filterSparseFields(resp, r)
952-
if err != nil {
953-
return err
954-
}
955-
result, err := marshaler.Marshal(filtered)
956-
if err != nil {
957-
return err
958-
}
959-
writeResult(w, result, status, contentType)
960-
return nil
961-
}
962-
963954
func filterSparseFields(resp interface{}, r *http.Request) (interface{}, error) {
964955
query := r.URL.Query()
965956
queryParams := parseQueryFields(&query)
@@ -1067,39 +1058,16 @@ func replaceAttributes(query *map[string][]string, entry *jsonapi.Data) map[stri
10671058
return nil
10681059
}
10691060

1070-
func selectContentMarshaler(r *http.Request, marshalers map[string]ContentMarshaler) (marshaler ContentMarshaler, contentType string) {
1071-
if _, found := r.Header["Accept"]; found {
1072-
var contentTypes []string
1073-
for ct := range marshalers {
1074-
contentTypes = append(contentTypes, ct)
1075-
}
1076-
1077-
contentType = httputil.NegotiateContentType(r, contentTypes, defaultContentTypHeader)
1078-
marshaler = marshalers[contentType]
1079-
} else if contentTypes, found := r.Header["Content-Type"]; found {
1080-
contentType = contentTypes[0]
1081-
marshaler = marshalers[contentType]
1082-
}
1083-
1084-
if marshaler == nil {
1085-
contentType = defaultContentTypHeader
1086-
marshaler = JSONContentMarshaler{}
1087-
}
1088-
1089-
return
1090-
}
1091-
1092-
func handleError(err error, w http.ResponseWriter, r *http.Request, marshalers map[string]ContentMarshaler) {
1093-
marshaler, contentType := selectContentMarshaler(r, marshalers)
1094-
1061+
func (api *API) handleError(err error, w http.ResponseWriter, r *http.Request) {
10951062
log.Println(err)
10961063
if e, ok := err.(HTTPError); ok {
1097-
writeResult(w, []byte(marshaler.MarshalError(err)), e.status, contentType)
1064+
writeResult(w, []byte(marshalHTTPError(e)), e.status, api.ContentType)
10981065
return
10991066

11001067
}
11011068

1102-
writeResult(w, []byte(marshaler.MarshalError(err)), http.StatusInternalServerError, contentType)
1069+
e := NewHTTPError(err, err.Error(), http.StatusInternalServerError)
1070+
writeResult(w, []byte(marshalHTTPError(e)), http.StatusInternalServerError, api.ContentType)
11031071
}
11041072

11051073
// TODO: this can also be replaced with a struct into that we directly json.Unmarshal

0 commit comments

Comments
 (0)