From 6170d7b790922aed130c0801540fbef01f05a7c9 Mon Sep 17 00:00:00 2001 From: Kevin Wan Date: Sun, 19 Mar 2023 20:04:18 +0800 Subject: [PATCH] feat: rest validation on http requests (#3041) --- core/executors/periodicalexecutor.go | 2 +- core/validation/validator.go | 7 +++++++ rest/httpx/requests.go | 5 ++++- rest/httpx/requests_test.go | 20 ++++++++++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 core/validation/validator.go diff --git a/core/executors/periodicalexecutor.go b/core/executors/periodicalexecutor.go index 6722a657..e13f907e 100644 --- a/core/executors/periodicalexecutor.go +++ b/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() diff --git a/core/validation/validator.go b/core/validation/validator.go new file mode 100644 index 00000000..2903ac9c --- /dev/null +++ b/core/validation/validator.go @@ -0,0 +1,7 @@ +package validation + +// Validator represents a validator. +type Validator interface { + // Validate validates the value. + Validate() error +} diff --git a/rest/httpx/requests.go b/rest/httpx/requests.go index cd088bb0..02d29eca 100644 --- a/rest/httpx/requests.go +++ b/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) } diff --git a/rest/httpx/requests_test.go b/rest/httpx/requests_test.go index fa7dd9dc..aa462176 100644 --- a/rest/httpx/requests_test.go +++ b/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 +}