diff --git a/codegen/internal/runtime/params/bind.go b/codegen/internal/runtime/params/bind.go index 3de41d5..662d17c 100644 --- a/codegen/internal/runtime/params/bind.go +++ b/codegen/internal/runtime/params/bind.go @@ -170,6 +170,9 @@ func BindQueryParameter(paramName string, queryParams url.Values, dest any, opts var fieldsPresent bool fieldsPresent, err = bindParamsToExplodedObject(paramName, queryParams, output) if !fieldsPresent { + if opts.Required { + return &MissingRequiredParameterError{ParamName: paramName} + } return nil } default: @@ -339,6 +342,9 @@ func BindRawQueryParameter(paramName string, rawQuery string, dest any, opts Par var fieldsPresent bool fieldsPresent, err = bindParamsToExplodedObject(paramName, queryParams, output) if !fieldsPresent { + if opts.Required { + return &MissingRequiredParameterError{ParamName: paramName} + } return nil } default: diff --git a/codegen/internal/runtime/params/bind_test.go b/codegen/internal/runtime/params/bind_test.go index 56c3fdf..ea7496e 100644 --- a/codegen/internal/runtime/params/bind_test.go +++ b/codegen/internal/runtime/params/bind_test.go @@ -4,6 +4,7 @@ import ( "errors" "net/url" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -252,22 +253,60 @@ func TestBindQueryParameter_Form_Roundtrip(t *testing.T) { } func TestBindQueryParameter_OptionalMissing(t *testing.T) { - vals := url.Values{} + t.Run("explode_primitive", func(t *testing.T) { + vals := url.Values{} - var result *string - err := BindQueryParameter("missing", vals, &result, ParameterOptions{Style: "form", Explode: true}) - require.NoError(t, err) - assert.Nil(t, result) + var result *string + err := BindQueryParameter("missing", vals, &result, ParameterOptions{Style: "form", Explode: true}) + require.NoError(t, err) + assert.Nil(t, result) + }) + t.Run("explode_string_slice", func(t *testing.T) { + vals := url.Values{} + + var result *[]string + err := BindQueryParameter("missing", vals, &result, ParameterOptions{Style: "form", Explode: true}) + require.NoError(t, err) + assert.Nil(t, result) + }) + t.Run("explode_struct", func(t *testing.T) { + vals := url.Values{} + + var result *time.Time + err := BindQueryParameter("missing", vals, &result, ParameterOptions{Style: "form", Explode: true}) + require.NoError(t, err) + assert.Nil(t, result) + }) } func TestBindQueryParameter_RequiredMissing(t *testing.T) { - vals := url.Values{} + t.Run("explode_primitive", func(t *testing.T) { + vals := url.Values{} - var result string - err := BindQueryParameter("required", vals, &result, ParameterOptions{Style: "form", Explode: true, Required: true}) - require.Error(t, err) - var reqErr *MissingRequiredParameterError - assert.True(t, errors.As(err, &reqErr)) + var result string + err := BindQueryParameter("required", vals, &result, ParameterOptions{Style: "form", Explode: true, Required: true}) + require.Error(t, err) + var reqErr *MissingRequiredParameterError + assert.True(t, errors.As(err, &reqErr)) + }) + t.Run("explode_string_slice", func(t *testing.T) { + vals := url.Values{} + + var result []string + err := BindQueryParameter("required", vals, &result, ParameterOptions{Style: "form", Explode: true, Required: true}) + require.Error(t, err) + var reqErr *MissingRequiredParameterError + assert.True(t, errors.As(err, &reqErr)) + }) + t.Run("explode_struct", func(t *testing.T) { + vals := url.Values{} + + var result time.Time + err := BindQueryParameter("required", vals, &result, ParameterOptions{Style: "form", Explode: true, Required: true}) + require.Error(t, err) + var reqErr *MissingRequiredParameterError + assert.True(t, errors.As(err, &reqErr)) + }) } func TestBindQueryParameter_DeepObject_Roundtrip(t *testing.T) { @@ -325,3 +364,64 @@ func TestBindQueryParameter_DeepObject_Roundtrip(t *testing.T) { assert.Equal(t, original, result) }) } + +// --------------------------------------------------------------------------- +// BindRawQueryParameter (query - string) +// --------------------------------------------------------------------------- + +func TestBindRawQueryParameter_OptionalMissing(t *testing.T) { + t.Run("primitive", func(t *testing.T) { + vals := "" + + var result *string + err := BindRawQueryParameter("missing", vals, &result, ParameterOptions{Style: "form", Explode: false}) + require.NoError(t, err) + assert.Nil(t, result) + }) + t.Run("string_slice", func(t *testing.T) { + vals := "" + + var result *[]string + err := BindRawQueryParameter("missing", vals, &result, ParameterOptions{Style: "form", Explode: false}) + require.NoError(t, err) + assert.Nil(t, result) + }) + t.Run("struct", func(t *testing.T) { + vals := "" + + var result *time.Time + err := BindRawQueryParameter("missing", vals, &result, ParameterOptions{Style: "form", Explode: false}) + require.NoError(t, err) + assert.Nil(t, result) + }) +} + +func TestBindRawQueryParameter_RequiredMissing(t *testing.T) { + t.Run("primitive", func(t *testing.T) { + vals := "" + + var result string + err := BindRawQueryParameter("required", vals, &result, ParameterOptions{Style: "form", Explode: false, Required: true}) + require.Error(t, err) + var reqErr *MissingRequiredParameterError + assert.True(t, errors.As(err, &reqErr)) + }) + t.Run("string_slice", func(t *testing.T) { + vals := "" + + var result []string + err := BindRawQueryParameter("required", vals, &result, ParameterOptions{Style: "form", Explode: false, Required: true}) + require.Error(t, err) + var reqErr *MissingRequiredParameterError + assert.True(t, errors.As(err, &reqErr)) + }) + t.Run("struct", func(t *testing.T) { + vals := "" + + var result time.Time + err := BindRawQueryParameter("required", vals, &result, ParameterOptions{Style: "form", Explode: false, Required: true}) + require.Error(t, err) + var reqErr *MissingRequiredParameterError + assert.True(t, errors.As(err, &reqErr)) + }) +} diff --git a/examples/petstore-expanded/chi/server/server.gen.go b/examples/petstore-expanded/chi/server/server.gen.go index 13e7227..381b5f9 100644 --- a/examples/petstore-expanded/chi/server/server.gen.go +++ b/examples/petstore-expanded/chi/server/server.gen.go @@ -488,6 +488,9 @@ func BindQueryParameter(paramName string, queryParams url.Values, dest any, opts var fieldsPresent bool fieldsPresent, err = bindParamsToExplodedObject(paramName, queryParams, output) if !fieldsPresent { + if opts.Required { + return &MissingRequiredParameterError{ParamName: paramName} + } return nil } default: diff --git a/examples/petstore-expanded/echo-v4/server/server.gen.go b/examples/petstore-expanded/echo-v4/server/server.gen.go index e8ac192..2257f43 100644 --- a/examples/petstore-expanded/echo-v4/server/server.gen.go +++ b/examples/petstore-expanded/echo-v4/server/server.gen.go @@ -422,6 +422,9 @@ func BindQueryParameter(paramName string, queryParams url.Values, dest any, opts var fieldsPresent bool fieldsPresent, err = bindParamsToExplodedObject(paramName, queryParams, output) if !fieldsPresent { + if opts.Required { + return &MissingRequiredParameterError{ParamName: paramName} + } return nil } default: diff --git a/examples/petstore-expanded/echo/server/server.gen.go b/examples/petstore-expanded/echo/server/server.gen.go index 8f56add..063dfdd 100644 --- a/examples/petstore-expanded/echo/server/server.gen.go +++ b/examples/petstore-expanded/echo/server/server.gen.go @@ -423,6 +423,9 @@ func BindQueryParameter(paramName string, queryParams url.Values, dest any, opts var fieldsPresent bool fieldsPresent, err = bindParamsToExplodedObject(paramName, queryParams, output) if !fieldsPresent { + if opts.Required { + return &MissingRequiredParameterError{ParamName: paramName} + } return nil } default: diff --git a/examples/petstore-expanded/fiber/server/server.gen.go b/examples/petstore-expanded/fiber/server/server.gen.go index aa0a8c4..a1d63e3 100644 --- a/examples/petstore-expanded/fiber/server/server.gen.go +++ b/examples/petstore-expanded/fiber/server/server.gen.go @@ -418,6 +418,9 @@ func BindQueryParameter(paramName string, queryParams url.Values, dest any, opts var fieldsPresent bool fieldsPresent, err = bindParamsToExplodedObject(paramName, queryParams, output) if !fieldsPresent { + if opts.Required { + return &MissingRequiredParameterError{ParamName: paramName} + } return nil } default: diff --git a/examples/petstore-expanded/gin/server/server.gen.go b/examples/petstore-expanded/gin/server/server.gen.go index a2e4923..75f0400 100644 --- a/examples/petstore-expanded/gin/server/server.gen.go +++ b/examples/petstore-expanded/gin/server/server.gen.go @@ -456,6 +456,9 @@ func BindQueryParameter(paramName string, queryParams url.Values, dest any, opts var fieldsPresent bool fieldsPresent, err = bindParamsToExplodedObject(paramName, queryParams, output) if !fieldsPresent { + if opts.Required { + return &MissingRequiredParameterError{ParamName: paramName} + } return nil } default: diff --git a/examples/petstore-expanded/gorilla/server/server.gen.go b/examples/petstore-expanded/gorilla/server/server.gen.go index e5831bd..f375f9c 100644 --- a/examples/petstore-expanded/gorilla/server/server.gen.go +++ b/examples/petstore-expanded/gorilla/server/server.gen.go @@ -484,6 +484,9 @@ func BindQueryParameter(paramName string, queryParams url.Values, dest any, opts var fieldsPresent bool fieldsPresent, err = bindParamsToExplodedObject(paramName, queryParams, output) if !fieldsPresent { + if opts.Required { + return &MissingRequiredParameterError{ParamName: paramName} + } return nil } default: diff --git a/examples/petstore-expanded/iris/server/server.gen.go b/examples/petstore-expanded/iris/server/server.gen.go index 20379e5..1179169 100644 --- a/examples/petstore-expanded/iris/server/server.gen.go +++ b/examples/petstore-expanded/iris/server/server.gen.go @@ -422,6 +422,9 @@ func BindQueryParameter(paramName string, queryParams url.Values, dest any, opts var fieldsPresent bool fieldsPresent, err = bindParamsToExplodedObject(paramName, queryParams, output) if !fieldsPresent { + if opts.Required { + return &MissingRequiredParameterError{ParamName: paramName} + } return nil } default: diff --git a/examples/petstore-expanded/stdhttp/server/server.gen.go b/examples/petstore-expanded/stdhttp/server/server.gen.go index 3e104a4..8000c9d 100644 --- a/examples/petstore-expanded/stdhttp/server/server.gen.go +++ b/examples/petstore-expanded/stdhttp/server/server.gen.go @@ -484,6 +484,9 @@ func BindQueryParameter(paramName string, queryParams url.Values, dest any, opts var fieldsPresent bool fieldsPresent, err = bindParamsToExplodedObject(paramName, queryParams, output) if !fieldsPresent { + if opts.Required { + return &MissingRequiredParameterError{ParamName: paramName} + } return nil } default: diff --git a/runtime/params/params.gen.go b/runtime/params/params.gen.go index e63b8f7..eb8b68f 100644 --- a/runtime/params/params.gen.go +++ b/runtime/params/params.gen.go @@ -174,6 +174,9 @@ func BindQueryParameter(paramName string, queryParams url.Values, dest any, opts var fieldsPresent bool fieldsPresent, err = bindParamsToExplodedObject(paramName, queryParams, output) if !fieldsPresent { + if opts.Required { + return &MissingRequiredParameterError{ParamName: paramName} + } return nil } default: @@ -343,6 +346,9 @@ func BindRawQueryParameter(paramName string, rawQuery string, dest any, opts Par var fieldsPresent bool fieldsPresent, err = bindParamsToExplodedObject(paramName, queryParams, output) if !fieldsPresent { + if opts.Required { + return &MissingRequiredParameterError{ParamName: paramName} + } return nil } default: