func MarshalResponseMiddleware(registry kit.Registry, request kit.Request, response kit.Response) (kit.Response, bool) { js, err := json.Marshal(response.GetData()) if err != nil { js = []byte(`{"errors": [{code: "response_marshal_error"}]}`) } response.SetRawData(js) return nil, false }
func convertResponse(response kit.Response) *turnpike.CallResult { result := &turnpike.CallResult{} if response.GetError() != nil { result.Err = turnpike.URI(response.GetError().GetCode()) } result.Kwargs = map[string]interface{}{ "data": response.GetData(), "meta": response.GetMeta(), "errors": []error{response.GetError()}, } return result }
func processRequest(registry kit.Registry, request kit.Request, handler kit.RequestHandler) (kit.Response, bool) { var response kit.Response // Run before middlewares. for _, middleware := range registry.HttpFrontend().BeforeMiddlewares() { var skip bool response, skip = middleware(registry, request) if skip { return nil, true } else if response != nil { break } } // Only run the handler if no middleware provided a response. if response == nil { skip := false response, skip = handler(registry, request) if skip { return nil, true } } if response.GetHttpStatus() == 0 { // Note: error handler middleware will set proper http status for error responses. response.SetHttpStatus(200) } // Run after request middlewares. // Note: error responses are converted with the serverErrrorMiddleware middleware. // Note: serializing the response into the proper format is done with the SerializeResponseMiddleware. for _, middleware := range registry.HttpFrontend().AfterMiddlewares() { resp, skip := middleware(registry, request, response) if skip { return nil, true } else if resp != nil { response = resp } } return response, false }
func SerializeResponseMiddleware(registry kit.Registry, request kit.Request, response kit.Response) (kit.Response, bool) { // Try to serialize the reponse data. // Determine serializer. serializer := registry.DefaultSerializer() // Check if a custom serializer was specified. if name := request.GetContext().String("response-serializer"); name != "" { serializer = registry.Serializer(name) if serializer == nil { errResp := kit.NewErrorResponse("unknown_response_serializer", true) data, _ := serializer.MustSerializeResponse(errResp) errResp.SetData(data) return errResp, false } } // Set format in metadata. meta := response.GetMeta() if meta == nil { meta = make(map[string]interface{}) } meta["format"] = serializer.Name() response.SetMeta(meta) data, err := serializer.MustSerializeResponse(response) if err != nil { registry.Logger().Errorf("Response serialization error: %v (%+v)", err, response) } response.SetData(data) return nil, false }
// SerializeResponse converts a response with model data into the target format. func (s *Serializer) SerializeResponse(response kit.Response) (interface{}, apperror.Error) { transData := response.GetTransferData() if transData == nil { transData = &kit.AppTransferData{} data := response.GetData() if model, ok := data.(kit.Model); ok { transData.SetModels([]kit.Model{model}) } else if models, ok := data.([]kit.Model); ok { transData.SetModels(models) } else { transData.SetData(data) } } // Append response metadata. if meta := response.GetMeta(); meta != nil { transMeta := transData.GetMeta() if transMeta != nil { for key, val := range meta { transMeta[key] = val } } else { transData.SetMeta(meta) } } // If a response error is defined, prepend it to all errors that might have been in // TransferData. if err := response.GetError(); err != nil { oldErrs := transData.GetErrors() transData.SetErrors(append([]apperror.Error{err}, oldErrs...)) } data, err := s.SerializeTransferData(transData) if err != nil { return nil, err } return data, nil }
func RespondWithJson(w http.ResponseWriter, response kit.Response) { code := 200 respData := map[string]interface{}{ "data": response.GetData(), } if response.GetError() != nil { errs := []error{response.GetError()} additionalErrs := response.GetError().GetErrors() if additionalErrs != nil { for _, err := range additionalErrs { if apiErr, ok := err.(apperror.Error); ok && apiErr.IsPublic() { errs = append(errs, apiErr) } } } respData["errors"] = errs code = 500 } output, err2 := json.Marshal(respData) if err2 != nil { code = 500 respData = map[string]interface{}{ "errors": []error{ apperror.Wrap(err2, "json_encode_error"), }, } output, _ = json.Marshal(respData) } w.Header().Set("Content-Type", "application/json") w.WriteHeader(code) w.Write(output) }
func (f *Frontend) registerMethod(method kit.Method) { f.client.Register(method.GetName(), func(args []interface{}, kwargs map[string]interface{}, details map[string]interface{}) (result *turnpike.CallResult) { methodName := method.GetName() fmt.Printf("WAMP method %v |\n data: %v |\n details: %v\n", methodName, kwargs, details) request := kit.NewRequest() request.SetFrontend("wamp") request.SetPath("/method/" + methodName) request.SetData(kwargs) var response kit.Response // Find session. sessionId := uint(details["session_id"].(turnpike.ID)) session := f.sessions[sessionId] if session == nil { s, err := f.registry.UserService().StartSession(nil, "wamp") if err != nil { response = kit.NewErrorResponse(err) } else { f.sessions[sessionId] = s session = s } } request.SetSession(session) if session.GetUser() != nil { request.SetUser(session.GetUser()) } // Run before middlewares. for _, middleware := range f.beforeMiddlewares { resp, skip := middleware(f.registry, request) if skip { panic("WAMP frontend middlewares do not support skipping.") } else if resp != nil { response = resp break } } // Run the method. if response == nil { responder := func(r kit.Response) { response = r } finishedChannel, err := f.registry.App().RunMethod(methodName, request, responder, true) if err != nil { response = kit.NewErrorResponse(err) } else { <-finishedChannel } } // Run after middlewares. for _, middleware := range f.afterMiddlewares { resp, skip := middleware(f.registry, request, response) if skip { panic("WAMP frontend middlewares do not support skipping.") } if resp != nil { response = resp } } return &turnpike.CallResult{Kwargs: response.GetData().(map[string]interface{})} }, nil) }
func ServerErrorMiddleware(registry kit.Registry, r kit.Request, response kit.Response) (kit.Response, bool) { err := response.GetError() if err == nil { return nil, false } status := 500 // If the error is an apperror, and it contains a status, // set it as the http status of the response. if apperr, ok := err.(apperror.Error); ok { if apperr.GetStatus() != 0 { status = apperr.GetStatus() } } response.SetHttpStatus(status) if response.GetRawData() != nil || response.GetRawDataReader() != nil { return nil, false } httpRequest := r.GetHttpRequest() apiPrefix := "/" + registry.Config().UString("api.prefix", "api") isApiRequest := strings.HasPrefix(httpRequest.URL.Path, apiPrefix) if isApiRequest { return nil, false } data := map[string]interface{}{"errors": []error{response.GetError()}} tpl := defaultErrorTpl() tplPath := registry.Config().UString("frontend.errorTemplate") if tplPath != "" { t, err := template.ParseFiles(tplPath) if err != nil { registry.Logger().Fatalf("Could not parse error template at '%v': %v", tplPath, err) } else { tpl = t } } var buffer *bytes.Buffer if err := tpl.Execute(buffer, data); err != nil { registry.Logger().Fatalf("Could not render error template: %v\n", err) response.SetRawData([]byte("Server error")) } else { response.SetRawData(buffer.Bytes()) } return nil, false }
func RequestLoggerMiddleware(registry kit.Registry, r kit.Request, response kit.Response) (kit.Response, bool) { // Calculate time taken. rawStarted, ok1 := r.GetContext().Get("startTime") rawFinished, ok2 := r.GetContext().Get("endTime") timeTaken := int64(-1) if ok1 && ok2 { started := rawStarted.(time.Time) finished := rawFinished.(time.Time) timeTaken = int64(finished.Sub(started) / time.Millisecond) } // Log the request. method := r.GetHttpMethod() path := r.GetPath() if response.GetError() != nil { registry.Logger().WithFields(logrus.Fields{ "frontend": r.GetFrontend(), "action": "request", "method": method, "path": path, "status": response.GetHttpStatus(), "err": response.GetError(), "milliseconds": timeTaken, }).Errorf("%v: %v - %v - %v", response.GetHttpStatus(), method, path, response.GetError()) } else { registry.Logger().WithFields(logrus.Fields{ "frontend": r.GetFrontend(), "action": "request", "method": method, "path": path, "status": response.GetHttpStatus(), "milliseconds": timeTaken, }).Debugf("%v: %v - %v", response.GetHttpStatus(), method, path) } return nil, false }