Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor web server for RouterGroup features #14

Merged
merged 1 commit into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ module github.com/go-spring-projects/go-spring
go 1.21

require (
github.com/expr-lang/expr v1.15.6
github.com/expr-lang/expr v1.15.7
github.com/golang/mock v1.6.0
github.com/gorilla/mux v1.8.1
github.com/magiconair/properties v1.8.7
github.com/pelletier/go-toml v1.9.5
github.com/spf13/cast v1.6.0
Expand Down
6 changes: 2 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/expr-lang/expr v1.15.6 h1:dQFgzj5DBu3wnUz8+PGLZdPMpefAvxaCFTNM3iSjkGA=
github.com/expr-lang/expr v1.15.6/go.mod h1:uCkhfG+x7fcZ5A5sXHKuQ07jGZRl6J0FCAaf2k4PtVQ=
github.com/expr-lang/expr v1.15.7 h1:BK0JcWUkoW6nrbLBo6xCKhz4BvH5DSOOu1Gx5lucyZo=
github.com/expr-lang/expr v1.15.7/go.mod h1:uCkhfG+x7fcZ5A5sXHKuQ07jGZRl6J0FCAaf2k4PtVQ=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
Expand Down
39 changes: 34 additions & 5 deletions web/bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"errors"
"fmt"
"net/http"
"path"
"reflect"

"github.com/go-spring-projects/go-spring/internal/utils"
Expand Down Expand Up @@ -75,9 +76,12 @@ func Bind(fn interface{}, render Renderer) http.HandlerFunc {
return func(writer http.ResponseWriter, request *http.Request) {

// param of context
webCtx := &Context{Writer: writer, Request: request}
ctx := WithContext(request.Context(), webCtx)
ctxValue := reflect.ValueOf(ctx)
ctx := request.Context()
webCtx := FromContext(ctx)
if nil == webCtx {
webCtx = &Context{Writer: writer, Request: request}
ctx = WithContext(request.Context(), webCtx)
}

defer func() {
if nil != request.MultipartForm {
Expand All @@ -102,6 +106,8 @@ func Bind(fn interface{}, render Renderer) http.HandlerFunc {
}
}()

ctxValue := reflect.ValueOf(ctx)

switch fnType.NumIn() {
case 1:
returnValues = fnValue.Call([]reflect.Value{ctxValue})
Expand Down Expand Up @@ -202,8 +208,12 @@ func validMappingFunc(fnType reflect.Type) error {

func warpHandlerCtx(handler http.HandlerFunc) http.HandlerFunc {
return func(writer http.ResponseWriter, request *http.Request) {
webCtx := &Context{Writer: writer, Request: request}
handler.ServeHTTP(writer, requestWithCtx(request, webCtx))
if nil != FromContext(request.Context()) {
handler.ServeHTTP(writer, request)
} else {
webCtx := &Context{Writer: writer, Request: request}
handler.ServeHTTP(writer, requestWithCtx(request, webCtx))
}
}
}

Expand Down Expand Up @@ -239,3 +249,22 @@ func defaultJsonRender(ctx *Context, err error, result interface{}) {

ctx.JSON(http.StatusOK, response{Code: code, Message: message, Data: result})
}

func lastChar(str string) uint8 {
if str == "" {
panic("The length of the string can't be 0")
}
return str[len(str)-1]
}

func joinPaths(absolutePath, relativePath string) string {
if relativePath == "" {
return absolutePath
}

finalPath := path.Join(absolutePath, relativePath)
if lastChar(relativePath) == '/' && lastChar(finalPath) != '/' {
return finalPath + "/"
}
return finalPath
}
2 changes: 1 addition & 1 deletion web/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ import (
"unicode"

"github.com/go-spring-projects/go-spring/web/binding"
"github.com/go-spring-projects/go-spring/web/internal/mux"
"github.com/go-spring-projects/go-spring/web/render"
"github.com/gorilla/mux"
)

type contextKey struct{}
Expand Down
3 changes: 1 addition & 2 deletions web/examples/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ replace github.com/go-spring-projects/go-spring => ../../
require github.com/go-spring-projects/go-spring v0.0.0-00010101000000-000000000000

require (
github.com/expr-lang/expr v1.15.6 // indirect
github.com/expr-lang/expr v1.15.7 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/spf13/cast v1.6.0 // indirect
Expand Down
6 changes: 2 additions & 4 deletions web/examples/go.sum
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/expr-lang/expr v1.15.6 h1:dQFgzj5DBu3wnUz8+PGLZdPMpefAvxaCFTNM3iSjkGA=
github.com/expr-lang/expr v1.15.6/go.mod h1:uCkhfG+x7fcZ5A5sXHKuQ07jGZRl6J0FCAaf2k4PtVQ=
github.com/expr-lang/expr v1.15.7 h1:BK0JcWUkoW6nrbLBo6xCKhz4BvH5DSOOu1Gx5lucyZo=
github.com/expr-lang/expr v1.15.7/go.mod h1:uCkhfG+x7fcZ5A5sXHKuQ07jGZRl6J0FCAaf2k4PtVQ=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
Expand Down
36 changes: 29 additions & 7 deletions web/examples/greeting/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,43 @@ type Greeting struct {
}

func (g *Greeting) OnInit(ctx context.Context) error {
g.Server.Get("/greeting", g.Greeting)
g.Server.Get("/health", g.Health)
g.Server.Post("/user/register/{username}/{password}", g.Register)
g.Server.Post("/user/password", g.UpdatePassword)

// request time middleware
g.Server.Use(func(handler http.Handler) http.Handler {

return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
start := time.Now()
handler.ServeHTTP(writer, request)
g.Logger.Info("http handle cost",
slog.String("path", request.URL.Path), slog.Duration("cost", time.Since(start)))
g.Logger.Info("request time",
slog.String("path", request.URL.Path), slog.String("method", request.Method), slog.Duration("cost", time.Since(start)))
})
})

// cors middleware
g.Server.Use(func(handler http.Handler) http.Handler {
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
writer.Header().Set("Access-Control-Allow-Origin", "*")
writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
writer.Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type")

// preflight request
if request.Method == http.MethodOptions {
writer.WriteHeader(http.StatusNoContent)
return
}

handler.ServeHTTP(writer, request)
})
})

g.Server.Get("/greeting", g.Greeting)
g.Server.Get("/health", g.Health)

user := g.Server.Group("/user")
{
user.Post("/register/{username}/{password}", g.Register)
user.Post("/password", g.UpdatePassword)
}

return nil
}

Expand Down
Loading