Add GQL response format to Orbit queries
What does this MR do and why?
REST callers of POST /api/v4/orbit/query and POST /api/v4/orbit/query/:name, and MCP callers of query_graph, can now pass response_format: "gql" (MCP: format: "gql"). Results come back as a plain-text table with one column per returned alias. REST responds with text/plain; MCP responds with text content.
The format is gated by the per-user orbit_gql_queries flag, the same flag that enables GQL query input (!256465 (merged)). With the flag off, gql is rejected with 400 "GQL response format is not enabled"; MCP returns a tool error with the same text. raw and llm are unchanged in both flag states. raw stays the REST default; llm stays the MCP default. Other Orbit endpoints, such as the schema endpoint, still accept only raw and llm.
Workhorse maps gql to the new protobuf response format and writes it the same way it writes llm. Workhorse does not check for an older backend, so deploy the Orbit backend before enabling the flag. No changelog entry: the feature is behind a default-off flag.
workhorse/go.mod pins the Orbit protobuf client to v0.137.0, the first release with the GQL format from gitlab-org/orbit/knowledge-graph!2661 (merged).
References
- Backend MR: gitlab-org/orbit/knowledge-graph!2661 (merged)
- Issue: https://gitlab.com/gitlab-org/orbit/knowledge-graph/-/work_items/1263
- GQL query input MR: !256465 (merged)
- Flag rollout issue: #629612
Screenshots or screen recordings
No UI changes. The GDK response for a user-group traversal:
+------------------------------------------------------------------------------------+
| u | g |
+------------------------------------------------------------------------------------+
| (:User {id: 1, username: "root"}) | (:Group {id: 22, name: "Toolbox"}) |
| (:User {id: 6, username: "georgine_keebler"}) | (:Group {id: 22, name: "Toolbox"}) |
+------------------------------------------------------------------------------------+
2 rows, more availableHow to set up and validate locally
-
Run Orbit from knowledge-graph main at or after the merge of gitlab-org/orbit/knowledge-graph!2661 (merged).
-
Check out this branch in GDK, run
make -C workhorse, and restartrails-webandgitlab-workhorse. -
In a Rails console:
Feature.enable(:orbit_gql_queries, user). Restartrails-web(Rails caches flag values per process for about a minute). -
Send:
curl --request POST \ --header "PRIVATE-TOKEN: <your_access_token>" \ --header "Content-Type: application/json" \ --data '{"query":"MATCH (p:Project) WHERE p.id IS NOT NULL RETURN p ORDER BY p.id LIMIT 3","response_format":"gql"}' \ --url "http://127.0.0.1:3000/api/v4/orbit/query" -
Disable the flag, restart
rails-web, and send the same request with a JSON DSL query. Expect HTTP 400.
Validation results and GDK setup
- Rails request and unit specs: 346 examples, 0 failures, 26 pending shared examples. Workhorse Orbit package tests pass, including with
-race. RuboCop, Vale, and markdownlint pass. - The new flag-off specs and Workhorse GQL tests fail against the code before this MR.
- 49 HTTP checks pass across three local GDK runs, with real Rails auth and no mocks:
- Flag on (17): REST query and named query return JSON for
raw, text forllm, a table forgql, andrawby default. MCP returns all three formats andllmby default. Empty results and aggregates render as tables. - Flag off (15):
rawandllmwork with JSON queries.gqlis rejected on REST, named queries, and MCP. - Both states: an invalid format returns 400, the schema endpoint still rejects
gql, and a missing token returns 401. The third run repeated the flag-on checks after restoring the flag.
- Flag on (17): REST query and named query return JSON for
- Setup: GDK at commit
11884e338e19with Workhorse rebuilt. Orbit at knowledge-graph main5f507a706, which includes the backend MR, against existing local v100 graph data. The flag was toggled for the root user and then restored.
MR acceptance checklist
Evaluated against the MR acceptance checklist.
- Specs cover the flag gate and the
gqlformat on REST, named queries, and MCP. - Verified end to end on local GDK with the flag on and off.
-
rawandllmbehavior unchanged. - Orbit release that includes the GQL format published (v0.137.0) and
go.modpin bumped to it. - Orbit backend deployed before the flag is enabled.