feat(core/handlers): improve handlers registration DevX (#22007)
This commit is contained in:
parent
a0f96930ab
commit
a3729c1ad6
@ -10,8 +10,8 @@ import (
|
||||
type (
|
||||
// PreMsgHandler is a handler that is executed before Handler. If it errors the execution reverts.
|
||||
PreMsgHandler = func(ctx context.Context, msg transaction.Msg) error
|
||||
// Handler handles the state transition of the provided message.
|
||||
Handler = func(ctx context.Context, msg transaction.Msg) (msgResp transaction.Msg, err error)
|
||||
// HandlerFunc handles the state transition of the provided message.
|
||||
HandlerFunc = func(ctx context.Context, msg transaction.Msg) (msgResp transaction.Msg, err error)
|
||||
// PostMsgHandler runs after Handler, only if Handler does not error. If PostMsgHandler errors
|
||||
// then the execution is reverted.
|
||||
PostMsgHandler = func(ctx context.Context, msg, msgResp transaction.Msg) error
|
||||
@ -19,10 +19,10 @@ type (
|
||||
|
||||
// PreMsgRouter is a router that allows you to register PreMsgHandlers for specific message types.
|
||||
type PreMsgRouter interface {
|
||||
// RegisterPreHandler will register a specific message handler hooking into the message with
|
||||
// RegisterPreMsgHandler will register a specific message handler hooking into the message with
|
||||
// the provided name.
|
||||
RegisterPreMsgHandler(msgName string, handler PreMsgHandler)
|
||||
// RegisterGlobalPreHandler will register a global message handler hooking into any message
|
||||
// RegisterGlobalPreMsgHandler will register a global message handler hooking into any message
|
||||
// being executed.
|
||||
RegisterGlobalPreMsgHandler(handler PreMsgHandler)
|
||||
}
|
||||
@ -64,10 +64,10 @@ func RegisterMsgPreHandler[Req transaction.Msg](
|
||||
|
||||
// PostMsgRouter is a router that allows you to register PostMsgHandlers for specific message types.
|
||||
type PostMsgRouter interface {
|
||||
// RegisterPostHandler will register a specific message handler hooking after the execution of message with
|
||||
// RegisterPostMsgHandler will register a specific message handler hooking after the execution of message with
|
||||
// the provided name.
|
||||
RegisterPostMsgHandler(msgName string, handler PostMsgHandler)
|
||||
// RegisterGlobalPostHandler will register a global message handler hooking after the execution of any message.
|
||||
// RegisterGlobalPostMsgHandler will register a global message handler hooking after the execution of any message.
|
||||
RegisterGlobalPostMsgHandler(handler PostMsgHandler)
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ type HasPostMsgHandlers interface {
|
||||
RegisterPostMsgHandlers(router PostMsgRouter)
|
||||
}
|
||||
|
||||
// RegisterPostHandler is a helper function that modules can use to not lose type safety when registering handlers to the
|
||||
// RegisterPostMsgHandler is a helper function that modules can use to not lose type safety when registering handlers to the
|
||||
// PostMsgRouter. Example usage:
|
||||
// ```go
|
||||
//
|
||||
@ -110,9 +110,20 @@ func RegisterPostMsgHandler[Req, Resp transaction.Msg](
|
||||
router.RegisterPostMsgHandler(msgName, untypedHandler)
|
||||
}
|
||||
|
||||
// Handler defines a handler descriptor.
|
||||
type Handler struct {
|
||||
// Func defines the actual handler, the function that runs a request and returns a response.
|
||||
// Can be query handler or msg handler.
|
||||
Func HandlerFunc
|
||||
// MakeMsg instantiates the type of the request, can be used in decoding contexts.
|
||||
MakeMsg func() transaction.Msg
|
||||
// MakeMsgResp instantiates a new response, can be used in decoding contexts.
|
||||
MakeMsgResp func() transaction.Msg
|
||||
}
|
||||
|
||||
// MsgRouter is a router that allows you to register Handlers for specific message types.
|
||||
type MsgRouter = interface {
|
||||
RegisterHandler(msgName string, handler Handler) error
|
||||
RegisterHandler(handler Handler)
|
||||
}
|
||||
|
||||
// HasMsgHandlers is an interface that modules must implement if they want to register Handlers.
|
||||
@ -142,27 +153,34 @@ type HasQueryHandlers interface {
|
||||
//
|
||||
// func (m Module) RegisterMsgHandlers(router appmodule.MsgRouter) {
|
||||
// handlers := keeper.NewHandlers(m.keeper)
|
||||
// err := appmodule.RegisterHandler(router, gogoproto.MessageName(types.MsgMint{}), handlers.MsgMint)
|
||||
// err := appmodule.RegisterHandler(router, handlers.MsgMint)
|
||||
// }
|
||||
//
|
||||
// func (m Module) RegisterQueryHandlers(router appmodule.QueryRouter) {
|
||||
// handlers := keeper.NewHandlers(m.keeper)
|
||||
// err := appmodule.RegisterHandler(router, gogoproto.MessageName(types.QueryBalanceRequest{}), handlers.QueryBalance)
|
||||
// err := appmodule.RegisterHandler(router, handlers.QueryBalance)
|
||||
// }
|
||||
//
|
||||
// ```
|
||||
func RegisterHandler[Req, Resp transaction.Msg](
|
||||
func RegisterMsgHandler[Req, Resp any, PReq transaction.GenericMsg[Req], PResp transaction.GenericMsg[Resp]](
|
||||
router MsgRouter,
|
||||
msgName string,
|
||||
handler func(ctx context.Context, msg Req) (msgResp Resp, err error),
|
||||
) error {
|
||||
handler func(ctx context.Context, msg PReq) (msgResp PResp, err error),
|
||||
) {
|
||||
untypedHandler := func(ctx context.Context, m transaction.Msg) (transaction.Msg, error) {
|
||||
typed, ok := m.(Req)
|
||||
typed, ok := m.(PReq)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type %T, wanted: %T", m, *new(Req))
|
||||
}
|
||||
return handler(ctx, typed)
|
||||
}
|
||||
|
||||
return router.RegisterHandler(msgName, untypedHandler)
|
||||
router.RegisterHandler(Handler{
|
||||
Func: untypedHandler,
|
||||
MakeMsg: func() transaction.Msg {
|
||||
return PReq(new(Req))
|
||||
},
|
||||
MakeMsgResp: func() transaction.Msg {
|
||||
return PResp(new(Resp))
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@ -10,6 +10,14 @@ type (
|
||||
Identity = []byte
|
||||
)
|
||||
|
||||
// GenericMsg defines a generic version of a Msg.
|
||||
// The GenericMsg refers to the non pointer version of Msg,
|
||||
// and is required to allow its instantiations in generic contexts.
|
||||
type GenericMsg[T any] interface {
|
||||
*T
|
||||
Msg
|
||||
}
|
||||
|
||||
// Codec defines the TX codec, which converts a TX from bytes to its concrete representation.
|
||||
type Codec[T Tx] interface {
|
||||
// Decode decodes the tx bytes into a DecodedTx, containing
|
||||
|
||||
@ -5,7 +5,7 @@ go 1.23.1
|
||||
require (
|
||||
cosmossdk.io/api v0.7.6
|
||||
cosmossdk.io/client/v2 v2.0.0-00010101000000-000000000000
|
||||
cosmossdk.io/core v1.0.0-alpha.3
|
||||
cosmossdk.io/core v1.0.0-alpha.3.0.20241001182821-3f9c9a087760
|
||||
cosmossdk.io/depinject v1.0.0
|
||||
cosmossdk.io/log v1.4.1
|
||||
cosmossdk.io/math v1.3.0
|
||||
@ -291,7 +291,6 @@ replace (
|
||||
// server v2 integration
|
||||
replace (
|
||||
cosmossdk.io/api => ../../api
|
||||
cosmossdk.io/core => ../../core
|
||||
cosmossdk.io/runtime/v2 => ../../runtime/v2
|
||||
cosmossdk.io/server/v2 => ../../server/v2
|
||||
cosmossdk.io/server/v2/appmanager => ../../server/v2/appmanager
|
||||
|
||||
@ -192,6 +192,8 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX
|
||||
cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg=
|
||||
cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0=
|
||||
cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
|
||||
cosmossdk.io/core v1.0.0-alpha.3.0.20241001182821-3f9c9a087760 h1:jyldjo99XdhT94cIyoSVBT2hxNoI4X/1pEUh4+659e0=
|
||||
cosmossdk.io/core v1.0.0-alpha.3.0.20241001182821-3f9c9a087760/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY=
|
||||
cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY=
|
||||
cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs=
|
||||
cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050=
|
||||
|
||||
Loading…
Reference in New Issue
Block a user