Add back ResponseBuilder
This commit is contained in:
parent
8c8976d79a
commit
052eb1ed56
95
default.go
95
default.go
@ -43,12 +43,12 @@ func (e DefaultError) String() (out string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e DefaultError) Response() *Response {
|
func (e DefaultError) Response() *response {
|
||||||
body, err := json.Marshal(struct{ Error string }{Error: e.String()})
|
body, err := json.Marshal(struct{ Error string }{Error: e.String()})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return &Response{
|
return &response{
|
||||||
Status: e.Status(),
|
Status: e.Status(),
|
||||||
Header: Header{"Content-Type": []string{"text/javascript", "charset=utf-8"}},
|
Header: Header{"Content-Type": []string{"text/javascript", "charset=utf-8"}},
|
||||||
Body: body,
|
Body: body,
|
||||||
@ -81,7 +81,7 @@ type DefaultRequestBuilder struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// /* Leave commented to require services to create their own New method */
|
// Leave commented to require services to create their own New method
|
||||||
// var _ RequestBuilder = (*DefaultRequestBuilder)(nil)
|
// var _ RequestBuilder = (*DefaultRequestBuilder)(nil)
|
||||||
// func (*DefaultRequestBuilder) New() RequestBuilder {
|
// func (*DefaultRequestBuilder) New() RequestBuilder {
|
||||||
// return NewDefaultRequestBuilder()
|
// return NewDefaultRequestBuilder()
|
||||||
@ -177,7 +177,7 @@ func (rqb *DefaultRequestBuilder) Url(url url.URL) (e Error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rqb *DefaultRequestBuilder) Header(header Header) (e Error) {
|
func (rqb *DefaultRequestBuilder) Header(header map[string][]string) (e Error) {
|
||||||
*rqb.header.Header = header
|
*rqb.header.Header = header
|
||||||
err := rqb.header.Header.Unmarshal(rqb.header.fields)
|
err := rqb.header.Header.Unmarshal(rqb.header.fields)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -192,7 +192,7 @@ func (rqb *DefaultRequestBuilder) Body(body io.ReadCloser) (e Error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rqb *DefaultRequestBuilder) Values(values Values) (e Error) {
|
func (rqb *DefaultRequestBuilder) Values(values map[string][]string) (e Error) {
|
||||||
*rqb.values.Values = values
|
*rqb.values.Values = values
|
||||||
err := rqb.values.Values.Unmarshal(rqb.values.fields)
|
err := rqb.values.Values.Unmarshal(rqb.values.fields)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -210,3 +210,88 @@ func (rqb *DefaultRequestBuilder) Request() (req *request) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DefaultResponseBuilder struct {
|
||||||
|
errorHandler Error
|
||||||
|
status *int
|
||||||
|
header struct {
|
||||||
|
*Header
|
||||||
|
fields header
|
||||||
|
}
|
||||||
|
body struct {
|
||||||
|
*Body
|
||||||
|
fields body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Leave commented to require services to create their own New method
|
||||||
|
// var _ ResponseBuilder = (*DefaultResponseBuilder)(nil)
|
||||||
|
// func (rsb *DefaultResponseBuilder) New() ResponseBuilder {
|
||||||
|
// return NewDefaultResponseBuilder()
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (*DefaultResponseBuilder) mustEmbedDefaultResponseBuilder() {}
|
||||||
|
|
||||||
|
func NewDefaultResponseBuilder() *DefaultResponseBuilder {
|
||||||
|
return &DefaultResponseBuilder{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rsb *DefaultResponseBuilder) SetStatus(code *int) *DefaultResponseBuilder {
|
||||||
|
rsb.status = code
|
||||||
|
return rsb
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rsb *DefaultResponseBuilder) SetHeader(parsed *Header, fields header) *DefaultResponseBuilder {
|
||||||
|
rsb.header.Header = parsed
|
||||||
|
rsb.header.fields = fields
|
||||||
|
return rsb
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rsb *DefaultResponseBuilder) SetBody(parsed *Body, fields body) *DefaultResponseBuilder {
|
||||||
|
rsb.body.Body = parsed
|
||||||
|
rsb.body.fields = fields
|
||||||
|
return rsb
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rsb *DefaultResponseBuilder) SetDefaults() *DefaultResponseBuilder {
|
||||||
|
if rsb.status == nil {
|
||||||
|
c := http.StatusOK
|
||||||
|
rsb.status = &c
|
||||||
|
}
|
||||||
|
if rsb.header.Header == nil || rsb.header.fields == nil {
|
||||||
|
hd := Header{"Content-Type": []string{"text/plain", "charset=utf-8"}}
|
||||||
|
rsb.header.Header = &hd
|
||||||
|
hfd := struct{ Header }{Header: hd}
|
||||||
|
rsb.header.fields = &hfd
|
||||||
|
}
|
||||||
|
if rsb.body.Body == nil || rsb.body.fields == nil {
|
||||||
|
bd := make(Body, 0)
|
||||||
|
rsb.body.Body = &bd
|
||||||
|
bfd := struct{ Body }{Body: bd}
|
||||||
|
rsb.body.fields = &bfd
|
||||||
|
}
|
||||||
|
return rsb
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rsb *DefaultResponseBuilder) Header(header map[string][]string) (e Error) {
|
||||||
|
*rsb.header.Header = header
|
||||||
|
err := rsb.header.Header.Unmarshal(rsb.header.fields)
|
||||||
|
if err != nil {
|
||||||
|
return rsb.errorHandler.Error(DefaultErrorInternalServerError)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rsb *DefaultResponseBuilder) Write(body []byte) (e Error) {
|
||||||
|
*rsb.body.Body = append(*rsb.body.Body, body...)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rsb *DefaultResponseBuilder) Response() (res *response) {
|
||||||
|
res = &response{
|
||||||
|
Status: *rsb.status,
|
||||||
|
Header: *rsb.header.Header,
|
||||||
|
Body: *rsb.body.Body,
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
61
server.go
61
server.go
@ -8,17 +8,25 @@ import (
|
|||||||
"somehole.com/common/log"
|
"somehole.com/common/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Response struct {
|
type response struct {
|
||||||
Status int
|
Status int
|
||||||
Header Header
|
Header Header
|
||||||
Body Body
|
Body Body
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Response[RSB ResponseBuilder] struct {
|
||||||
|
response
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewResponse[RSB ResponseBuilder](rsb RSB) *Response[RSB] {
|
||||||
|
return &Response[RSB]{*rsb.Response()}
|
||||||
|
}
|
||||||
|
|
||||||
type Error interface {
|
type Error interface {
|
||||||
Error(e Error) (err Error)
|
Error(e Error) (err Error)
|
||||||
Status() (code int)
|
Status() (code int)
|
||||||
String() (out string)
|
String() (out string)
|
||||||
Response() (res *Response)
|
Response() (res *response)
|
||||||
}
|
}
|
||||||
|
|
||||||
type request struct {
|
type request struct {
|
||||||
@ -46,12 +54,25 @@ type RequestBuilder interface {
|
|||||||
New() (rqb RequestBuilder)
|
New() (rqb RequestBuilder)
|
||||||
Allowed(method string) (err Error)
|
Allowed(method string) (err Error)
|
||||||
Url(url url.URL) (err Error)
|
Url(url url.URL) (err Error)
|
||||||
Header(header Header) (err Error)
|
Header(map[string][]string) (err Error)
|
||||||
Values(values Values) (err Error)
|
Values(map[string][]string) (err Error)
|
||||||
Body(body io.ReadCloser) (err Error)
|
Body(body io.ReadCloser) (err Error)
|
||||||
Request() *request
|
Request() *request
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*Response[RSB]) ResponseBuilder() ResponseBuilder {
|
||||||
|
var rsb RSB
|
||||||
|
return rsb.New()
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResponseBuilder interface {
|
||||||
|
mustEmbedDefaultResponseBuilder()
|
||||||
|
New() (rsb ResponseBuilder)
|
||||||
|
Header(header Header) (err Error)
|
||||||
|
Write(body []byte) (err Error)
|
||||||
|
Response() *response
|
||||||
|
}
|
||||||
|
|
||||||
type writer struct {
|
type writer struct {
|
||||||
http.ResponseWriter
|
http.ResponseWriter
|
||||||
log.Logger
|
log.Logger
|
||||||
@ -82,47 +103,47 @@ const (
|
|||||||
numServeStages
|
numServeStages
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServeFunc[RQB RequestBuilder] func(req *Request[RQB]) (res *Response, err Error)
|
type ServeFunc[RQB RequestBuilder, RSB ResponseBuilder] func(req *Request[RQB]) (res *Response[RSB], err Error)
|
||||||
|
|
||||||
type server[RQB RequestBuilder] struct {
|
type server[RQB RequestBuilder, RSB ResponseBuilder] struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
serve [numServeStages][]ServeFunc[RQB]
|
serve [numServeStages][]ServeFunc[RQB, RSB]
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServer[RQB RequestBuilder](serve func(req *Request[RQB]) (res *Response, err Error)) (srv *server[RQB]) {
|
func NewServer[RQB RequestBuilder, RSB ResponseBuilder](serve ServeFunc[RQB, RSB]) (srv *server[RQB, RSB]) {
|
||||||
srv = &server[RQB]{
|
srv = &server[RQB, RSB]{
|
||||||
serve: [numServeStages][]ServeFunc[RQB]{},
|
serve: [numServeStages][]ServeFunc[RQB, RSB]{},
|
||||||
}
|
}
|
||||||
srv.serve[serveMain] = append(srv.serve[serveMain], serve)
|
srv.serve[serveMain] = append(srv.serve[serveMain], serve)
|
||||||
return srv
|
return srv
|
||||||
}
|
}
|
||||||
|
|
||||||
func (srv *server[RQB]) SetLogger(logger log.Logger) *server[RQB] {
|
func (srv *server[RQB, RSB]) SetLogger(logger log.Logger) *server[RQB, RSB] {
|
||||||
srv.logger = logger
|
srv.logger = logger
|
||||||
return srv
|
return srv
|
||||||
}
|
}
|
||||||
|
|
||||||
func (srv *server[RQB]) addServeFunc(when serveStage, serve ServeFunc[RQB]) *server[RQB] {
|
func (srv *server[RQB, RSB]) addServeFunc(when serveStage, serve ServeFunc[RQB, RSB]) *server[RQB, RSB] {
|
||||||
if srv.serve[when] == nil {
|
if srv.serve[when] == nil {
|
||||||
srv.serve[when] = make([]ServeFunc[RQB], 0)
|
srv.serve[when] = make([]ServeFunc[RQB, RSB], 0)
|
||||||
}
|
}
|
||||||
srv.serve[when] = append(srv.serve[when], serve)
|
srv.serve[when] = append(srv.serve[when], serve)
|
||||||
return srv
|
return srv
|
||||||
}
|
}
|
||||||
|
|
||||||
func (srv *server[RQB]) PreServeFunc(serve ServeFunc[RQB]) *server[RQB] {
|
func (srv *server[RQB, RSB]) PreServeFunc(serve ServeFunc[RQB, RSB]) *server[RQB, RSB] {
|
||||||
return srv.addServeFunc(servePre, serve)
|
return srv.addServeFunc(servePre, serve)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (srv *server[RQB]) AddServeFunc(serve ServeFunc[RQB]) *server[RQB] {
|
func (srv *server[RQB, RSB]) AddServeFunc(serve ServeFunc[RQB, RSB]) *server[RQB, RSB] {
|
||||||
return srv.addServeFunc(serveMain, serve)
|
return srv.addServeFunc(serveMain, serve)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (srv *server[RQB]) PostServeFunc(serve ServeFunc[RQB]) *server[RQB] {
|
func (srv *server[RQB, RSB]) PostServeFunc(serve ServeFunc[RQB, RSB]) *server[RQB, RSB] {
|
||||||
return srv.addServeFunc(servePost, serve)
|
return srv.addServeFunc(servePost, serve)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (srv *server[RQB]) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (srv *server[RQB, RSB]) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
var rqb RQB
|
var rqb RQB
|
||||||
rqb = rqb.New().(RQB)
|
rqb = rqb.New().(RQB)
|
||||||
wr := writer{ResponseWriter: w, Logger: srv.logger}
|
wr := writer{ResponseWriter: w, Logger: srv.logger}
|
||||||
@ -132,14 +153,14 @@ func (srv *server[RQB]) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
if ok := wr.handleError(rqb.Url(*r.URL)); !ok {
|
if ok := wr.handleError(rqb.Url(*r.URL)); !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ok := wr.handleError(rqb.Header(Header(r.Header))); !ok {
|
if ok := wr.handleError(rqb.Header(r.Header)); !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ok := wr.handleError(rqb.Body(r.Body)); !ok {
|
if ok := wr.handleError(rqb.Body(r.Body)); !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.ParseForm()
|
r.ParseForm()
|
||||||
if ok := wr.handleError(rqb.Values(Values(r.Form))); !ok {
|
if ok := wr.handleError(rqb.Values(r.Form)); !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, stage := range srv.serve {
|
for _, stage := range srv.serve {
|
||||||
@ -151,7 +172,7 @@ func (srv *server[RQB]) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
if res.Header != nil {
|
if res.Header != nil {
|
||||||
for key, value := range res.Header {
|
for key, value := range res.Header {
|
||||||
for _, v := range value {
|
for _, v := range value {
|
||||||
w.Header().Add(key, v)
|
wr.Header().Add(key, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user