Feat: Enhance service method retrieval and invocation features#1429
Feat: Enhance service method retrieval and invocation features#1429Similarityoung wants to merge 10 commits intoapache:developfrom
Conversation
…ovider app name in ServiceMethodsReq
There was a problem hiding this comment.
Pull request overview
This PR adds service method introspection endpoints and a metadata-driven generic invocation flow to the Dubbo Admin console, shifting generic invoke parameter type resolution from client input to provider metadata.
Changes:
- Added console APIs for listing service methods, fetching method details (including signature/types closure), and performing generic invoke.
- Implemented provider-metadata-based overload resolution via
methodName + signatureand refactored generic invoke argument decoding using[]json.RawMessage. - Updated ZK node creation flag usage and bumped/adjusted Go module dependencies to support the new generic invoke implementation.
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/governor/zk/governor.go | Adjusts ZK node creation flags for compatibility. |
| pkg/console/service/service_generic_invoke_decode.go | Adds typed argument decoding helpers for generic invoke based on resolved parameter types. |
| pkg/console/service/service_generic_invoke.go | Implements generic invoke flow: metadata lookup, overload resolution, target selection, and RPC invocation. |
| pkg/console/service/service.go | Adds provider-metadata-backed method discovery and method detail/type-closure building. |
| pkg/console/router/router.go | Registers new service routes for methods, method detail, and generic invoke under /api/v1/service. |
| pkg/console/model/service.go | Adds request/response models for method discovery, method detail, and generic invoke (including signature and raw args). |
| pkg/console/handler/service.go | Adds handlers wiring the new endpoints to service layer functions. |
| go.mod | Updates dubbo-go dependency and adds hessian2 + other indirects needed for new invoke path. |
| go.sum | Updates dependency checksums accordingly. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| var invokeGenericServiceRPC = func(callCtx context.Context, invocation genericInvocation) (any, error) { | ||
| ins, err := dubbo.NewInstance(dubbo.WithName(genericInvokeInstanceName)) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| cli, err := ins.NewClient( | ||
| client.WithClientProtocolTriple(), | ||
| client.WithClientSerialization(dubboconstant.Hessian2Serialization), | ||
| ) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| svc, err := cli.NewGenericService( | ||
| invocation.ServiceName, | ||
| client.WithURL(invocation.URL), | ||
| client.WithVersion(invocation.Version), | ||
| client.WithGroup(invocation.Group), | ||
| ) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| return svc.Invoke(callCtx, invocation.MethodName, invocation.ParameterTypes, invocation.Args) | ||
| } |
There was a problem hiding this comment.
invokeGenericServiceRPC creates a new Dubbo instance + client + generic service on every invocation. This is likely expensive and may also accumulate background resources (connections, goroutines) depending on the dubbo-go implementation. Consider initializing and reusing a singleton instance/client (and, if possible, a cached generic service per service/version/group) with proper lifecycle management instead of rebuilding everything per request.
There was a problem hiding this comment.
Optimization can be made in the future
There was a problem hiding this comment.
copilot这里说的有道理,这里可以在代码里记一个todo,加上client的缓存
Code reviewFound 1 issue:
dubbo-admin/pkg/console/service/service_generic_invoke.go Lines 148 to 152 in c04698c 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
…rameter count validation
…viceGeneric in ServiceGenericInvoke
robocanic
left a comment
There was a problem hiding this comment.
Great Work! I left some comments and hope you can discuss them with me.
| } | ||
|
|
||
| func (s *ServiceGenericInvokeReq) Validate() error { | ||
| s.Mesh = strings.TrimSpace(s.Mesh) |
There was a problem hiding this comment.
suggestrion: 这里都可以简化用lancet的工具类strutil.isBlank来判断
| return filtered, nil | ||
| } | ||
|
|
||
| func matchesServiceMethodsReq(metadata *meshresource.ServiceProviderMetadataResource, req model.ServiceMethodsReq) bool { |
There was a problem hiding this comment.
Suggestion:这里的过滤其实可以在查询DB的时候做掉。可以在ServiceProviderMetadata的index(pkg/core/store/index/service_provider_metadata.go)里面新增对于serviceKey(serviceName:version:group)的一个索引,这样就不用在上层过滤了。
| } | ||
| } | ||
|
|
||
| for methodName := range fallbackMethodNames { |
There was a problem hiding this comment.
Question:这段逻辑有点没看懂,可以写写注释
There was a problem hiding this comment.
当前实现会优先使用 Spec.Methods 里的结构化定义;只有当结构化方法信息缺失时,才退回到 parameters["methods"] 里提取方法名做兜底展示,避免 fallback 覆盖掉更完整的签名/参数类型信息。
| return nil, err | ||
| } | ||
|
|
||
| cli, err := ins.NewClient( |
There was a problem hiding this comment.
Question:这里是不是应该根据目标service的协议和序列化来new client?
There was a problem hiding this comment.
这里其他协议我还没做测试,我记得序列化好像只有 Hessian2,我回头看看。
| var invokeGenericServiceRPC = func(callCtx context.Context, invocation genericInvocation) (any, error) { | ||
| ins, err := dubbo.NewInstance(dubbo.WithName(genericInvokeInstanceName)) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| cli, err := ins.NewClient( | ||
| client.WithClientProtocolTriple(), | ||
| client.WithClientSerialization(dubboconstant.Hessian2Serialization), | ||
| ) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| svc, err := cli.NewGenericService( | ||
| invocation.ServiceName, | ||
| client.WithURL(invocation.URL), | ||
| client.WithVersion(invocation.Version), | ||
| client.WithGroup(invocation.Group), | ||
| ) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| return svc.Invoke(callCtx, invocation.MethodName, invocation.ParameterTypes, invocation.Args) | ||
| } |
There was a problem hiding this comment.
copilot这里说的有道理,这里可以在代码里记一个todo,加上client的缓存
…enhance service provider metadata indexing
|



Description
This PR adds structured service method introspection and generic invoke capabilities to Dubbo Admin console, and tightens the generic invoke contract to rely on provider metadata instead of client-supplied parameter types.
What changed
Added console APIs for service method discovery:
GET /api/v1/service/methodsGET /api/v1/service/method/detailPOST /api/v1/service/generic/invokeExtended method detail response to include:
signaturemethod-related
typesclosure derived from provider metadataChanged generic invoke request contract:
removed client-provided
parameterTypesadded
signaturebackend now resolves authoritative
parameterTypesfrom provider metadata byservice + methodName + signatureAdded stricter overload handling:
if
signatureis omitted and the method is overloaded, returnInvalidArgumentif only fallback metadata exists without structured
Methods/Types, return a clear error instead of guessingRefactored generic invoke argument decoding:
switched request
argsto[]json.RawMessagedecode values after metadata resolution based on target parameter types
supports numeric primitives, primitive arrays, object arrays, JVM array descriptors, and
charIncluded a small ZK governor compatibility fix when creating nodes
To help us figure out who should review this PR, please put an X in all the areas that this PR affects.
Docs
Installation
User Experience
Dubboctl
Console
Core Component