Skip to content

feat(resolution): index GoFrame g.Meta routes, link to controller methods (#747)#803

Open
maxmilian wants to merge 1 commit into
colbymchenry:mainfrom
maxmilian:fix/747-goframe-routes
Open

feat(resolution): index GoFrame g.Meta routes, link to controller methods (#747)#803
maxmilian wants to merge 1 commit into
colbymchenry:mainfrom
maxmilian:fix/747-goframe-routes

Conversation

@maxmilian

Copy link
Copy Markdown
Contributor

Follow-up to #720 (suggestion #3 — structural route coverage, distinct from the ranking fix). Closes #747.

Why

GoFrame binds routes reflectively, so there's no literal /chat string and no call edge from path → controller method:

// api/chat/v1/chat.go — the route lives in a struct tag on the request type
type ChatReq struct {
	g.Meta `path:"/chat" method:"post"`
	Content string `json:"content"`
}
// the handler is the controller method named after the request type (ChatReq -> Chat)
func (c *ControllerV1) Chat(ctx context.Context, req *v1.ChatReq) (*v1.ChatRes, error) { ... }

Today "where is this route registered / which method handles it" can only be answered lexically — route-registration symbols have nothing to win on.

What

Extend goResolver.extract (src/resolution/frameworks/go.ts) with a GoFrame pass:

  • read the g.Meta struct tag (path: + method:, defaulting to ANY when method: is absent) → a route node, identical in shape to the existing Gin/mux route nodes, and
  • link that route to the controller method by GoFrame's naming convention (request type with the Req suffix dropped, ChatReqChat) via a references edge — same shape as the existing route→handler edges.

The route node and its method edge are emitted together: a g.Meta whose type doesn't follow the …Req convention (or has no path:) is skipped rather than left as an orphan route node, per the "partial coverage is worse than none" guidance.

Scope / follow-ups (intentional)

  • Relative path only. Only the path: from the tag is captured (/chat), not the s.Group("/api", …) prefix that GoFrame prepends. The route node + method edge are still complete and useful; joining the group prefix (cross-file) is a clean follow-up.
  • Method resolution. The route→method references edge resolves through the same name-resolution path as the existing Gin/mux route handlers. There's no GoFrame-specific resolve() pattern, so a method name resolves like any PascalCase ref; a dedicated method-kind resolution pattern is possible follow-up hardening (same risk profile as today's route-handler refs).

Tests

Two unit cases added to goResolver.extract in __tests__/frameworks.test.ts (mirroring the existing Gin/mux/Rust route-extraction tests): g.Meta with method:"post"POST /chat + Chat edge; method-less g.MetaANY /list + List edge. Both assert the edge binds to the route node id.

Validation

  • npm run build — clean (tsc).
  • npx vitest run __tests__/frameworks.test.ts96 passed, no existing route tests broken.
  • Verifiable with pure inline-Go string fixtures (the resolver is regex-over-source) — no Go toolchain needed; happy to also run the real small/medium/large GoFrame-repo validation from codegraph/CLAUDE.md if you want it in the PR.

…hods (colbymchenry#747)

GoFrame binds routes reflectively — the path/method live in a g.Meta
struct tag on the request type, and the handler is the controller method
named after that type with the Req suffix dropped (ChatReq -> Chat). So
there was no literal route string and no call edge: route questions could
only be answered lexically.

Extend goResolver.extract to read the g.Meta tag (path: + method:,
defaulting to ANY when method is absent) into a route node and link it to
the controller method by the naming convention. Route node and its
method edge are emitted together — a g.Meta whose type doesn't follow the
…Req convention is skipped rather than left as an orphan route node.

Only the relative path: from the tag is captured; joining the
s.Group("/api", …) prefix is left to a follow-up.

Follow-up to colbymchenry#720 (structural coverage, distinct from the ranking fix).
@maxmilian maxmilian marked this pull request as ready for review June 11, 2026 16:13
@psandeep02

Copy link
Copy Markdown

Code Review
This pull request is a valuable enhancement that improves CodeGraph's support for the GoFrame framework by indexing g.Meta routes and linking them directly to controller methods.
Strengths
Clearly addresses a real limitation where GoFrame routes are defined through struct tags rather than explicit route registration.
Route extraction logic is straightforward and aligns with existing Gin/mux route node behavior, maintaining consistency across frameworks.
Sensible handling of missing method tags by defaulting to ANY.
The controller-method linking strategy (ChatReq → Chat) follows GoFrame conventions and creates useful navigation edges without introducing framework-specific complexity.
Good decision to skip unsupported or incomplete g.Meta definitions instead of creating orphaned route nodes.
Unit tests cover both explicit-method and method-less scenarios and verify route-to-handler edge binding.
Validation results indicate no regressions in existing route extraction functionality.
Suggestions
Consider documenting any edge cases where request types do not follow the standard Req naming convention.
Future enhancement could resolve route group prefixes (g.Group) to generate fully qualified routes.
Additional tests for nested packages and uncommon controller naming patterns may further improve robustness.
Overall Assessment
Approve. The implementation is focused, well-tested, consistent with existing architecture, and provides meaningful support for GoFrame applications without adding unnecessary complexity. The scope is appropriately limited, and the follow-up items are clearly identified for future improvements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Go] Index GoFrame route metadata (g.Meta path: + RouterGroup.Bind) as route→method edges (follow-up to #720)

2 participants