From 828cbbdf5d265d521bcc12300d9c750e7df505cc Mon Sep 17 00:00:00 2001 From: Eyal Post Date: Wed, 17 May 2017 20:38:59 +0300 Subject: [PATCH] Refactor a bit to consolidate packages --- context/context.go | 16 +++++++++++ context/output.go | 13 +++++++++ context/renderer.go | 12 ++++++++ context/response/renderer.go | 46 ------------------------------ context/response/responses.go | 53 ----------------------------------- httpResponse/response.go | 52 ++++++++++++++++++++++++++++++++++ router.go | 3 +- 7 files changed, 94 insertions(+), 101 deletions(-) create mode 100644 context/renderer.go delete mode 100644 context/response/renderer.go delete mode 100644 context/response/responses.go create mode 100644 httpResponse/response.go diff --git a/context/context.go b/context/context.go index 03286097..8b32062c 100644 --- a/context/context.go +++ b/context/context.go @@ -171,6 +171,22 @@ func (ctx *Context) CheckXSRFCookie() bool { return true } +// RenderMethodResult renders the return value of a controller method to the output +func (ctx *Context) RenderMethodResult(result interface{}) { + if result != nil { + renderer, ok := result.(Renderer) + if !ok { + err, ok := result.(error) + if ok { + renderer = errorRenderer(err) + } else { + renderer = jsonRenderer(result) + } + } + renderer.Render(ctx) + } +} + //Response is a wrapper for the http.ResponseWriter //started set to true if response was written to then don't execute other handler type Response struct { diff --git a/context/output.go b/context/output.go index 564ef96d..835552b0 100644 --- a/context/output.go +++ b/context/output.go @@ -168,6 +168,19 @@ func sanitizeValue(v string) string { return cookieValueSanitizer.Replace(v) } +func jsonRenderer(value interface{}) Renderer { + return rendererFunc(func(ctx *Context) { + ctx.Output.JSON(value, false, false) + }) +} + +func errorRenderer(err error) Renderer { + return rendererFunc(func(ctx *Context) { + ctx.Output.SetStatus(500) + ctx.WriteString(err.Error()) + }) +} + // JSON writes json to response body. // if coding is true, it converts utf-8 to \u0000 type. func (output *BeegoOutput) JSON(data interface{}, hasIndent bool, coding bool) error { diff --git a/context/renderer.go b/context/renderer.go new file mode 100644 index 00000000..36a7cb53 --- /dev/null +++ b/context/renderer.go @@ -0,0 +1,12 @@ +package context + +// Renderer defines an http response renderer +type Renderer interface { + Render(ctx *Context) +} + +type rendererFunc func(ctx *Context) + +func (f rendererFunc) Render(ctx *Context) { + f(ctx) +} diff --git a/context/response/renderer.go b/context/response/renderer.go deleted file mode 100644 index 38d0cdf6..00000000 --- a/context/response/renderer.go +++ /dev/null @@ -1,46 +0,0 @@ -package response - -import ( - "strconv" - - "net/http" - - beecontext "github.com/astaxie/beego/context" -) - -const ( - NotFound StatusCode = http.StatusNotFound - BadRequest StatusCode = http.StatusBadRequest -) - -// Renderer defines an http response renderer -type Renderer interface { - Render(ctx *beecontext.Context) -} - -type rendererFunc func(ctx *beecontext.Context) - -func (f rendererFunc) Render(ctx *beecontext.Context) { - f(ctx) -} - -// StatusCode sets the http response status code -type StatusCode int - -func (s StatusCode) Error() string { - return strconv.Itoa(int(s)) -} - -// Render sets the http status code -func (s StatusCode) Render(ctx *beecontext.Context) { - ctx.Output.SetStatus(int(s)) -} - -type statusCodeWithRender struct { - statusCode int - rendererFunc -} - -func (s statusCodeWithRender) Error() string { - return strconv.Itoa(s.statusCode) -} diff --git a/context/response/responses.go b/context/response/responses.go deleted file mode 100644 index 10d1ed3f..00000000 --- a/context/response/responses.go +++ /dev/null @@ -1,53 +0,0 @@ -package response - -import ( - beecontext "github.com/astaxie/beego/context" -) - -// JSON renders value to the response as JSON -func JSON(value interface{}, encoding ...bool) Renderer { - return rendererFunc(func(ctx *beecontext.Context) { - var ( - hasIndent = true - hasEncoding = false - ) - //TODO: need access to BConfig :( - // if BConfig.RunMode == PROD { - // hasIndent = false - // } - if len(encoding) > 0 && encoding[0] { - hasEncoding = true - } - ctx.Output.JSON(value, hasIndent, hasEncoding) - }) -} - -func errorRenderer(err error) Renderer { - return rendererFunc(func(ctx *beecontext.Context) { - ctx.Output.SetStatus(500) - ctx.WriteString(err.Error()) - }) -} - -// Redirect renders http 302 with a URL -func Redirect(localurl string) error { - return statusCodeWithRender{302, func(ctx *beecontext.Context) { - ctx.Redirect(302, localurl) - }} -} - -// RenderMethodResult renders the return value of a controller method to the output -func RenderMethodResult(result interface{}, ctx *beecontext.Context) { - if result != nil { - renderer, ok := result.(Renderer) - if !ok { - err, ok := result.(error) - if ok { - renderer = errorRenderer(err) - } else { - renderer = JSON(result) - } - } - renderer.Render(ctx) - } -} diff --git a/httpResponse/response.go b/httpResponse/response.go new file mode 100644 index 00000000..ca74b85c --- /dev/null +++ b/httpResponse/response.go @@ -0,0 +1,52 @@ +package httpResponse + +import ( + "strconv" + + "net/http" + + beecontext "github.com/astaxie/beego/context" +) + +const ( + //BadRequest indicates http error 400 + BadRequest StatusCode = http.StatusBadRequest + + //NotFound indicates http error 404 + NotFound StatusCode = http.StatusNotFound +) + +// Redirect renders http 302 with a URL +func Redirect(localurl string) error { + return statusCodeWithRender{302, func(ctx *beecontext.Context) { + ctx.Redirect(302, localurl) + }} +} + +// StatusCode sets the http response status code +type StatusCode int + +func (s StatusCode) Error() string { + return strconv.Itoa(int(s)) +} + +// Render sets the http status code +func (s StatusCode) Render(ctx *beecontext.Context) { + ctx.Output.SetStatus(int(s)) +} + +type statusCodeWithRender struct { + statusCode int + f func(ctx *beecontext.Context) +} + +//assert that statusCodeWithRender implements Renderer interface +var _r beecontext.Renderer = (*statusCodeWithRender)(nil) + +func (s statusCodeWithRender) Error() string { + return strconv.Itoa(s.statusCode) +} + +func (s statusCodeWithRender) Render(ctx *beecontext.Context) { + s.f(ctx) +} diff --git a/router.go b/router.go index 33096039..72476ae8 100644 --- a/router.go +++ b/router.go @@ -28,7 +28,6 @@ import ( beecontext "github.com/astaxie/beego/context" "github.com/astaxie/beego/context/param" - "github.com/astaxie/beego/context/response" "github.com/astaxie/beego/logs" "github.com/astaxie/beego/toolbox" "github.com/astaxie/beego/utils" @@ -905,7 +904,7 @@ func (p *ControllerRegister) handleParamResponse(context *beecontext.Context, ex result := results[i] if result.Kind() != reflect.Interface || !result.IsNil() { resultValue := result.Interface() - response.RenderMethodResult(resultValue, context) + context.RenderMethodResult(resultValue) } } if !context.ResponseWriter.Started && context.Output.Status == 0 {