Interceptors
An interceptor pattern is offers a way to change, or augment, their usual processing cycle. Key aspects of the pattern are that, the change is transparent and used automatically.
aah framework provides per Controller
and per Action
level. It is very good spot for performing Authorization check
, if its satisfies move on otherwise call Context.Abort()
to stop the flow.
In the order of execution/calling in the request life cycle-
Before()
- Always called if presentBefore<ActionName>()
- Always called if present, exceptpanic()
,Context.Abort()
- Controller action gets called
After<ActionName>()
- Always called if present, exceptpanic()
,Context.Abort()
After()
- Always called if present, exceptpanic()
,Context.Abort()
Panic<ActionName>(r interface{})
- Always called if present in the event ofpanic
Panic(r interface{})
- Always called if present in the event ofpanic
, exceptPanic<ActionName>(...)
not exists, it propagates to framework.Finally<ActionName>()
- Always called if present.Finally()
- Always called if present.
Note
Panic
interceptors method has a parameter.- If
Context.Abort()
is called, subsequent interceptors and TargetedAction
won’t be called. Control goes to framework.- Let’s say you do some logic check and call
Abort()
in the interceptorBefore()
the remaining request life cycle skipped and control goes to framework. - Let’s say you call
Abort()
in the Targeted Action then remaining request life cycle skipped and control goes to framework.
- Let’s say you do some logic check and call
Example
// UserController implementation.
type UserController struct {
*aah.Context
}
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// Controller Level Interceptors
//___________________________________
// Before is called for every action in the Controller
func (u *UserController) Before() {
log.Info("UserController before interceptor called")
}
// After is called for every action in the Controller
func (u *UserController) After() {
log.Info("UserController after interceptor called")
}
// Finally is called for every action in the Controller except `Context.Abort()`
func (u *UserController) Finally() {
log.Info("UserController finally interceptor called")
}
// Panic is called for every action in the Controller except `Context.Abort()`,
// if action level Panic interceptor present
// Note: Panic interceptor has parameter
func (u *UserController) Panic(r interface{}) {
log.Info("UserController panic interceptor called")
}
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// Actions
//___________________________________
// Login action is for performing login.
func (u *UserController) Login() {
log.Info("UserController login action called")
}
// Logout action is for performing logout
func (u *UserController) Logout() {
log.Info("UserController logout action called")
}
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// Controller Action Level Interceptors
//
// just couple of example.
//_____________________________________
// BeforeLogin is called for before `Login` action
func (u *UserController) BeforeLogin() {
log.Info("UserController login before action interceptor called")
}
// AfterLogout is called after `Logout` action
func (u *UserController) AfterLogout() {
log.Info("UserController logout after action interceptor called")
}