mirror of
https://github.com/zeromicro/go-zero.git
synced 2026-05-07 15:10:01 +08:00
feat: support serverless in rest (#5001)
Signed-off-by: kevin <wanjunfeng@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -119,6 +119,16 @@ func (s *Server) Use(middleware Middleware) {
|
|||||||
s.ngin.use(middleware)
|
s.ngin.use(middleware)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// build builds the Server and binds the routes to the router.
|
||||||
|
func (s *Server) build() error {
|
||||||
|
return s.ngin.bindRoutes(s.router)
|
||||||
|
}
|
||||||
|
|
||||||
|
// serve serves the HTTP requests using the Server's router.
|
||||||
|
func (s *Server) serve(w http.ResponseWriter, r *http.Request) {
|
||||||
|
s.router.ServeHTTP(w, r)
|
||||||
|
}
|
||||||
|
|
||||||
// ToMiddleware converts the given handler to a Middleware.
|
// ToMiddleware converts the given handler to a Middleware.
|
||||||
func ToMiddleware(handler func(next http.Handler) http.Handler) Middleware {
|
func ToMiddleware(handler func(next http.Handler) http.Handler) Middleware {
|
||||||
return func(handle http.HandlerFunc) http.HandlerFunc {
|
return func(handle http.HandlerFunc) http.HandlerFunc {
|
||||||
|
|||||||
@@ -819,6 +819,6 @@ func TestServerEmbedFileSystem(t *testing.T) {
|
|||||||
// serve(server, w, r)
|
// serve(server, w, r)
|
||||||
// // verify the response
|
// // verify the response
|
||||||
func serve(s *Server, w http.ResponseWriter, r *http.Request) {
|
func serve(s *Server, w http.ResponseWriter, r *http.Request) {
|
||||||
s.ngin.bindRoutes(s.router)
|
_ = s.build()
|
||||||
s.router.ServeHTTP(w, r)
|
s.serve(w, r)
|
||||||
}
|
}
|
||||||
|
|||||||
27
rest/serverless.go
Normal file
27
rest/serverless.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package rest
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
|
// Serverless is a wrapper around Server that allows it to be used in serverless environments.
|
||||||
|
type Serverless struct {
|
||||||
|
server *Server
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewServerless creates a new Serverless instance from the provided Server.
|
||||||
|
func NewServerless(server *Server) (*Serverless, error) {
|
||||||
|
// Ensure the server is built before using it in a serverless context.
|
||||||
|
// Why not call server.build() when serving requests,
|
||||||
|
// is because we need to ensure fail fast behavior.
|
||||||
|
if err := server.build(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Serverless{
|
||||||
|
server: server,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serve handles HTTP requests by delegating them to the underlying Server instance.
|
||||||
|
func (s *Serverless) Serve(w http.ResponseWriter, r *http.Request) {
|
||||||
|
s.server.serve(w, r)
|
||||||
|
}
|
||||||
67
rest/serverless_test.go
Normal file
67
rest/serverless_test.go
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
package rest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/zeromicro/go-zero/core/conf"
|
||||||
|
"github.com/zeromicro/go-zero/core/logx/logtest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewServerless(t *testing.T) {
|
||||||
|
logtest.Discard(t)
|
||||||
|
|
||||||
|
const configYaml = `
|
||||||
|
Name: foo
|
||||||
|
Host: localhost
|
||||||
|
Port: 0
|
||||||
|
`
|
||||||
|
var cnf RestConf
|
||||||
|
assert.Nil(t, conf.LoadFromYamlBytes([]byte(configYaml), &cnf))
|
||||||
|
|
||||||
|
svr, err := NewServer(cnf)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
svr.AddRoute(Route{
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/",
|
||||||
|
Handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Write([]byte("Hello World"))
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
serverless, err := NewServerless(svr)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
r := httptest.NewRequest(http.MethodGet, "/", nil)
|
||||||
|
serverless.Serve(w, r)
|
||||||
|
assert.Equal(t, http.StatusOK, w.Code)
|
||||||
|
assert.Equal(t, "Hello World", w.Body.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewServerlessWithError(t *testing.T) {
|
||||||
|
logtest.Discard(t)
|
||||||
|
|
||||||
|
const configYaml = `
|
||||||
|
Name: foo
|
||||||
|
Host: localhost
|
||||||
|
Port: 0
|
||||||
|
`
|
||||||
|
var cnf RestConf
|
||||||
|
assert.Nil(t, conf.LoadFromYamlBytes([]byte(configYaml), &cnf))
|
||||||
|
|
||||||
|
svr, err := NewServer(cnf)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
svr.AddRoute(Route{
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "notstartwith/",
|
||||||
|
Handler: nil,
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err = NewServerless(svr)
|
||||||
|
assert.Error(t, err)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user