Repository navigation
Replies: 1 comment
|
Thank you for the concrete public example and the careful distinction between declared static relationships, extracted edges, and runtime traces. That makes the proposal much easier to evaluate. The declared-link format and how it coexists with extracted GraphQL keys still need a maintainer design decision; this reply is not approval of a new format or a request to build the prototype. The example already supplies useful detail for that decision. |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
In #1568 you asked for a small public example of a missing cross-project relationship before committing to a design. That thread is about framework forks; this is the service-oriented case, following #561 (closed with an invitation to continue in Discussions) and the storage direction in #576 and #932.
Setup. A polyrepo: several Laravel services exposing GraphQL with Lighthouse, a schema-stitching gateway in front, Vue clients. Minimal example, three folders indexed as three projects: https://github.com/jmverges/cbm-stitched-graphql-example
The relationship.
web/src/graphql/recentOrders.jsreadsOrder.total,Order.buyerandCustomer.name. In the service they are served byOrder::getTotalCentsAttribute()(@rename(attribute: "total_cents")),Order::customer()(@belongsTo) andCustomer::getDisplayNameAttribute(). "Who readsOrder.total, and which PHP serves it?" needs client file -> schema field -> PHP method, across repos, through a gateway that hides which service answers.What 0.11.0 extracts (exact commands in the README):
acme-api: the schema becomesClass/Fieldnodes and the PHP methods are there, but there is no edge from a field to the method that serves it, and noRoute/HANDLES.acme-web: noGRAPHQL_CALLS. Same result after padding the project past the 50-file parallel threshold: the emitter fires on a resolved callee whose qualified name contains a GraphQL library token (a localgql()does produce an edge), not ongqlimported fromgraphql-tag.cross_graphql_calls: 0.__graphql__<operation text>, and I could not find anything that emits a server-side GraphQLRoute+HANDLES, so for GraphQL the pass has nothing to pair today.Why not a pass for this. The mapping is framework semantics: Lighthouse directives, Eloquent accessor naming, schema stitching. A parser per framework is the combinatorial problem you described in #561. We already compute these links with a small tool of our own and write them into the per-project databases after each index. That works, but as you explained in #576 the next index run erases them, so we redo it after every reindex.
Proposal: a declared links file read during indexing. An opt-in file in the repo, e.g.
.cbmlinks.json(sketch in the example'sproposal/links.json), with entries{route, role: handler|caller, file, symbol}. A pipeline pass turns them into the sameRoute+HANDLES/*_CALLSedges the indexer already builds (including theoperation-style property the cross-repo pass reads), so the existing pass pairs them by Route qualified name and they survive a reindex by construction. The route key is whatever both sides declare; for GraphQL we use__graphql__Type.field, a different granularity from the operation-text key the extractor uses, so declared keys would stay separate from extracted ones. Along the lines of #932: paths must stay inside the project, unresolved symbols are reported, and staleness is detectable (the file's hash recorded with the index generation).This is different from #292 (teaching the extractor more call patterns) and from the runtime trace model from #612 (observations kept out of the static graph): it is for links that are known statically but not derivable from source alone.
Does this shape fit what you had in mind? If so, I'm happy to prototype it within the contribution guidelines, or to adapt the format to whatever you prefer.
Drafted with AI assistance (Claude); I reviewed it and ran the example myself.
All reactions