Create a new GLQL REST API for Duo integration

What does this MR do and why?

This MR adds a new REST API which allows us to send GLQL query blocks to the backend, and be given data back.

This is very useful for two reasons:

  1. It can handle more complex GLQL situations, and in the future, it could cache the results
  2. It allows Duo Workflow Service to be able to query this API, allowing Duo to use and understand GLQL queries and the results.

References

Related to #578342 (closed) and #573055 (closed)

Example API outputs

Success response
curl -X POST --location "http://gdk.test:8080/api/v4/glql" --http1.1 \
  -H "Host: gdk.test:8080" \
  -H "PRIVATE-TOKEN: {{privateToken}}" \
  -H "Content-Type: application/json" \
  -d '{
    "glql_yaml": "display: table\nfields: title, state, author, created\nsort: created desc\nlimit: 100\nquery: type = Issue and project = \"gitlab-duo/test\""
  }'
{
  "data": {
    "count": 1,
    "nodes": [
      {
        "author": {
          "avatarUrl": "https://www.gravatar.com/avatar/4a17cff4a15e98966063bd203d88aceac682c623e74943a08cdbe0cce87c6d7c?s=80&d=identicon",
          "id": "gid://gitlab/User/1",
          "name": "Administrator",
          "username": "root",
          "webUrl": "http://gdk.test:3000/root"
        },
        "created": "2025-09-23T15:16:15Z",
        "createdAt": "2025-09-23T15:16:15Z",
        "id": "gid://gitlab/Issue/1000000",
        "iid": "1",
        "reference": "#1",
        "state": "opened",
        "title": "Add an example of GoLang HTTP server",
        "webUrl": "http://gdk.test:3000/gitlab-duo/test/-/issues/1"
      }
    ],
    "pageInfo": {
      "endCursor": "eyJjcmVhdGVkX2F0IjoiMjAyNS0wOS0yMyAxNToxNjoxNS45MDA0ODMwMDAgKzAwMDAiLCJpZCI6IjEwMDAwMDAifQ",
      "hasNextPage": false,
      "hasPreviousPage": false,
      "startCursor": "eyJjcmVhdGVkX2F0IjoiMjAyNS0wOS0yMyAxNToxNjoxNS45MDA0ODMwMDAgKzAwMDAiLCJpZCI6IjEwMDAwMDAifQ"
    }
  },
  "error": null,
  "fields": [
    {
      "key": "title",
      "label": "Title",
      "name": "title"
    },
    {
      "key": "state",
      "label": "State",
      "name": "state"
    },
    {
      "key": "author",
      "label": "Author",
      "name": "author"
    },
    {
      "key": "created",
      "label": "Created",
      "name": "createdAt"
    }
  ],
  "success": true
}
Failure response - inaccessible or unknown project
curl -X POST --location "http://gdk.test:8080/api/v4/glql" \
  -H "Host: gdk.test:8080" \
  -H "PRIVATE-TOKEN: {{privateToken}}" \
  -H "Content-Type: application/json" \
  -d '{
    "glql_yaml": "display: table\nfields: title, state, author, created\nsort: created desc\nlimit: 100\nquery: type = Issue and project = \"gitlab-duo/sdfdfdsf\""
  }'
{
  "message": "400 Bad request - Error: Project does not exist or you do not have access to it"
}
Failure response - rate limited
curl -X POST --location "http://gdk.test:8080/api/v4/glql" --http1.1 \
  -H "Host: gdk.test:8080" \
  -H "PRIVATE-TOKEN: {{privateToken}}" \
  -H "Content-Type: application/json" \
  -d '{
    "glql_yaml": "display: table\nfields: title, state, author, created\nsort: created desc\nlimit: 100\nquery: type = Issue and project = \"gitlab-duo/test\""
  }'
{
  "error": "Query temporarily blocked due to repeated timeouts. Please try again later or narrow your search scope."
}

How to set up and validate locally

  1. Call the API with an appropriate GLQL YAML configuration:
    curl -X POST --location "http://gdk.test:8080/api/v4/glql" --http1.1 \
      -H "Host: gdk.test:8080" \
      -H "PRIVATE-TOKEN: {{privateToken}}" \
      -H "Content-Type: application/json" \
      -d '{
        "glql_yaml": "display: table\nfields: title, state, author, created\nsort: created desc\nlimit: 100\nquery: type = Issue and project = \"gitlab-duo/test\""
      }'
  2. Verify that it outputs a valid response on success
  3. Verify that it outputs a valid error state on failure

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Robert Hunt

Merge request reports

Loading