// matcherFunc matches the handler to the correct API version based on its `accept` header // TODO: refactor matcher function as server.Config func matcherFunc(r domain.Route, defaultHandler http.HandlerFunc, ctx domain.IContext, ac domain.IAccessController) func(r *http.Request, rm *mux.RouteMatch) bool { return func(req *http.Request, rm *mux.RouteMatch) bool { acceptHeaders := domain.NewAcceptHeadersFromString(req.Header.Get("accept")) foundHandler := defaultHandler // try to match a handler to the specified `version` params // else we will fall back to the default handler for _, h := range acceptHeaders { m := h.MediaType // check if media type is `application/json` type or `application/[*]+json` suffix if !(m.Type == "application" && (m.SubType == "json" || m.Suffix == "json")) { continue } // if its the right application type, check if a version specified version, hasVersion := m.Parameters["version"] if !hasVersion { continue } if handler, ok := r.RouteHandlers[domain.RouteHandlerVersion(version)]; ok { // found handler for specified version foundHandler = handler break } } if ac != nil { rm.Handler = ac.NewContextHandler(r.Name, foundHandler) } else { rm.Handler = foundHandler } return true } }
func (renderer *Renderer) Render(w http.ResponseWriter, req *http.Request, status int, v interface{}) { acceptHeaders := domain.NewAcceptHeadersFromString(req.Header.Get("accept")) renderType := renderer.DefaultRenderType for _, h := range acceptHeaders { m := h.MediaType if m.SubType == JSON || m.Suffix == JSON { renderType = JSON break } if m.SubType == XML || m.Suffix == XML { renderType = XML break } if m.SubType == Data || m.Suffix == Data { renderType = Data break } if m.SubType == Text || m.Suffix == Text { renderType = Text break } } switch renderType { case JSON: renderer.JSON(w, status, v) case XML: renderer.XML(w, status, v) case Data: renderer.Data(w, status, v.([]byte)) case Text: renderer.Text(w, status, v.([]byte)) default: renderer.Text(w, status, v.([]byte)) } }
String: "*/*", Type: "*", Tree: "", SubType: "*", Suffix: "", Parameters: domain.MediaTypeParams{ "q": "noninteger", }, }, 1}, }, }, } for _, test := range tests { testValue := test.TestValue expectedResults := test.ExpectedResults Context(fmt.Sprintf("when `Accept=%v`", testValue), func() { result := domain.NewAcceptHeadersFromString(testValue) It("parses OK", func() { Expect(len(result)).To(Equal(len(expectedResults))) for i, _ := range expectedResults { Expect(result[i].MediaType).To(Equal(expectedResults[i].MediaType)) Expect(result[i].QualityFactor).To(Equal(expectedResults[i].QualityFactor)) } }) }) } }) })