瀏覽代碼

feat: rest validation on http requests (#3041)

Kevin Wan 2 年之前
父節點
當前提交
6170d7b790
共有 4 個文件被更改,包括 32 次插入2 次删除
  1. 1 1
      core/executors/periodicalexecutor.go
  2. 7 0
      core/validation/validator.go
  3. 4 1
      rest/httpx/requests.go
  4. 20 0
      rest/httpx/requests_test.go

+ 1 - 1
core/executors/periodicalexecutor.go

@@ -81,7 +81,7 @@ func (pe *PeriodicalExecutor) Flush() bool {
 	}())
 }
 
-// Sync lets caller to run fn thread-safe with pe, especially for the underlying container.
+// Sync lets caller run fn thread-safe with pe, especially for the underlying container.
 func (pe *PeriodicalExecutor) Sync(fn func()) {
 	pe.lock.Lock()
 	defer pe.lock.Unlock()

+ 7 - 0
core/validation/validator.go

@@ -0,0 +1,7 @@
+package validation
+
+// Validator represents a validator.
+type Validator interface {
+	// Validate validates the value.
+	Validate() error
+}

+ 4 - 1
rest/httpx/requests.go

@@ -7,6 +7,7 @@ import (
 	"sync/atomic"
 
 	"github.com/zeromicro/go-zero/core/mapping"
+	"github.com/zeromicro/go-zero/core/validation"
 	"github.com/zeromicro/go-zero/rest/internal/encoding"
 	"github.com/zeromicro/go-zero/rest/internal/header"
 	"github.com/zeromicro/go-zero/rest/pathvar"
@@ -51,7 +52,9 @@ func Parse(r *http.Request, v any) error {
 		return err
 	}
 
-	if val := validator.Load(); val != nil {
+	if valid, ok := v.(validation.Validator); ok {
+		return valid.Validate()
+	} else if val := validator.Load(); val != nil {
 		return val.(Validator).Validate(r, v)
 	}
 

+ 20 - 0
rest/httpx/requests_test.go

@@ -354,6 +354,14 @@ func TestParseWithValidatorWithError(t *testing.T) {
 	assert.Error(t, Parse(r, &v))
 }
 
+func TestParseWithValidatorRequest(t *testing.T) {
+	SetValidator(mockValidator{})
+	var v mockRequest
+	r, err := http.NewRequest(http.MethodGet, "/a?&age=18", http.NoBody)
+	assert.Nil(t, err)
+	assert.Error(t, Parse(r, &v))
+}
+
 func BenchmarkParseRaw(b *testing.B) {
 	r, err := http.NewRequest(http.MethodGet, "http://hello.com/a?name=hello&age=18&percent=3.4", http.NoBody)
 	if err != nil {
@@ -410,3 +418,15 @@ func (m mockValidator) Validate(r *http.Request, data any) error {
 
 	return nil
 }
+
+type mockRequest struct {
+	Name string `json:"name,optional"`
+}
+
+func (m mockRequest) Validate() error {
+	if m.Name != "hello" {
+		return errors.New("name is not hello")
+	}
+
+	return nil
+}