コード例 #1
0
ファイル: api.go プロジェクト: app-kit/go-appkit
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
}
コード例 #2
0
ファイル: wamp.go プロジェクト: app-kit/go-appkit
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
}
コード例 #3
0
ファイル: api.go プロジェクト: app-kit/go-appkit
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
}
コード例 #4
0
ファイル: middlewares.go プロジェクト: app-kit/go-appkit
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
}
コード例 #5
0
ファイル: jsonapi.go プロジェクト: app-kit/go-appkit
// 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
}
コード例 #6
0
ファイル: api.go プロジェクト: app-kit/go-appkit
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)
}
コード例 #7
0
ファイル: wamp.go プロジェクト: app-kit/go-appkit
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)
}
コード例 #8
0
ファイル: api.go プロジェクト: app-kit/go-appkit
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
}
コード例 #9
0
ファイル: middlewares.go プロジェクト: app-kit/go-appkit
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
}