mirror of
https://github.com/kataras/iris.git
synced 2025-03-21 22:16:28 +01:00
add 'Context.Register/RemoveDependency' for registering dependencies for next handler in the chain from a common iris handler in serve-time
And also, add a Configuration.FireEmptyFormError if end-dev wants to receive an iris.ErrEmptyForm error on missing form data on 'Context.ReadForm/ReadBody' Former-commit-id: a2713bec77375b2908f1f066a46be4f19e6b7a61
This commit is contained in:
parent
c0fd429a43
commit
c866709acc
|
@ -371,6 +371,8 @@ Other Improvements:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
- `Context.ReadForm` now can return an `iris.ErrEmptyForm` instead of `nil` when the new `Configuration.FireEmptyFormError` is true (or `iris.WithEmptyFormError`) on missing form body to read from.
|
||||||
|
|
||||||
- `Configuration.EnablePathIntelligence | iris.WithPathIntelligence` to enable path intelligence automatic path redirection on the most closest path (if any), [example]((https://github.com/kataras/iris/blob/master/_examples/routing/intelligence/main.go)
|
- `Configuration.EnablePathIntelligence | iris.WithPathIntelligence` to enable path intelligence automatic path redirection on the most closest path (if any), [example]((https://github.com/kataras/iris/blob/master/_examples/routing/intelligence/main.go)
|
||||||
|
|
||||||
- Enhanced cookie security and management through new `Context.AddCookieOptions` method and new cookie options (look on New Package-level functions section below), [securecookie](https://github.com/kataras/iris/tree/master/_examples/cookies/securecookie) example has been updated.
|
- Enhanced cookie security and management through new `Context.AddCookieOptions` method and new cookie options (look on New Package-level functions section below), [securecookie](https://github.com/kataras/iris/tree/master/_examples/cookies/securecookie) example has been updated.
|
||||||
|
@ -409,6 +411,7 @@ New Package-level Variables:
|
||||||
|
|
||||||
New Context Methods:
|
New Context Methods:
|
||||||
|
|
||||||
|
- `Context.RegisterDependency(v interface{})` and `Context.RemoveDependency(typ reflect.Type)` to register/remove struct dependencies on serve-time through a middleware.
|
||||||
- `Context.SetID(id interface{})` and `Context.GetID() interface{}` added to register a custom unique indetifier to the Context, if necessary.
|
- `Context.SetID(id interface{})` and `Context.GetID() interface{}` added to register a custom unique indetifier to the Context, if necessary.
|
||||||
- `Context.GetDomain() string` returns the domain.
|
- `Context.GetDomain() string` returns the domain.
|
||||||
- `Context.AddCookieOptions(...CookieOption)` adds options for `SetCookie`, `SetCookieKV, UpsertCookie` and `RemoveCookie` methods for the current request.
|
- `Context.AddCookieOptions(...CookieOption)` adds options for `SetCookie`, `SetCookieKV, UpsertCookie` and `RemoveCookie` methods for the current request.
|
||||||
|
|
|
@ -164,6 +164,7 @@
|
||||||
* [Middleware](dependency-injection/basic/middleware/main.go)
|
* [Middleware](dependency-injection/basic/middleware/main.go)
|
||||||
* [Sessions](dependency-injection/sessions/main.go)
|
* [Sessions](dependency-injection/sessions/main.go)
|
||||||
* [Smart Contract](dependency-injection/smart-contract/main.go)
|
* [Smart Contract](dependency-injection/smart-contract/main.go)
|
||||||
|
* [JWT](dependency-injection/jwt/main.go)
|
||||||
* MVC
|
* MVC
|
||||||
* [Overview - Repository and Service layers](mvc/overview)
|
* [Overview - Repository and Service layers](mvc/overview)
|
||||||
* [Login - Repository and Service layers](mvc/login)
|
* [Login - Repository and Service layers](mvc/login)
|
||||||
|
|
|
@ -37,10 +37,13 @@ func register(api *iris.APIContainer) {
|
||||||
// ctx.StopWithStatus(iris.StatusUnauthorized)
|
// ctx.StopWithStatus(iris.StatusUnauthorized)
|
||||||
// return nil
|
// return nil
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
// token := j.Get(ctx)
|
// token := j.Get(ctx)
|
||||||
// return token
|
// return token
|
||||||
// })
|
// })
|
||||||
|
// ^ You can do the same with MVC too, as the container is shared and works
|
||||||
|
// the same way in both functions-as-handlers and structs-as-controllers.
|
||||||
|
//
|
||||||
// api.Get("/", verifiedWithBindedTokenPage)
|
// api.Get("/", verifiedWithBindedTokenPage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -262,6 +262,13 @@ var WithoutBodyConsumptionOnUnmarshal = func(app *Application) {
|
||||||
app.config.DisableBodyConsumptionOnUnmarshal = true
|
app.config.DisableBodyConsumptionOnUnmarshal = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithEmptyFormError enables the setting `FireEmptyFormError`.
|
||||||
|
//
|
||||||
|
// See `Configuration`.
|
||||||
|
var WithEmptyFormError = func(app *Application) {
|
||||||
|
app.config.FireEmptyFormError = true
|
||||||
|
}
|
||||||
|
|
||||||
// WithoutAutoFireStatusCode disables the AutoFireStatusCode setting.
|
// WithoutAutoFireStatusCode disables the AutoFireStatusCode setting.
|
||||||
//
|
//
|
||||||
// See `Configuration`.
|
// See `Configuration`.
|
||||||
|
@ -837,6 +844,9 @@ type Configuration struct {
|
||||||
// The body will not be changed and existing data before the
|
// The body will not be changed and existing data before the
|
||||||
// context.UnmarshalBody/ReadJSON/ReadXML will be not consumed.
|
// context.UnmarshalBody/ReadJSON/ReadXML will be not consumed.
|
||||||
DisableBodyConsumptionOnUnmarshal bool `json:"disableBodyConsumptionOnUnmarshal,omitempty" yaml:"DisableBodyConsumptionOnUnmarshal" toml:"DisableBodyConsumptionOnUnmarshal"`
|
DisableBodyConsumptionOnUnmarshal bool `json:"disableBodyConsumptionOnUnmarshal,omitempty" yaml:"DisableBodyConsumptionOnUnmarshal" toml:"DisableBodyConsumptionOnUnmarshal"`
|
||||||
|
// FireEmptyFormError returns if set to tue true then the `context.ReadBody/ReadForm`
|
||||||
|
// will return an `iris.ErrEmptyForm` on empty request form data.
|
||||||
|
FireEmptyFormError bool `json:"fireEmptyFormError,omitempty" yaml:"FireEmptyFormError" yaml:"FireEmptyFormError"`
|
||||||
|
|
||||||
// DisableAutoFireStatusCode if true then it turns off the http error status code handler automatic execution
|
// DisableAutoFireStatusCode if true then it turns off the http error status code handler automatic execution
|
||||||
// from (`context.StatusCodeNotSuccessful`, defaults to < 200 || >= 400).
|
// from (`context.StatusCodeNotSuccessful`, defaults to < 200 || >= 400).
|
||||||
|
@ -1021,6 +1031,13 @@ func (c Configuration) GetDisableBodyConsumptionOnUnmarshal() bool {
|
||||||
return c.DisableBodyConsumptionOnUnmarshal
|
return c.DisableBodyConsumptionOnUnmarshal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetFireEmptyFormError returns the Configuration.FireEmptyFormError value.
|
||||||
|
// If true then the `context.ReadBody/ReadForm` will return an `iris.ErrEmptyForm`
|
||||||
|
// on empty request form data.
|
||||||
|
func (c Configuration) GetFireEmptyFormError() bool {
|
||||||
|
return c.DisableBodyConsumptionOnUnmarshal
|
||||||
|
}
|
||||||
|
|
||||||
// GetDisableAutoFireStatusCode returns the Configuration#DisableAutoFireStatusCode.
|
// GetDisableAutoFireStatusCode returns the Configuration#DisableAutoFireStatusCode.
|
||||||
// Returns true when the http error status code handler automatic execution turned off.
|
// Returns true when the http error status code handler automatic execution turned off.
|
||||||
func (c Configuration) GetDisableAutoFireStatusCode() bool {
|
func (c Configuration) GetDisableAutoFireStatusCode() bool {
|
||||||
|
@ -1190,6 +1207,10 @@ func WithConfiguration(c Configuration) Configurator {
|
||||||
main.DisableBodyConsumptionOnUnmarshal = v
|
main.DisableBodyConsumptionOnUnmarshal = v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v := c.FireEmptyFormError; v {
|
||||||
|
main.FireEmptyFormError = v
|
||||||
|
}
|
||||||
|
|
||||||
if v := c.DisableAutoFireStatusCode; v {
|
if v := c.DisableAutoFireStatusCode; v {
|
||||||
main.DisableAutoFireStatusCode = v
|
main.DisableAutoFireStatusCode = v
|
||||||
}
|
}
|
||||||
|
@ -1261,6 +1282,7 @@ func DefaultConfiguration() Configuration {
|
||||||
ForceLowercaseRouting: false,
|
ForceLowercaseRouting: false,
|
||||||
FireMethodNotAllowed: false,
|
FireMethodNotAllowed: false,
|
||||||
DisableBodyConsumptionOnUnmarshal: false,
|
DisableBodyConsumptionOnUnmarshal: false,
|
||||||
|
FireEmptyFormError: false,
|
||||||
DisableAutoFireStatusCode: false,
|
DisableAutoFireStatusCode: false,
|
||||||
TimeFormat: "Mon, 02 Jan 2006 15:04:05 GMT",
|
TimeFormat: "Mon, 02 Jan 2006 15:04:05 GMT",
|
||||||
Charset: "utf-8",
|
Charset: "utf-8",
|
||||||
|
|
|
@ -53,7 +53,10 @@ type ConfigurationReadOnly interface {
|
||||||
// The body will not be changed and existing data before the
|
// The body will not be changed and existing data before the
|
||||||
// context.UnmarshalBody/ReadJSON/ReadXML will be not consumed.
|
// context.UnmarshalBody/ReadJSON/ReadXML will be not consumed.
|
||||||
GetDisableBodyConsumptionOnUnmarshal() bool
|
GetDisableBodyConsumptionOnUnmarshal() bool
|
||||||
|
// GetFireEmptyFormError returns the Configuration.FireEmptyFormError value.
|
||||||
|
// If true then the `context.ReadBody/ReadForm` will return an `iris.ErrEmptyForm`
|
||||||
|
// on empty request form data.
|
||||||
|
GetFireEmptyFormError() bool
|
||||||
// GetDisableAutoFireStatusCode returns the configuration.DisableAutoFireStatusCode.
|
// GetDisableAutoFireStatusCode returns the configuration.DisableAutoFireStatusCode.
|
||||||
// Returns true when the http error status code handler automatic execution turned off.
|
// Returns true when the http error status code handler automatic execution turned off.
|
||||||
GetDisableAutoFireStatusCode() bool
|
GetDisableAutoFireStatusCode() bool
|
||||||
|
|
|
@ -662,6 +662,9 @@ type Context interface {
|
||||||
// It supports any kind of type, including custom structs.
|
// It supports any kind of type, including custom structs.
|
||||||
// It will return nothing if request data are empty.
|
// It will return nothing if request data are empty.
|
||||||
// The struct field tag is "form".
|
// The struct field tag is "form".
|
||||||
|
// Note that it will return nil error on empty form data if `Configuration.FireEmptyFormError`
|
||||||
|
// is false (as defaulted) in this case the caller should check the pointer to
|
||||||
|
// see if something was actually binded.
|
||||||
//
|
//
|
||||||
// Example: https://github.com/kataras/iris/blob/master/_examples/http_request/read-form/main.go
|
// Example: https://github.com/kataras/iris/blob/master/_examples/http_request/read-form/main.go
|
||||||
ReadForm(formObject interface{}) error
|
ReadForm(formObject interface{}) error
|
||||||
|
@ -1124,6 +1127,20 @@ type Context interface {
|
||||||
// Controller returns a reflect Value of the custom Controller from which this handler executed.
|
// Controller returns a reflect Value of the custom Controller from which this handler executed.
|
||||||
// It will return a Kind() == reflect.Invalid if the handler was not executed from within a controller.
|
// It will return a Kind() == reflect.Invalid if the handler was not executed from within a controller.
|
||||||
Controller() reflect.Value
|
Controller() reflect.Value
|
||||||
|
// RegisterDependency registers a struct dependency at serve-time
|
||||||
|
// for the next handler in the chain. One value per type.
|
||||||
|
// Note that it's highly recommended to register
|
||||||
|
// your dependencies before server ran
|
||||||
|
// through APIContainer(app.ConfigureContainer) or MVC(mvc.New)
|
||||||
|
// in sake of minimum performance cost.
|
||||||
|
//
|
||||||
|
// See `UnRegisterDependency` too.
|
||||||
|
RegisterDependency(v interface{})
|
||||||
|
// UnRegisterDependency removes a dependency based on its type.
|
||||||
|
// Reports whether a dependency with that type was found and removed successfully.
|
||||||
|
//
|
||||||
|
// See `RegisterDependency` too.
|
||||||
|
UnRegisterDependency(typ reflect.Type) bool
|
||||||
|
|
||||||
// Application returns the iris app instance which belongs to this context.
|
// Application returns the iris app instance which belongs to this context.
|
||||||
// Worth to notice that this function returns an interface
|
// Worth to notice that this function returns an interface
|
||||||
|
@ -2890,15 +2907,25 @@ func (ctx *context) ReadYAML(outPtr interface{}) error {
|
||||||
// A shortcut for the `schema#IsErrPath`.
|
// A shortcut for the `schema#IsErrPath`.
|
||||||
var IsErrPath = schema.IsErrPath
|
var IsErrPath = schema.IsErrPath
|
||||||
|
|
||||||
|
// ErrEmptyForm is returned by `context#ReadForm` and `context#ReadBody`
|
||||||
|
// when it should read data from a request form data but there is none.
|
||||||
|
var ErrEmptyForm = errors.New("empty form")
|
||||||
|
|
||||||
// ReadForm binds the request body of a form to the "formObject".
|
// ReadForm binds the request body of a form to the "formObject".
|
||||||
// It supports any kind of type, including custom structs.
|
// It supports any kind of type, including custom structs.
|
||||||
// It will return nothing if request data are empty.
|
// It will return nothing if request data are empty.
|
||||||
// The struct field tag is "form".
|
// The struct field tag is "form".
|
||||||
|
// Note that it will return nil error on empty form data if `Configuration.FireEmptyFormError`
|
||||||
|
// is false (as defaulted) in this case the caller should check the pointer to
|
||||||
|
// see if something was actually binded.
|
||||||
//
|
//
|
||||||
// Example: https://github.com/kataras/iris/blob/master/_examples/http_request/read-form/main.go
|
// Example: https://github.com/kataras/iris/blob/master/_examples/http_request/read-form/main.go
|
||||||
func (ctx *context) ReadForm(formObject interface{}) error {
|
func (ctx *context) ReadForm(formObject interface{}) error {
|
||||||
values := ctx.FormValues()
|
values := ctx.FormValues()
|
||||||
if len(values) == 0 {
|
if len(values) == 0 {
|
||||||
|
if ctx.Application().ConfigurationReadOnly().GetFireEmptyFormError() {
|
||||||
|
return ErrEmptyForm
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2984,6 +3011,7 @@ func (ctx *context) ReadBody(ptr interface{}) error {
|
||||||
// try read from query.
|
// try read from query.
|
||||||
return ctx.ReadQuery(ptr)
|
return ctx.ReadQuery(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise default to JSON.
|
// otherwise default to JSON.
|
||||||
return ctx.ReadJSON(ptr)
|
return ctx.ReadJSON(ptr)
|
||||||
}
|
}
|
||||||
|
@ -5424,6 +5452,61 @@ func (ctx *context) Controller() reflect.Value {
|
||||||
return emptyValue
|
return emptyValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DependenciesContextKey is the context key for the context's value
|
||||||
|
// to keep the serve-time static dependencies raw values.
|
||||||
|
const DependenciesContextKey = "iris.dependencies"
|
||||||
|
|
||||||
|
// DependenciesMap is the type which context serve-time
|
||||||
|
// struct dependencies are stored with.
|
||||||
|
type DependenciesMap map[reflect.Type]reflect.Value
|
||||||
|
|
||||||
|
// RegisterDependency registers a struct dependency at serve-time
|
||||||
|
// for the next handler in the chain. One value per type.
|
||||||
|
// Note that it's highly recommended to register
|
||||||
|
// your dependencies before server ran
|
||||||
|
// through APIContainer(app.ConfigureContainer) or MVC(mvc.New)
|
||||||
|
// in sake of minimum performance cost.
|
||||||
|
func (ctx *context) RegisterDependency(v interface{}) {
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val, ok := v.(reflect.Value)
|
||||||
|
if !ok {
|
||||||
|
val = reflect.ValueOf(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
cv := ctx.Values().Get(DependenciesContextKey)
|
||||||
|
if cv != nil {
|
||||||
|
m, ok := cv.(DependenciesMap)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
m[val.Type()] = val
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Values().Set(DependenciesContextKey, DependenciesMap{
|
||||||
|
val.Type(): val,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnRegisterDependency removes a dependency based on its type.
|
||||||
|
// Reports whether a dependency with that type was found and removed successfully.
|
||||||
|
func (ctx *context) UnRegisterDependency(typ reflect.Type) bool {
|
||||||
|
cv := ctx.Values().Get(DependenciesContextKey)
|
||||||
|
if cv != nil {
|
||||||
|
m, ok := cv.(DependenciesMap)
|
||||||
|
if ok {
|
||||||
|
delete(m, typ)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// Application returns the iris app instance which belongs to this context.
|
// Application returns the iris app instance which belongs to this context.
|
||||||
// Worth to notice that this function returns an interface
|
// Worth to notice that this function returns an interface
|
||||||
// of the Application, which contains methods that are safe
|
// of the Application, which contains methods that are safe
|
||||||
|
|
|
@ -323,6 +323,14 @@ func payloadBinding(index int, typ reflect.Type) *binding {
|
||||||
Handle: func(ctx context.Context, input *Input) (newValue reflect.Value, err error) {
|
Handle: func(ctx context.Context, input *Input) (newValue reflect.Value, err error) {
|
||||||
wasPtr := input.Type.Kind() == reflect.Ptr
|
wasPtr := input.Type.Kind() == reflect.Ptr
|
||||||
|
|
||||||
|
if serveDepsV := ctx.Values().Get(context.DependenciesContextKey); serveDepsV != nil {
|
||||||
|
if serveDeps, ok := serveDepsV.(context.DependenciesMap); ok {
|
||||||
|
if newValue, ok = serveDeps[typ]; ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
newValue = reflect.New(indirectType(input.Type))
|
newValue = reflect.New(indirectType(input.Type))
|
||||||
ptr := newValue.Interface()
|
ptr := newValue.Interface()
|
||||||
err = ctx.ReadBody(ptr)
|
err = ctx.ReadBody(ptr)
|
||||||
|
|
|
@ -75,7 +75,8 @@ func makeHandler(fn interface{}, c *Container, paramsCount int) context.Handler
|
||||||
}
|
}
|
||||||
|
|
||||||
v := valueOf(fn)
|
v := valueOf(fn)
|
||||||
numIn := v.Type().NumIn()
|
typ := v.Type()
|
||||||
|
numIn := typ.NumIn()
|
||||||
|
|
||||||
bindings := getBindingsForFunc(v, c.Dependencies, paramsCount)
|
bindings := getBindingsForFunc(v, c.Dependencies, paramsCount)
|
||||||
|
|
||||||
|
|
|
@ -129,17 +129,18 @@ func TestBindFunctionAsFunctionInputArgument(t *testing.T) {
|
||||||
func TestPayloadBinding(t *testing.T) {
|
func TestPayloadBinding(t *testing.T) {
|
||||||
h := New()
|
h := New()
|
||||||
|
|
||||||
postHandler := h.Handler(func(input *testUserStruct /* ptr */) string {
|
ptrHandler := h.Handler(func(input *testUserStruct /* ptr */) string {
|
||||||
return input.Username
|
return input.Username
|
||||||
})
|
})
|
||||||
|
|
||||||
postHandler2 := h.Handler(func(input testUserStruct) string {
|
valHandler := h.Handler(func(input testUserStruct) string {
|
||||||
return input.Username
|
return input.Username
|
||||||
})
|
})
|
||||||
|
|
||||||
app := iris.New()
|
app := iris.New()
|
||||||
app.Post("/", postHandler)
|
app.Get("/", ptrHandler)
|
||||||
app.Post("/2", postHandler2)
|
app.Post("/", ptrHandler)
|
||||||
|
app.Post("/2", valHandler)
|
||||||
|
|
||||||
e := httptest.New(t, app)
|
e := httptest.New(t, app)
|
||||||
|
|
||||||
|
@ -152,8 +153,10 @@ func TestPayloadBinding(t *testing.T) {
|
||||||
// FORM (multipart)
|
// FORM (multipart)
|
||||||
e.POST("/").WithMultipart().WithFormField("username", "makis").Expect().Status(httptest.StatusOK).Body().Equal("makis")
|
e.POST("/").WithMultipart().WithFormField("username", "makis").Expect().Status(httptest.StatusOK).Body().Equal("makis")
|
||||||
|
|
||||||
// URL query.
|
// POST URL query.
|
||||||
e.POST("/").WithQuery("username", "makis").Expect().Status(httptest.StatusOK).Body().Equal("makis")
|
e.POST("/").WithQuery("username", "makis").Expect().Status(httptest.StatusOK).Body().Equal("makis")
|
||||||
|
// GET URL query.
|
||||||
|
e.GET("/").WithQuery("username", "makis").Expect().Status(httptest.StatusOK).Body().Equal("makis")
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Author's notes:
|
/* Author's notes:
|
||||||
|
@ -241,3 +244,44 @@ func TestHandlerPathParams(t *testing.T) {
|
||||||
testReq.Expect().Status(httptest.StatusOK).Body().Equal("42")
|
testReq.Expect().Status(httptest.StatusOK).Body().Equal("42")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRegisterDependenciesFromContext(t *testing.T) {
|
||||||
|
// Tests serve-time struct dependencies through a common Iris middleware.
|
||||||
|
app := iris.New()
|
||||||
|
app.Use(func(ctx iris.Context) {
|
||||||
|
ctx.RegisterDependency(testUserStruct{Username: "kataras"})
|
||||||
|
ctx.Next()
|
||||||
|
})
|
||||||
|
app.Use(func(ctx iris.Context) {
|
||||||
|
ctx.RegisterDependency(&testServiceImpl{prefix: "say"})
|
||||||
|
ctx.Next()
|
||||||
|
})
|
||||||
|
|
||||||
|
app.ConfigureContainer(func(api *iris.APIContainer) {
|
||||||
|
api.Get("/", func(u testUserStruct) string {
|
||||||
|
return u.Username
|
||||||
|
})
|
||||||
|
|
||||||
|
api.Get("/service", func(s *testServiceImpl) string {
|
||||||
|
return s.Say("hello")
|
||||||
|
})
|
||||||
|
|
||||||
|
// Note: we are not allowed to pass the service as an interface here
|
||||||
|
// because the container will, correctly, panic because it will expect
|
||||||
|
// a dependency to be registered before server ran.
|
||||||
|
api.Get("/both", func(s *testServiceImpl, u testUserStruct) string {
|
||||||
|
return s.Say(u.Username)
|
||||||
|
})
|
||||||
|
|
||||||
|
api.Get("/non", func() string {
|
||||||
|
return "nothing"
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
e := httptest.New(t, app)
|
||||||
|
|
||||||
|
e.GET("/").Expect().Status(httptest.StatusOK).Body().Equal("kataras")
|
||||||
|
e.GET("/service").Expect().Status(httptest.StatusOK).Body().Equal("say hello")
|
||||||
|
e.GET("/both").Expect().Status(httptest.StatusOK).Body().Equal("say kataras")
|
||||||
|
e.GET("/non").Expect().Status(httptest.StatusOK).Body().Equal("nothing")
|
||||||
|
}
|
||||||
|
|
5
iris.go
5
iris.go
|
@ -575,6 +575,11 @@ var (
|
||||||
//
|
//
|
||||||
// A shortcut for the `context#IsErrPath`.
|
// A shortcut for the `context#IsErrPath`.
|
||||||
IsErrPath = context.IsErrPath
|
IsErrPath = context.IsErrPath
|
||||||
|
// ErrEmptyForm is the type error which API users can make use of
|
||||||
|
// to check if a form was empty on `Context.ReadForm`.
|
||||||
|
//
|
||||||
|
// A shortcut for the `context#ErrEmptyForm`.
|
||||||
|
ErrEmptyForm = context.ErrEmptyForm
|
||||||
// NewProblem returns a new Problem.
|
// NewProblem returns a new Problem.
|
||||||
// Head over to the `Problem` type godoc for more.
|
// Head over to the `Problem` type godoc for more.
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in New Issue
Block a user