Skip to content

feat(router): plugin system#628

Merged
ardatan merged 1 commit intomainfrom
plugin-system
Feb 25, 2026
Merged

feat(router): plugin system#628
ardatan merged 1 commit intomainfrom
plugin-system

Conversation

@ardatan
Copy link
Member

@ardatan ardatan commented Dec 19, 2025

Documentation > graphql-hive/console#7387
Preview of the docs -> https://pr-7387.hive-landing-page.pages.dev/docs/router/guides/extending-the-router
Example plugins -> https://github.com/graphql-hive/router/tree/plugin-system/plugin_examples

TODO:

  • Document why API is implemented in this way and that way (payload.initialize_plugins, OnPluginInitResult type e.g.)
  • Documentation updates

@ardatan ardatan changed the title Plugin system Plugin System Dec 19, 2025
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @ardatan, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a robust and flexible plugin system to the router, transforming it into a highly extensible platform. By integrating a series of well-defined plugin hooks throughout the request lifecycle, from initial HTTP handling to final execution and response, the router now supports custom logic injection at critical points. This refactoring not only enables advanced features like Automatic Persisted Queries, response caching, and custom authorization rules but also streamlines the core pipeline by centralizing common functionalities and improving modularity. The extensive suite of new end-to-end tests validates the functionality and stability of this new plugin architecture, demonstrating its potential for a wide range of custom router behaviors.

Highlights

  • Plugin System Introduction: A comprehensive plugin system has been integrated into the router, allowing for custom logic to be injected at various stages of the request processing lifecycle.
  • Extensive Plugin Hooks: New hook points have been added across the request pipeline, including HTTP request handling, GraphQL parameter deserialization, parsing, validation, query planning, execution, and supergraph loading, enabling fine-grained control and extensibility.
  • Core Pipeline Refactoring: Significant refactoring of core router components, such as GraphQL parameter handling, authorization metadata, and executor logic, was performed to seamlessly integrate the new plugin architecture and improve modularity.
  • New Plugin Examples and Tests: A wide array of new end-to-end tests and example plugins demonstrate diverse capabilities, including Apollo Sandbox integration, Automatic Persisted Queries (APQ), client ID authorization, context data propagation, multipart file uploads, and response caching.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive plugin system to the router, enabling custom logic at various stages of the request pipeline. Key changes include adding plugins configuration to HiveRouterConfig, introducing PluginRegistry and PluginService for managing and integrating plugins, and defining several new plugin hooks (on_http_request, on_graphql_params, on_graphql_parse, on_graphql_validation, on_query_plan, on_execute, on_subgraph_execute, on_subgraph_http_request, on_supergraph_reload) within the hive-router-plan-executor crate. The JwtRequestDetails and AuthorizationMetadata types have been refactored to use owned String and Value types, and AuthorizationMetadata has been moved to a new hive-router-internal crate. The request processing pipeline has been significantly refactored to accommodate these hooks, moving from direct error returns to Result types and introducing a new deserialize_graphql_params module. Additionally, the bench/subgraphs now uses DashMap for request logging and includes new upload and oneofTest mutations for testing multipart and oneOf input types. Dependencies have been updated to include bollard, multer, redis, and other related crates. Review comments highlight a security vulnerability in the upload function due to potential path traversal, recommend replacing sonic_rs::from_slice_unchecked with from_slice or adding a safety comment, and suggest refactoring the execute_query_plan method into smaller, more manageable functions for improved readability and maintainability.

I am having trouble creating individual review comments. Click here to see my feedback.

bench/subgraphs/products.rs (132-144)

high

The upload function has a few issues that should be addressed:

  1. Security Vulnerability (Path Traversal): The file path is constructed using `format!("/tmp/{}
    async fn upload(&self, ctx: &Context<'_>, file: Option<Upload>) -> async_graphql::Result<String> {
        let uploaded_file = file.ok_or_else(|| "No file uploaded")?.value(ctx)?;

        // Sanitize filename to prevent path traversal
        let filename = std::path::Path::new(&uploaded_file.filename)
            .file_name()
            .ok_or_else(|| async_graphql::Error::new("Invalid filename"))?;

        let path = std::env::temp_dir().join(filename);

        let mut tmp_file = tokio::fs::File::create(&path).await?;
        tokio::io::copy(&mut uploaded_file.into_async_read(), &mut tmp_file).await?;

        Ok(path.to_string_lossy().into_owned())
    }

bin/router/src/pipeline/deserialize_graphql_params.rs (95-100)

high

The use of unsafe with sonic_rs::from_slice_unchecked is a concern. The style guide (Rule J) requires a safety comment for unsafe blocks explaining why it's safe. from_slice_unchecked assumes the input is valid UTF-8, but an HTTP request body isn't guaranteed to be, even with a JSON content type. A malicious request could lead to undefined behavior.

Please replace this with the safe sonic_rs::from_slice or add a detailed safety comment justifying the performance gain and explaining how the validity of the byte slice is guaranteed.

            let execution_request = sonic_rs::from_slice::<GraphQLParams>(&body_bytes).map_err(|e| {
                warn!("Failed to parse body: {}", e);
                PipelineErrorVariant::FailedToParseBody(e)
            })?;

lib/executor/src/execution/plan.rs (71-201)

medium

The execute_query_plan method is quite long and handles many concerns, making it difficult to follow. As per the style guide (Rule E), it would be beneficial to break this down into smaller, more focused functions to improve readability and maintainability. For example, the plugin hook logic could be separated from the main execution logic.

@github-actions
Copy link

github-actions bot commented Dec 19, 2025

🐋 This PR was built and pushed to the following Docker images:

Image Names: ghcr.io/graphql-hive/router

Platforms: linux/amd64,linux/arm64

Image Tags: ghcr.io/graphql-hive/router:pr-628 ghcr.io/graphql-hive/router:sha-879dd4a

Docker metadata
{
"buildx.build.provenance/linux/amd64": {
  "builder": {
    "id": "https://github.com/graphql-hive/router/actions/runs/22393835154/attempts/1"
  },
  "buildType": "https://mobyproject.org/buildkit@v1",
  "materials": [
    {
      "uri": "pkg:docker/docker/dockerfile@1.21",
      "digest": {
        "sha256": "27f9262d43452075f3c410287a2c43f5ef1bf7ec2bb06e8c9eeb1b8d453087bc"
      }
    },
    {
      "uri": "pkg:docker/gcr.io/distroless/cc-debian12@latest?platform=linux%2Famd64",
      "digest": {
        "sha256": "329e54034ce498f9c6b345044e8f530c6691f99e94a92446f68c0adf9baa8464"
      }
    }
  ],
  "invocation": {
    "configSource": {
      "entryPoint": "router.Dockerfile"
    },
    "parameters": {
      "frontend": "gateway.v0",
      "args": {
        "cmdline": "docker/dockerfile:1.21",
        "label:org.opencontainers.image.created": "2026-02-25T11:09:00.621Z",
        "label:org.opencontainers.image.description": "Open-source (MIT) GraphQL Federation Router. Built with Rust for maximum performance and robustness.",
        "label:org.opencontainers.image.licenses": "MIT",
        "label:org.opencontainers.image.revision": "879dd4a75fc20137b2cbc445c993192e12988699",
        "label:org.opencontainers.image.source": "https://github.com/graphql-hive/router",
        "label:org.opencontainers.image.title": "router",
        "label:org.opencontainers.image.url": "https://github.com/graphql-hive/router",
        "label:org.opencontainers.image.vendor": "theguild",
        "label:org.opencontainers.image.version": "pr-628",
        "source": "docker/dockerfile:1.21"
      },
      "locals": [
        {
          "name": "context"
        },
        {
          "name": "dockerfile"
        }
      ]
    },
    "environment": {
      "github_actor": "ardatan",
      "github_actor_id": "20847995",
      "github_event_name": "pull_request",
      "github_event_payload": {
        "action": "synchronize",
        "after": "ad6a855a4d7374aba01258d15c14583f411db780",
        "before": "a6d5894d2dd3e12989423b9d6c120a38b9c24e59",
        "enterprise": {
          "avatar_url": "https://avatars.githubusercontent.com/b/187753?v=4",
          "created_at": "2024-07-02T08:52:28Z",
          "description": "",
          "html_url": "https://github.com/enterprises/the-guild",
          "id": 187753,
          "name": "The Guild",
          "node_id": "E_kgDOAALdaQ",
          "slug": "the-guild",
          "updated_at": "2026-02-11T08:01:14Z",
          "website_url": "https://the-guild.dev/"
        },
        "number": 628,
        "organization": {
          "avatar_url": "https://avatars.githubusercontent.com/u/182742256?v=4",
          "description": "Schema registry, analytics and gateway for GraphQL federation and other GraphQL APIs.",
          "events_url": "https://api.github.com/orgs/graphql-hive/events",
          "hooks_url": "https://api.github.com/orgs/graphql-hive/hooks",
          "id": 182742256,
          "issues_url": "https://api.github.com/orgs/graphql-hive/issues",
          "login": "graphql-hive",
          "members_url": "https://api.github.com/orgs/graphql-hive/members{/member}",
          "node_id": "O_kgDOCuRs8A",
          "public_members_url": "https://api.github.com/orgs/graphql-hive/public_members{/member}",
          "repos_url": "https://api.github.com/orgs/graphql-hive/repos",
          "url": "https://api.github.com/orgs/graphql-hive"
        },
        "pull_request": {
          "_links": {
            "comments": {
              "href": "https://api.github.com/repos/graphql-hive/router/issues/628/comments"
            },
            "commits": {
              "href": "https://api.github.com/repos/graphql-hive/router/pulls/628/commits"
            },
            "html": {
              "href": "https://github.com/graphql-hive/router/pull/628"
            },
            "issue": {
              "href": "https://api.github.com/repos/graphql-hive/router/issues/628"
            },
            "review_comment": {
              "href": "https://api.github.com/repos/graphql-hive/router/pulls/comments{/number}"
            },
            "review_comments": {
              "href": "https://api.github.com/repos/graphql-hive/router/pulls/628/comments"
            },
            "self": {
              "href": "https://api.github.com/repos/graphql-hive/router/pulls/628"
            },
            "statuses": {
              "href": "https://api.github.com/repos/graphql-hive/router/statuses/ad6a855a4d7374aba01258d15c14583f411db780"
            }
          },
          "active_lock_reason": null,
          "additions": 9071,
          "assignee": null,
          "assignees": [],
          "author_association": "MEMBER",
          "auto_merge": null,
          "base": {
            "label": "graphql-hive:main",
            "ref": "main",
            "repo": {
              "allow_auto_merge": false,
              "allow_forking": true,
              "allow_merge_commit": false,
              "allow_rebase_merge": false,
              "allow_squash_merge": true,
              "allow_update_branch": true,
              "archive_url": "https://api.github.com/repos/graphql-hive/router/{archive_format}{/ref}",
              "archived": false,
              "assignees_url": "https://api.github.com/repos/graphql-hive/router/assignees{/user}",
              "blobs_url": "https://api.github.com/repos/graphql-hive/router/git/blobs{/sha}",
              "branches_url": "https://api.github.com/repos/graphql-hive/router/branches{/branch}",
              "clone_url": "https://github.com/graphql-hive/router.git",
              "collaborators_url": "https://api.github.com/repos/graphql-hive/router/collaborators{/collaborator}",
              "comments_url": "https://api.github.com/repos/graphql-hive/router/comments{/number}",
              "commits_url": "https://api.github.com/repos/graphql-hive/router/commits{/sha}",
              "compare_url": "https://api.github.com/repos/graphql-hive/router/compare/{base}...{head}",
              "contents_url": "https://api.github.com/repos/graphql-hive/router/contents/{+path}",
              "contributors_url": "https://api.github.com/repos/graphql-hive/router/contributors",
              "created_at": "2024-11-20T16:16:12Z",
              "default_branch": "main",
              "delete_branch_on_merge": true,
              "deployments_url": "https://api.github.com/repos/graphql-hive/router/deployments",
              "description": "Open-source (MIT) GraphQL Federation Router. Built with Rust for maximum performance and robustness.",
              "disabled": false,
              "downloads_url": "https://api.github.com/repos/graphql-hive/router/downloads",
              "events_url": "https://api.github.com/repos/graphql-hive/router/events",
              "fork": false,
              "forks": 8,
              "forks_count": 8,
              "forks_url": "https://api.github.com/repos/graphql-hive/router/forks",
              "full_name": "graphql-hive/router",
              "git_commits_url": "https://api.github.com/repos/graphql-hive/router/git/commits{/sha}",
              "git_refs_url": "https://api.github.com/repos/graphql-hive/router/git/refs{/sha}",
              "git_tags_url": "https://api.github.com/repos/graphql-hive/router/git/tags{/sha}",
              "git_url": "git://github.com/graphql-hive/router.git",
              "has_discussions": false,
              "has_downloads": true,
              "has_issues": true,
              "has_pages": false,
              "has_projects": false,
              "has_pull_requests": true,
              "has_wiki": false,
              "homepage": "https://the-guild.dev/graphql/hive/docs/router",
              "hooks_url": "https://api.github.com/repos/graphql-hive/router/hooks",
              "html_url": "https://github.com/graphql-hive/router",
              "id": 891604244,
              "is_template": false,
              "issue_comment_url": "https://api.github.com/repos/graphql-hive/router/issues/comments{/number}",
              "issue_events_url": "https://api.github.com/repos/graphql-hive/router/issues/events{/number}",
              "issues_url": "https://api.github.com/repos/graphql-hive/router/issues{/number}",
              "keys_url": "https://api.github.com/repos/graphql-hive/router/keys{/key_id}",
              "labels_url": "https://api.github.com/repos/graphql-hive/router/labels{/name}",
              "language": "Rust",
              "languages_url": "https://api.github.com/repos/graphql-hive/router/languages",
              "license": {
                "key": "mit",
                "name": "MIT License",
                "node_id": "MDc6TGljZW5zZTEz",
                "spdx_id": "MIT",
                "url": "https://api.github.com/licenses/mit"
              },
              "merge_commit_message": "PR_TITLE",
              "merge_commit_title": "MERGE_MESSAGE",
              "merges_url": "https://api.github.com/repos/graphql-hive/router/merges",
              "milestones_url": "https://api.github.com/repos/graphql-hive/router/milestones{/number}",
              "mirror_url": null,
              "name": "router",
              "node_id": "R_kgDONSTNFA",
              "notifications_url": "https://api.github.com/repos/graphql-hive/router/notifications{?since,all,participating}",
              "open_issues": 58,
              "open_issues_count": 58,
              "owner": {
                "avatar_url": "https://avatars.githubusercontent.com/u/182742256?v=4",
                "events_url": "https://api.github.com/users/graphql-hive/events{/privacy}",
                "followers_url": "https://api.github.com/users/graphql-hive/followers",
                "following_url": "https://api.github.com/users/graphql-hive/following{/other_user}",
                "gists_url": "https://api.github.com/users/graphql-hive/gists{/gist_id}",
                "gravatar_id": "",
                "html_url": "https://github.com/graphql-hive",
                "id": 182742256,
                "login": "graphql-hive",
                "node_id": "O_kgDOCuRs8A",
                "organizations_url": "https://api.github.com/users/graphql-hive/orgs",
                "received_events_url": "https://api.github.com/users/graphql-hive/received_events",
                "repos_url": "https://api.github.com/users/graphql-hive/repos",
                "site_admin": false,
                "starred_url": "https://api.github.com/users/graphql-hive/starred{/owner}{/repo}",
                "subscriptions_url": "https://api.github.com/users/graphql-hive/subscriptions",
                "type": "Organization",
                "url": "https://api.github.com/users/graphql-hive",
                "user_view_type": "public"
              },
              "private": false,
              "pull_request_creation_policy": "all",
              "pulls_url": "https://api.github.com/repos/graphql-hive/router/pulls{/number}",
              "pushed_at": "2026-02-25T10:58:18Z",
              "releases_url": "https://api.github.com/repos/graphql-hive/router/releases{/id}",
              "size": 5097,
              "squash_merge_commit_message": "PR_BODY",
              "squash_merge_commit_title": "PR_TITLE",
              "ssh_url": "git@github.com:graphql-hive/router.git",
              "stargazers_count": 73,
              "stargazers_url": "https://api.github.com/repos/graphql-hive/router/stargazers",
              "statuses_url": "https://api.github.com/repos/graphql-hive/router/statuses/{sha}",
              "subscribers_url": "https://api.github.com/repos/graphql-hive/router/subscribers",
              "subscription_url": "https://api.github.com/repos/graphql-hive/router/subscription",
              "svn_url": "https://github.com/graphql-hive/router",
              "tags_url": "https://api.github.com/repos/graphql-hive/router/tags",
              "teams_url": "https://api.github.com/repos/graphql-hive/router/teams",
              "topics": [
                "apollo-federation",
                "federation",
                "federation-gateway",
                "graphql",
                "graphql-federation",
                "router"
              ],
              "trees_url": "https://api.github.com/repos/graphql-hive/router/git/trees{/sha}",
              "updated_at": "2026-02-25T10:55:23Z",
              "url": "https://api.github.com/repos/graphql-hive/router",
              "use_squash_pr_title_as_default": true,
              "visibility": "public",
              "watchers": 73,
              "watchers_count": 73,
              "web_commit_signoff_required": false
            },
            "sha": "ce3f102b470f424904c5d970fc53a33e5a904b95",
            "user": {
              "avatar_url": "https://avatars.githubusercontent.com/u/182742256?v=4",
              "events_url": "https://api.github.com/users/graphql-hive/events{/privacy}",
              "followers_url": "https://api.github.com/users/graphql-hive/followers",
              "following_url": "https://api.github.com/users/graphql-hive/following{/other_user}",
              "gists_url": "https://api.github.com/users/graphql-hive/gists{/gist_id}",
              "gravatar_id": "",
              "html_url": "https://github.com/graphql-hive",
              "id": 182742256,
              "login": "graphql-hive",
              "node_id": "O_kgDOCuRs8A",
              "organizations_url": "https://api.github.com/users/graphql-hive/orgs",
              "received_events_url": "https://api.github.com/users/graphql-hive/received_events",
              "repos_url": "https://api.github.com/users/graphql-hive/repos",
              "site_admin": false,
              "starred_url": "https://api.github.com/users/graphql-hive/starred{/owner}{/repo}",
              "subscriptions_url": "https://api.github.com/users/graphql-hive/subscriptions",
              "type": "Organization",
              "url": "https://api.github.com/users/graphql-hive",
              "user_view_type": "public"
            }
          },
          "body": "Documentation > https://github.com/graphql-hive/console/pull/7387\r\nPreview of the docs -> https://pr-7387.hive-landing-page.pages.dev/docs/router/guides/extending-the-router\r\nExample plugins -> https://github.com/graphql-hive/router/tree/plugin-system/plugin_examples\r\n\r\nTODO:\r\n- Document why API is implemented in this way and that way (payload.initialize_plugins, OnPluginInitResult type e.g.)\r\n- Documentation updates",
          "changed_files": 213,
          "closed_at": null,
          "comments": 5,
          "comments_url": "https://api.github.com/repos/graphql-hive/router/issues/628/comments",
          "commits": 1,
          "commits_url": "https://api.github.com/repos/graphql-hive/router/pulls/628/commits",
          "created_at": "2025-12-19T14:23:59Z",
          "deletions": 1198,
          "diff_url": "https://github.com/graphql-hive/router/pull/628.diff",
          "draft": false,
          "head": {
            "label": "graphql-hive:plugin-system",
            "ref": "plugin-system",
            "repo": {
              "allow_auto_merge": false,
              "allow_forking": true,
              "allow_merge_commit": false,
              "allow_rebase_merge": false,
              "allow_squash_merge": true,
              "allow_update_branch": true,
              "archive_url": "https://api.github.com/repos/graphql-hive/router/{archive_format}{/ref}",
              "archived": false,
              "assignees_url": "https://api.github.com/repos/graphql-hive/router/assignees{/user}",
              "blobs_url": "https://api.github.com/repos/graphql-hive/router/git/blobs{/sha}",
              "branches_url": "https://api.github.com/repos/graphql-hive/router/branches{/branch}",
              "clone_url": "https://github.com/graphql-hive/router.git",
              "collaborators_url": "https://api.github.com/repos/graphql-hive/router/collaborators{/collaborator}",
              "comments_url": "https://api.github.com/repos/graphql-hive/router/comments{/number}",
              "commits_url": "https://api.github.com/repos/graphql-hive/router/commits{/sha}",
              "compare_url": "https://api.github.com/repos/graphql-hive/router/compare/{base}...{head}",
              "contents_url": "https://api.github.com/repos/graphql-hive/router/contents/{+path}",
              "contributors_url": "https://api.github.com/repos/graphql-hive/router/contributors",
              "created_at": "2024-11-20T16:16:12Z",
              "default_branch": "main",
              "delete_branch_on_merge": true,
              "deployments_url": "https://api.github.com/repos/graphql-hive/router/deployments",
              "description": "Open-source (MIT) GraphQL Federation Router. Built with Rust for maximum performance and robustness.",
              "disabled": false,
              "downloads_url": "https://api.github.com/repos/graphql-hive/router/downloads",
              "events_url": "https://api.github.com/repos/graphql-hive/router/events",
              "fork": false,
              "forks": 8,
              "forks_count": 8,
              "forks_url": "https://api.github.com/repos/graphql-hive/router/forks",
              "full_name": "graphql-hive/router",
              "git_commits_url": "https://api.github.com/repos/graphql-hive/router/git/commits{/sha}",
              "git_refs_url": "https://api.github.com/repos/graphql-hive/router/git/refs{/sha}",
              "git_tags_url": "https://api.github.com/repos/graphql-hive/router/git/tags{/sha}",
              "git_url": "git://github.com/graphql-hive/router.git",
              "has_discussions": false,
              "has_downloads": true,
              "has_issues": true,
              "has_pages": false,
              "has_projects": false,
              "has_pull_requests": true,
              "has_wiki": false,
              "homepage": "https://the-guild.dev/graphql/hive/docs/router",
              "hooks_url": "https://api.github.com/repos/graphql-hive/router/hooks",
              "html_url": "https://github.com/graphql-hive/router",
              "id": 891604244,
              "is_template": false,
              "issue_comment_url": "https://api.github.com/repos/graphql-hive/router/issues/comments{/number}",
              "issue_events_url": "https://api.github.com/repos/graphql-hive/router/issues/events{/number}",
              "issues_url": "https://api.github.com/repos/graphql-hive/router/issues{/number}",
              "keys_url": "https://api.github.com/repos/graphql-hive/router/keys{/key_id}",
              "labels_url": "https://api.github.com/repos/graphql-hive/router/labels{/name}",
              "language": "Rust",
              "languages_url": "https://api.github.com/repos/graphql-hive/router/languages",
              "license": {
                "key": "mit",
                "name": "MIT License",
                "node_id": "MDc6TGljZW5zZTEz",
                "spdx_id": "MIT",
                "url": "https://api.github.com/licenses/mit"
              },
              "merge_commit_message": "PR_TITLE",
              "merge_commit_title": "MERGE_MESSAGE",
              "merges_url": "https://api.github.com/repos/graphql-hive/router/merges",
              "milestones_url": "https://api.github.com/repos/graphql-hive/router/milestones{/number}",
              "mirror_url": null,
              "name": "router",
              "node_id": "R_kgDONSTNFA",
              "notifications_url": "https://api.github.com/repos/graphql-hive/router/notifications{?since,all,participating}",
              "open_issues": 58,
              "open_issues_count": 58,
              "owner": {
                "avatar_url": "https://avatars.githubusercontent.com/u/182742256?v=4",
                "events_url": "https://api.github.com/users/graphql-hive/events{/privacy}",
                "followers_url": "https://api.github.com/users/graphql-hive/followers",
                "following_url": "https://api.github.com/users/graphql-hive/following{/other_user}",
                "gists_url": "https://api.github.com/users/graphql-hive/gists{/gist_id}",
                "gravatar_id": "",
                "html_url": "https://github.com/graphql-hive",
                "id": 182742256,
                "login": "graphql-hive",
                "node_id": "O_kgDOCuRs8A",
                "organizations_url": "https://api.github.com/users/graphql-hive/orgs",
                "received_events_url": "https://api.github.com/users/graphql-hive/received_events",
                "repos_url": "https://api.github.com/users/graphql-hive/repos",
                "site_admin": false,
                "starred_url": "https://api.github.com/users/graphql-hive/starred{/owner}{/repo}",
                "subscriptions_url": "https://api.github.com/users/graphql-hive/subscriptions",
                "type": "Organization",
                "url": "https://api.github.com/users/graphql-hive",
                "user_view_type": "public"
              },
              "private": false,
              "pull_request_creation_policy": "all",
              "pulls_url": "https://api.github.com/repos/graphql-hive/router/pulls{/number}",
              "pushed_at": "2026-02-25T10:58:18Z",
              "releases_url": "https://api.github.com/repos/graphql-hive/router/releases{/id}",
              "size": 5097,
              "squash_merge_commit_message": "PR_BODY",
              "squash_merge_commit_title": "PR_TITLE",
              "ssh_url": "git@github.com:graphql-hive/router.git",
              "stargazers_count": 73,
              "stargazers_url": "https://api.github.com/repos/graphql-hive/router/stargazers",
              "statuses_url": "https://api.github.com/repos/graphql-hive/router/statuses/{sha}",
              "subscribers_url": "https://api.github.com/repos/graphql-hive/router/subscribers",
              "subscription_url": "https://api.github.com/repos/graphql-hive/router/subscription",
              "svn_url": "https://github.com/graphql-hive/router",
              "tags_url": "https://api.github.com/repos/graphql-hive/router/tags",
              "teams_url": "https://api.github.com/repos/graphql-hive/router/teams",
              "topics": [
                "apollo-federation",
                "federation",
                "federation-gateway",
                "graphql",
                "graphql-federation",
                "router"
              ],
              "trees_url": "https://api.github.com/repos/graphql-hive/router/git/trees{/sha}",
              "updated_at": "2026-02-25T10:55:23Z",
              "url": "https://api.github.com/repos/graphql-hive/router",
              "use_squash_pr_title_as_default": true,
              "visibility": "public",
              "watchers": 73,
              "watchers_count": 73,
              "web_commit_signoff_required": false
            },
            "sha": "ad6a855a4d7374aba01258d15c14583f411db780",
            "user": {
              "avatar_url": "https://avatars.githubusercontent.com/u/182742256?v=4",
              "events_url": "https://api.github.com/users/graphql-hive/events{/privacy}",
              "followers_url": "https://api.github.com/users/graphql-hive/followers",
              "following_url": "https://api.github.com/users/graphql-hive/following{/other_user}",
              "gists_url": "https://api.github.com/users/graphql-hive/gists{/gist_id}",
              "gravatar_id": "",
              "html_url": "https://github.com/graphql-hive",
              "id": 182742256,
              "login": "graphql-hive",
              "node_id": "O_kgDOCuRs8A",
              "organizations_url": "https://api.github.com/users/graphql-hive/orgs",
              "received_events_url": "https://api.github.com/users/graphql-hive/received_events",
              "repos_url": "https://api.github.com/users/graphql-hive/repos",
              "site_admin": false,
              "starred_url": "https://api.github.com/users/graphql-hive/starred{/owner}{/repo}",
              "subscriptions_url": "https://api.github.com/users/graphql-hive/subscriptions",
              "type": "Organization",
              "url": "https://api.github.com/users/graphql-hive",
              "user_view_type": "public"
            }
          },
          "html_url": "https://github.com/graphql-hive/router/pull/628",
          "id": 3117772466,
          "issue_url": "https://api.github.com/repos/graphql-hive/router/issues/628",
          "labels": [],
          "locked": false,
          "maintainer_can_modify": false,
          "merge_commit_sha": "1eff976ef7e8e4be9c3dbfde8567c2406156fb6f",
          "mergeable": null,
          "mergeable_state": "unknown",
          "merged": false,
          "merged_at": null,
          "merged_by": null,
          "milestone": null,
          "node_id": "PR_kwDONSTNFM651W6y",
          "number": 628,
          "patch_url": "https://github.com/graphql-hive/router/pull/628.patch",
          "rebaseable": null,
          "requested_reviewers": [],
          "requested_teams": [],
          "review_comment_url": "https://api.github.com/repos/graphql-hive/router/pulls/comments{/number}",
          "review_comments": 124,
          "review_comments_url": "https://api.github.com/repos/graphql-hive/router/pulls/628/comments",
          "state": "open",
          "statuses_url": "https://api.github.com/repos/graphql-hive/router/statuses/ad6a855a4d7374aba01258d15c14583f411db780",
          "title": "Plugin System",
          "updated_at": "2026-02-25T10:58:19Z",
          "url": "https://api.github.com/repos/graphql-hive/router/pulls/628",
          "user": {
            "avatar_url": "https://avatars.githubusercontent.com/u/20847995?v=4",
            "events_url": "https://api.github.com/users/ardatan/events{/privacy}",
            "followers_url": "https://api.github.com/users/ardatan/followers",
            "following_url": "https://api.github.com/users/ardatan/following{/other_user}",
            "gists_url": "https://api.github.com/users/ardatan/gists{/gist_id}",
            "gravatar_id": "",
            "html_url": "https://github.com/ardatan",
            "id": 20847995,
            "login": "ardatan",
            "node_id": "MDQ6VXNlcjIwODQ3OTk1",
            "organizations_url": "https://api.github.com/users/ardatan/orgs",
            "received_events_url": "https://api.github.com/users/ardatan/received_events",
            "repos_url": "https://api.github.com/users/ardatan/repos",
            "site_admin": false,
            "starred_url": "https://api.github.com/users/ardatan/starred{/owner}{/repo}",
            "subscriptions_url": "https://api.github.com/users/ardatan/subscriptions",
            "type": "User",
            "url": "https://api.github.com/users/ardatan",
            "user_view_type": "public"
          }
        },
        "repository": {
          "allow_forking": true,
          "archive_url": "https://api.github.com/repos/graphql-hive/router/{archive_format}{/ref}",
          "archived": false,
          "assignees_url": "https://api.github.com/repos/graphql-hive/router/assignees{/user}",
          "blobs_url": "https://api.github.com/repos/graphql-hive/router/git/blobs{/sha}",
          "branches_url": "https://api.github.com/repos/graphql-hive/router/branches{/branch}",
          "clone_url": "https://github.com/graphql-hive/router.git",
          "collaborators_url": "https://api.github.com/repos/graphql-hive/router/collaborators{/collaborator}",
          "comments_url": "https://api.github.com/repos/graphql-hive/router/comments{/number}",
          "commits_url": "https://api.github.com/repos/graphql-hive/router/commits{/sha}",
          "compare_url": "https://api.github.com/repos/graphql-hive/router/compare/{base}...{head}",
          "contents_url": "https://api.github.com/repos/graphql-hive/router/contents/{+path}",
          "contributors_url": "https://api.github.com/repos/graphql-hive/router/contributors",
          "created_at": "2024-11-20T16:16:12Z",
          "custom_properties": {
            "vanta_production_branch_name": "main"
          },
          "default_branch": "main",
          "deployments_url": "https://api.github.com/repos/graphql-hive/router/deployments",
          "description": "Open-source (MIT) GraphQL Federation Router. Built with Rust for maximum performance and robustness.",
          "disabled": false,
          "downloads_url": "https://api.github.com/repos/graphql-hive/router/downloads",
          "events_url": "https://api.github.com/repos/graphql-hive/router/events",
          "fork": false,
          "forks": 8,
          "forks_count": 8,
          "forks_url": "https://api.github.com/repos/graphql-hive/router/forks",
          "full_name": "graphql-hive/router",
          "git_commits_url": "https://api.github.com/repos/graphql-hive/router/git/commits{/sha}",
          "git_refs_url": "https://api.github.com/repos/graphql-hive/router/git/refs{/sha}",
          "git_tags_url": "https://api.github.com/repos/graphql-hive/router/git/tags{/sha}",
          "git_url": "git://github.com/graphql-hive/router.git",
          "has_discussions": false,
          "has_downloads": true,
          "has_issues": true,
          "has_pages": false,
          "has_projects": false,
          "has_pull_requests": true,
          "has_wiki": false,
          "homepage": "https://the-guild.dev/graphql/hive/docs/router",
          "hooks_url": "https://api.github.com/repos/graphql-hive/router/hooks",
          "html_url": "https://github.com/graphql-hive/router",
          "id": 891604244,
          "is_template": false,
          "issue_comment_url": "https://api.github.com/repos/graphql-hive/router/issues/comments{/number}",
          "issue_events_url": "https://api.github.com/repos/graphql-hive/router/issues/events{/number}",
          "issues_url": "https://api.github.com/repos/graphql-hive/router/issues{/number}",
          "keys_url": "https://api.github.com/repos/graphql-hive/router/keys{/key_id}",
          "labels_url": "https://api.github.com/repos/graphql-hive/router/labels{/name}",
          "language": "Rust",
          "languages_url": "https://api.github.com/repos/graphql-hive/router/languages",
          "license": {
            "key": "mit",
            "name": "MIT License",
            "node_id": "MDc6TGljZW5zZTEz",
            "spdx_id": "MIT",
            "url": "https://api.github.com/licenses/mit"
          },
          "merges_url": "https://api.github.com/repos/graphql-hive/router/merges",
          "milestones_url": "https://api.github.com/repos/graphql-hive/router/milestones{/number}",
          "mirror_url": null,
          "name": "router",
          "node_id": "R_kgDONSTNFA",
          "notifications_url": "https://api.github.com/repos/graphql-hive/router/notifications{?since,all,participating}",
          "open_issues": 58,
          "open_issues_count": 58,
          "owner": {
            "avatar_url": "https://avatars.githubusercontent.com/u/182742256?v=4",
            "events_url": "https://api.github.com/users/graphql-hive/events{/privacy}",
            "followers_url": "https://api.github.com/users/graphql-hive/followers",
            "following_url": "https://api.github.com/users/graphql-hive/following{/other_user}",
            "gists_url": "https://api.github.com/users/graphql-hive/gists{/gist_id}",
            "gravatar_id": "",
            "html_url": "https://github.com/graphql-hive",
            "id": 182742256,
            "login": "graphql-hive",
            "node_id": "O_kgDOCuRs8A",
            "organizations_url": "https://api.github.com/users/graphql-hive/orgs",
            "received_events_url": "https://api.github.com/users/graphql-hive/received_events",
            "repos_url": "https://api.github.com/users/graphql-hive/repos",
            "site_admin": false,
            "starred_url": "https://api.github.com/users/graphql-hive/starred{/owner}{/repo}",
            "subscriptions_url": "https://api.github.com/users/graphql-hive/subscriptions",
            "type": "Organization",
            "url": "https://api.github.com/users/graphql-hive",
            "user_view_type": "public"
          },
          "private": false,
          "pull_request_creation_policy": "all",
          "pulls_url": "https://api.github.com/repos/graphql-hive/router/pulls{/number}",
          "pushed_at": "2026-02-25T10:58:18Z",
          "releases_url": "https://api.github.com/repos/graphql-hive/router/releases{/id}",
          "size": 5097,
          "ssh_url": "git@github.com:graphql-hive/router.git",
          "stargazers_count": 73,
          "stargazers_url": "https://api.github.com/repos/graphql-hive/router/stargazers",
          "statuses_url": "https://api.github.com/repos/graphql-hive/router/statuses/{sha}",
          "subscribers_url": "https://api.github.com/repos/graphql-hive/router/subscribers",
          "subscription_url": "https://api.github.com/repos/graphql-hive/router/subscription",
          "svn_url": "https://github.com/graphql-hive/router",
          "tags_url": "https://api.github.com/repos/graphql-hive/router/tags",
          "teams_url": "https://api.github.com/repos/graphql-hive/router/teams",
          "topics": [
            "apollo-federation",
            "federation",
            "federation-gateway",
            "graphql",
            "graphql-federation",
            "router"
          ],
          "trees_url": "https://api.github.com/repos/graphql-hive/router/git/trees{/sha}",
          "updated_at": "2026-02-25T10:55:23Z",
          "url": "https://api.github.com/repos/graphql-hive/router",
          "visibility": "public",
          "watchers": 73,
          "watchers_count": 73,
          "web_commit_signoff_required": false
        },
        "sender": {
          "avatar_url": "https://avatars.githubusercontent.com/u/20847995?v=4",
          "events_url": "https://api.github.com/users/ardatan/events{/privacy}",
          "followers_url": "https://api.github.com/users/ardatan/followers",
          "following_url": "https://api.github.com/users/ardatan/following{/other_user}",
          "gists_url": "https://api.github.com/users/ardatan/gists{/gist_id}",
          "gravatar_id": "",
          "html_url": "https://github.com/ardatan",
          "id": 20847995,
          "login": "ardatan",
          "node_id": "MDQ6VXNlcjIwODQ3OTk1",
          "organizations_url": "https://api.github.com/users/ardatan/orgs",
          "received_events_url": "https://api.github.com/users/ardatan/received_events",
          "repos_url": "https://api.github.com/users/ardatan/repos",
          "site_admin": false,
          "starred_url": "https://api.github.com/users/ardatan/starred{/owner}{/repo}",
          "subscriptions_url": "https://api.github.com/users/ardatan/subscriptions",
          "type": "User",
          "url": "https://api.github.com/users/ardatan",
          "user_view_type": "public"
        }
      },
      "github_job": "docker",
      "github_ref": "refs/pull/628/merge",
      "github_ref_name": "628/merge",
      "github_ref_protected": "false",
      "github_ref_type": "branch",
      "github_repository": "graphql-hive/router",
      "github_repository_id": "891604244",
      "github_repository_owner": "graphql-hive",
      "github_repository_owner_id": "182742256",
      "github_run_attempt": "1",
      "github_run_id": "22393835154",
      "github_run_number": "1597",
      "github_runner_arch": "X64",
      "github_runner_environment": "github-hosted",
      "github_runner_image_os": "ubuntu24",
      "github_runner_image_version": "20260201.15.1",
      "github_runner_name": "GitHub Actions 1000590268",
      "github_runner_os": "Linux",
      "github_runner_tracking_id": "github_f0914dd2-173a-49ec-ace2-07ce9ea5a850",
      "github_server_url": "https://github.com",
      "github_triggering_actor": "ardatan",
      "github_workflow": "build-router",
      "github_workflow_ref": "graphql-hive/router/.github/workflows/build-router.yaml@refs/pull/628/merge",
      "github_workflow_sha": "879dd4a75fc20137b2cbc445c993192e12988699",
      "platform": "linux/amd64"
    }
  }
},
"buildx.build.provenance/linux/arm64": {
  "builder": {
    "id": "https://github.com/graphql-hive/router/actions/runs/22393835154/attempts/1"
  },
  "buildType": "https://mobyproject.org/buildkit@v1",
  "materials": [
    {
      "uri": "pkg:docker/docker/dockerfile@1.21",
      "digest": {
        "sha256": "27f9262d43452075f3c410287a2c43f5ef1bf7ec2bb06e8c9eeb1b8d453087bc"
      }
    },
    {
      "uri": "pkg:docker/gcr.io/distroless/cc-debian12@latest?platform=linux%2Farm64",
      "digest": {
        "sha256": "329e54034ce498f9c6b345044e8f530c6691f99e94a92446f68c0adf9baa8464"
      }
    }
  ],
  "invocation": {
    "configSource": {
      "entryPoint": "router.Dockerfile"
    },
    "parameters": {
      "frontend": "gateway.v0",
      "args": {
        "cmdline": "docker/dockerfile:1.21",
        "label:org.opencontainers.image.created": "2026-02-25T11:09:00.621Z",
        "label:org.opencontainers.image.description": "Open-source (MIT) GraphQL Federation Router. Built with Rust for maximum performance and robustness.",
        "label:org.opencontainers.image.licenses": "MIT",
        "label:org.opencontainers.image.revision": "879dd4a75fc20137b2cbc445c993192e12988699",
        "label:org.opencontainers.image.source": "https://github.com/graphql-hive/router",
        "label:org.opencontainers.image.title": "router",
        "label:org.opencontainers.image.url": "https://github.com/graphql-hive/router",
        "label:org.opencontainers.image.vendor": "theguild",
        "label:org.opencontainers.image.version": "pr-628",
        "source": "docker/dockerfile:1.21"
      },
      "locals": [
        {
          "name": "context"
        },
        {
          "name": "dockerfile"
        }
      ]
    },
    "environment": {
      "github_actor": "ardatan",
      "github_actor_id": "20847995",
      "github_event_name": "pull_request",
      "github_event_payload": {
        "action": "synchronize",
        "after": "ad6a855a4d7374aba01258d15c14583f411db780",
        "before": "a6d5894d2dd3e12989423b9d6c120a38b9c24e59",
        "enterprise": {
          "avatar_url": "https://avatars.githubusercontent.com/b/187753?v=4",
          "created_at": "2024-07-02T08:52:28Z",
          "description": "",
          "html_url": "https://github.com/enterprises/the-guild",
          "id": 187753,
          "name": "The Guild",
          "node_id": "E_kgDOAALdaQ",
          "slug": "the-guild",
          "updated_at": "2026-02-11T08:01:14Z",
          "website_url": "https://the-guild.dev/"
        },
        "number": 628,
        "organization": {
          "avatar_url": "https://avatars.githubusercontent.com/u/182742256?v=4",
          "description": "Schema registry, analytics and gateway for GraphQL federation and other GraphQL APIs.",
          "events_url": "https://api.github.com/orgs/graphql-hive/events",
          "hooks_url": "https://api.github.com/orgs/graphql-hive/hooks",
          "id": 182742256,
          "issues_url": "https://api.github.com/orgs/graphql-hive/issues",
          "login": "graphql-hive",
          "members_url": "https://api.github.com/orgs/graphql-hive/members{/member}",
          "node_id": "O_kgDOCuRs8A",
          "public_members_url": "https://api.github.com/orgs/graphql-hive/public_members{/member}",
          "repos_url": "https://api.github.com/orgs/graphql-hive/repos",
          "url": "https://api.github.com/orgs/graphql-hive"
        },
        "pull_request": {
          "_links": {
            "comments": {
              "href": "https://api.github.com/repos/graphql-hive/router/issues/628/comments"
            },
            "commits": {
              "href": "https://api.github.com/repos/graphql-hive/router/pulls/628/commits"
            },
            "html": {
              "href": "https://github.com/graphql-hive/router/pull/628"
            },
            "issue": {
              "href": "https://api.github.com/repos/graphql-hive/router/issues/628"
            },
            "review_comment": {
              "href": "https://api.github.com/repos/graphql-hive/router/pulls/comments{/number}"
            },
            "review_comments": {
              "href": "https://api.github.com/repos/graphql-hive/router/pulls/628/comments"
            },
            "self": {
              "href": "https://api.github.com/repos/graphql-hive/router/pulls/628"
            },
            "statuses": {
              "href": "https://api.github.com/repos/graphql-hive/router/statuses/ad6a855a4d7374aba01258d15c14583f411db780"
            }
          },
          "active_lock_reason": null,
          "additions": 9071,
          "assignee": null,
          "assignees": [],
          "author_association": "MEMBER",
          "auto_merge": null,
          "base": {
            "label": "graphql-hive:main",
            "ref": "main",
            "repo": {
              "allow_auto_merge": false,
              "allow_forking": true,
              "allow_merge_commit": false,
              "allow_rebase_merge": false,
              "allow_squash_merge": true,
              "allow_update_branch": true,
              "archive_url": "https://api.github.com/repos/graphql-hive/router/{archive_format}{/ref}",
              "archived": false,
              "assignees_url": "https://api.github.com/repos/graphql-hive/router/assignees{/user}",
              "blobs_url": "https://api.github.com/repos/graphql-hive/router/git/blobs{/sha}",
              "branches_url": "https://api.github.com/repos/graphql-hive/router/branches{/branch}",
              "clone_url": "https://github.com/graphql-hive/router.git",
              "collaborators_url": "https://api.github.com/repos/graphql-hive/router/collaborators{/collaborator}",
              "comments_url": "https://api.github.com/repos/graphql-hive/router/comments{/number}",
              "commits_url": "https://api.github.com/repos/graphql-hive/router/commits{/sha}",
              "compare_url": "https://api.github.com/repos/graphql-hive/router/compare/{base}...{head}",
              "contents_url": "https://api.github.com/repos/graphql-hive/router/contents/{+path}",
              "contributors_url": "https://api.github.com/repos/graphql-hive/router/contributors",
              "created_at": "2024-11-20T16:16:12Z",
              "default_branch": "main",
              "delete_branch_on_merge": true,
              "deployments_url": "https://api.github.com/repos/graphql-hive/router/deployments",
              "description": "Open-source (MIT) GraphQL Federation Router. Built with Rust for maximum performance and robustness.",
              "disabled": false,
              "downloads_url": "https://api.github.com/repos/graphql-hive/router/downloads",
              "events_url": "https://api.github.com/repos/graphql-hive/router/events",
              "fork": false,
              "forks": 8,
              "forks_count": 8,
              "forks_url": "https://api.github.com/repos/graphql-hive/router/forks",
              "full_name": "graphql-hive/router",
              "git_commits_url": "https://api.github.com/repos/graphql-hive/router/git/commits{/sha}",
              "git_refs_url": "https://api.github.com/repos/graphql-hive/router/git/refs{/sha}",
              "git_tags_url": "https://api.github.com/repos/graphql-hive/router/git/tags{/sha}",
              "git_url": "git://github.com/graphql-hive/router.git",
              "has_discussions": false,
              "has_downloads": true,
              "has_issues": true,
              "has_pages": false,
              "has_projects": false,
              "has_pull_requests": true,
              "has_wiki": false,
              "homepage": "https://the-guild.dev/graphql/hive/docs/router",
              "hooks_url": "https://api.github.com/repos/graphql-hive/router/hooks",
              "html_url": "https://github.com/graphql-hive/router",
              "id": 891604244,
              "is_template": false,
              "issue_comment_url": "https://api.github.com/repos/graphql-hive/router/issues/comments{/number}",
              "issue_events_url": "https://api.github.com/repos/graphql-hive/router/issues/events{/number}",
              "issues_url": "https://api.github.com/repos/graphql-hive/router/issues{/number}",
              "keys_url": "https://api.github.com/repos/graphql-hive/router/keys{/key_id}",
              "labels_url": "https://api.github.com/repos/graphql-hive/router/labels{/name}",
              "language": "Rust",
              "languages_url": "https://api.github.com/repos/graphql-hive/router/languages",
              "license": {
                "key": "mit",
                "name": "MIT License",
                "node_id": "MDc6TGljZW5zZTEz",
                "spdx_id": "MIT",
                "url": "https://api.github.com/licenses/mit"
              },
              "merge_commit_message": "PR_TITLE",
              "merge_commit_title": "MERGE_MESSAGE",
              "merges_url": "https://api.github.com/repos/graphql-hive/router/merges",
              "milestones_url": "https://api.github.com/repos/graphql-hive/router/milestones{/number}",
              "mirror_url": null,
              "name": "router",
              "node_id": "R_kgDONSTNFA",
              "notifications_url": "https://api.github.com/repos/graphql-hive/router/notifications{?since,all,participating}",
              "open_issues": 58,
              "open_issues_count": 58,
              "owner": {
                "avatar_url": "https://avatars.githubusercontent.com/u/182742256?v=4",
                "events_url": "https://api.github.com/users/graphql-hive/events{/privacy}",
                "followers_url": "https://api.github.com/users/graphql-hive/followers",
                "following_url": "https://api.github.com/users/graphql-hive/following{/other_user}",
                "gists_url": "https://api.github.com/users/graphql-hive/gists{/gist_id}",
                "gravatar_id": "",
                "html_url": "https://github.com/graphql-hive",
                "id": 182742256,
                "login": "graphql-hive",
                "node_id": "O_kgDOCuRs8A",
                "organizations_url": "https://api.github.com/users/graphql-hive/orgs",
                "received_events_url": "https://api.github.com/users/graphql-hive/received_events",
                "repos_url": "https://api.github.com/users/graphql-hive/repos",
                "site_admin": false,
                "starred_url": "https://api.github.com/users/graphql-hive/starred{/owner}{/repo}",
                "subscriptions_url": "https://api.github.com/users/graphql-hive/subscriptions",
                "type": "Organization",
                "url": "https://api.github.com/users/graphql-hive",
                "user_view_type": "public"
              },
              "private": false,
              "pull_request_creation_policy": "all",
              "pulls_url": "https://api.github.com/repos/graphql-hive/router/pulls{/number}",
              "pushed_at": "2026-02-25T10:58:18Z",
              "releases_url": "https://api.github.com/repos/graphql-hive/router/releases{/id}",
              "size": 5097,
              "squash_merge_commit_message": "PR_BODY",
              "squash_merge_commit_title": "PR_TITLE",
              "ssh_url": "git@github.com:graphql-hive/router.git",
              "stargazers_count": 73,
              "stargazers_url": "https://api.github.com/repos/graphql-hive/router/stargazers",
              "statuses_url": "https://api.github.com/repos/graphql-hive/router/statuses/{sha}",
              "subscribers_url": "https://api.github.com/repos/graphql-hive/router/subscribers",
              "subscription_url": "https://api.github.com/repos/graphql-hive/router/subscription",
              "svn_url": "https://github.com/graphql-hive/router",
              "tags_url": "https://api.github.com/repos/graphql-hive/router/tags",
              "teams_url": "https://api.github.com/repos/graphql-hive/router/teams",
              "topics": [
                "apollo-federation",
                "federation",
                "federation-gateway",
                "graphql",
                "graphql-federation",
                "router"
              ],
              "trees_url": "https://api.github.com/repos/graphql-hive/router/git/trees{/sha}",
              "updated_at": "2026-02-25T10:55:23Z",
              "url": "https://api.github.com/repos/graphql-hive/router",
              "use_squash_pr_title_as_default": true,
              "visibility": "public",
              "watchers": 73,
              "watchers_count": 73,
              "web_commit_signoff_required": false
            },
            "sha": "ce3f102b470f424904c5d970fc53a33e5a904b95",
            "user": {
              "avatar_url": "https://avatars.githubusercontent.com/u/182742256?v=4",
              "events_url": "https://api.github.com/users/graphql-hive/events{/privacy}",
              "followers_url": "https://api.github.com/users/graphql-hive/followers",
              "following_url": "https://api.github.com/users/graphql-hive/following{/other_user}",
              "gists_url": "https://api.github.com/users/graphql-hive/gists{/gist_id}",
              "gravatar_id": "",
              "html_url": "https://github.com/graphql-hive",
              "id": 182742256,
              "login": "graphql-hive",
              "node_id": "O_kgDOCuRs8A",
              "organizations_url": "https://api.github.com/users/graphql-hive/orgs",
              "received_events_url": "https://api.github.com/users/graphql-hive/received_events",
              "repos_url": "https://api.github.com/users/graphql-hive/repos",
              "site_admin": false,
              "starred_url": "https://api.github.com/users/graphql-hive/starred{/owner}{/repo}",
              "subscriptions_url": "https://api.github.com/users/graphql-hive/subscriptions",
              "type": "Organization",
              "url": "https://api.github.com/users/graphql-hive",
              "user_view_type": "public"
            }
          },
          "body": "Documentation > https://github.com/graphql-hive/console/pull/7387\r\nPreview of the docs -> https://pr-7387.hive-landing-page.pages.dev/docs/router/guides/extending-the-router\r\nExample plugins -> https://github.com/graphql-hive/router/tree/plugin-system/plugin_examples\r\n\r\nTODO:\r\n- Document why API is implemented in this way and that way (payload.initialize_plugins, OnPluginInitResult type e.g.)\r\n- Documentation updates",
          "changed_files": 213,
          "closed_at": null,
          "comments": 5,
          "comments_url": "https://api.github.com/repos/graphql-hive/router/issues/628/comments",
          "commits": 1,
          "commits_url": "https://api.github.com/repos/graphql-hive/router/pulls/628/commits",
          "created_at": "2025-12-19T14:23:59Z",
          "deletions": 1198,
          "diff_url": "https://github.com/graphql-hive/router/pull/628.diff",
          "draft": false,
          "head": {
            "label": "graphql-hive:plugin-system",
            "ref": "plugin-system",
            "repo": {
              "allow_auto_merge": false,
              "allow_forking": true,
              "allow_merge_commit": false,
              "allow_rebase_merge": false,
              "allow_squash_merge": true,
              "allow_update_branch": true,
              "archive_url": "https://api.github.com/repos/graphql-hive/router/{archive_format}{/ref}",
              "archived": false,
              "assignees_url": "https://api.github.com/repos/graphql-hive/router/assignees{/user}",
              "blobs_url": "https://api.github.com/repos/graphql-hive/router/git/blobs{/sha}",
              "branches_url": "https://api.github.com/repos/graphql-hive/router/branches{/branch}",
              "clone_url": "https://github.com/graphql-hive/router.git",
              "collaborators_url": "https://api.github.com/repos/graphql-hive/router/collaborators{/collaborator}",
              "comments_url": "https://api.github.com/repos/graphql-hive/router/comments{/number}",
              "commits_url": "https://api.github.com/repos/graphql-hive/router/commits{/sha}",
              "compare_url": "https://api.github.com/repos/graphql-hive/router/compare/{base}...{head}",
              "contents_url": "https://api.github.com/repos/graphql-hive/router/contents/{+path}",
              "contributors_url": "https://api.github.com/repos/graphql-hive/router/contributors",
              "created_at": "2024-11-20T16:16:12Z",
              "default_branch": "main",
              "delete_branch_on_merge": true,
              "deployments_url": "https://api.github.com/repos/graphql-hive/router/deployments",
              "description": "Open-source (MIT) GraphQL Federation Router. Built with Rust for maximum performance and robustness.",
              "disabled": false,
              "downloads_url": "https://api.github.com/repos/graphql-hive/router/downloads",
              "events_url": "https://api.github.com/repos/graphql-hive/router/events",
              "fork": false,
              "forks": 8,
              "forks_count": 8,
              "forks_url": "https://api.github.com/repos/graphql-hive/router/forks",
              "full_name": "graphql-hive/router",
              "git_commits_url": "https://api.github.com/repos/graphql-hive/router/git/commits{/sha}",
              "git_refs_url": "https://api.github.com/repos/graphql-hive/router/git/refs{/sha}",
              "git_tags_url": "https://api.github.com/repos/graphql-hive/router/git/tags{/sha}",
              "git_url": "git://github.com/graphql-hive/router.git",
              "has_discussions": false,
              "has_downloads": true,
              "has_issues": true,
              "has_pages": false,
              "has_projects": false,
              "has_pull_requests": true,
              "has_wiki": false,
              "homepage": "https://the-guild.dev/graphql/hive/docs/router",
              "hooks_url": "https://api.github.com/repos/graphql-hive/router/hooks",
              "html_url": "https://github.com/graphql-hive/router",
              "id": 891604244,
              "is_template": false,
              "issue_comment_url": "https://api.github.com/repos/graphql-hive/router/issues/comments{/number}",
              "issue_events_url": "https://api.github.com/repos/graphql-hive/router/issues/events{/number}",
              "issues_url": "https://api.github.com/repos/graphql-hive/router/issues{/number}",
              "keys_url": "https://api.github.com/repos/graphql-hive/router/keys{/key_id}",
              "labels_url": "https://api.github.com/repos/graphql-hive/router/labels{/name}",
              "language": "Rust",
              "languages_url": "https://api.github.com/repos/graphql-hive/router/languages",
              "license": {
                "key": "mit",
                "name": "MIT License",
                "node_id": "MDc6TGljZW5zZTEz",
                "spdx_id": "MIT",
                "url": "https://api.github.com/licenses/mit"
              },
              "merge_commit_message": "PR_TITLE",
              "merge_commit_title": "MERGE_MESSAGE",
              "merges_url": "https://api.github.com/repos/graphql-hive/router/merges",
              "milestones_url": "https://api.github.com/repos/graphql-hive/router/milestones{/number}",
              "mirror_url": null,
              "name": "router",
              "node_id": "R_kgDONSTNFA",
              "notifications_url": "https://api.github.com/repos/graphql-hive/router/notifications{?since,all,participating}",
              "open_issues": 58,
              "open_issues_count": 58,
              "owner": {
                "avatar_url": "https://avatars.githubusercontent.com/u/182742256?v=4",
                "events_url": "https://api.github.com/users/graphql-hive/events{/privacy}",
                "followers_url": "https://api.github.com/users/graphql-hive/followers",
                "following_url": "https://api.github.com/users/graphql-hive/following{/other_user}",
                "gists_url": "https://api.github.com/users/graphql-hive/gists{/gist_id}",
                "gravatar_id": "",
                "html_url": "https://github.com/graphql-hive",
                "id": 182742256,
                "login": "graphql-hive",
                "node_id": "O_kgDOCuRs8A",
                "organizations_url": "https://api.github.com/users/graphql-hive/orgs",
                "received_events_url": "https://api.github.com/users/graphql-hive/received_events",
                "repos_url": "https://api.github.com/users/graphql-hive/repos",
                "site_admin": false,
                "starred_url": "https://api.github.com/users/graphql-hive/starred{/owner}{/repo}",
                "subscriptions_url": "https://api.github.com/users/graphql-hive/subscriptions",
                "type": "Organization",
                "url": "https://api.github.com/users/graphql-hive",
                "user_view_type": "public"
              },
              "private": false,
              "pull_request_creation_policy": "all",
              "pulls_url": "https://api.github.com/repos/graphql-hive/router/pulls{/number}",
              "pushed_at": "2026-02-25T10:58:18Z",
              "releases_url": "https://api.github.com/repos/graphql-hive/router/releases{/id}",
              "size": 5097,
              "squash_merge_commit_message": "PR_BODY",
              "squash_merge_commit_title": "PR_TITLE",
              "ssh_url": "git@github.com:graphql-hive/router.git",
              "stargazers_count": 73,
              "stargazers_url": "https://api.github.com/repos/graphql-hive/router/stargazers",
              "statuses_url": "https://api.github.com/repos/graphql-hive/router/statuses/{sha}",
              "subscribers_url": "https://api.github.com/repos/graphql-hive/router/subscribers",
              "subscription_url": "https://api.github.com/repos/graphql-hive/router/subscription",
              "svn_url": "https://github.com/graphql-hive/router",
              "tags_url": "https://api.github.com/repos/graphql-hive/router/tags",
              "teams_url": "https://api.github.com/repos/graphql-hive/router/teams",
              "topics": [
                "apollo-federation",
                "federation",
                "federation-gateway",
                "graphql",
                "graphql-federation",
                "router"
              ],
              "trees_url": "https://api.github.com/repos/graphql-hive/router/git/trees{/sha}",
              "updated_at": "2026-02-25T10:55:23Z",
              "url": "https://api.github.com/repos/graphql-hive/router",
              "use_squash_pr_title_as_default": true,
              "visibility": "public",
              "watchers": 73,
              "watchers_count": 73,
              "web_commit_signoff_required": false
            },
            "sha": "ad6a855a4d7374aba01258d15c14583f411db780",
            "user": {
              "avatar_url": "https://avatars.githubusercontent.com/u/182742256?v=4",
              "events_url": "https://api.github.com/users/graphql-hive/events{/privacy}",
              "followers_url": "https://api.github.com/users/graphql-hive/followers",
              "following_url": "https://api.github.com/users/graphql-hive/following{/other_user}",
              "gists_url": "https://api.github.com/users/graphql-hive/gists{/gist_id}",
              "gravatar_id": "",
              "html_url": "https://github.com/graphql-hive",
              "id": 182742256,
              "login": "graphql-hive",
              "node_id": "O_kgDOCuRs8A",
              "organizations_url": "https://api.github.com/users/graphql-hive/orgs",
              "received_events_url": "https://api.github.com/users/graphql-hive/received_events",
              "repos_url": "https://api.github.com/users/graphql-hive/repos",
              "site_admin": false,
              "starred_url": "https://api.github.com/users/graphql-hive/starred{/owner}{/repo}",
              "subscriptions_url": "https://api.github.com/users/graphql-hive/subscriptions",
              "type": "Organization",
              "url": "https://api.github.com/users/graphql-hive",
              "user_view_type": "public"
            }
          },
          "html_url": "https://github.com/graphql-hive/router/pull/628",
          "id": 3117772466,
          "issue_url": "https://api.github.com/repos/graphql-hive/router/issues/628",
          "labels": [],
          "locked": false,
          "maintainer_can_modify": false,
          "merge_commit_sha": "1eff976ef7e8e4be9c3dbfde8567c2406156fb6f",
          "mergeable": null,
          "mergeable_state": "unknown",
          "merged": false,
          "merged_at": null,
          "merged_by": null,
          "milestone": null,
          "node_id": "PR_kwDONSTNFM651W6y",
          "number": 628,
          "patch_url": "https://github.com/graphql-hive/router/pull/628.patch",
          "rebaseable": null,
          "requested_reviewers": [],
          "requested_teams": [],
          "review_comment_url": "https://api.github.com/repos/graphql-hive/router/pulls/comments{/number}",
          "review_comments": 124,
          "review_comments_url": "https://api.github.com/repos/graphql-hive/router/pulls/628/comments",
          "state": "open",
          "statuses_url": "https://api.github.com/repos/graphql-hive/router/statuses/ad6a855a4d7374aba01258d15c14583f411db780",
          "title": "Plugin System",
          "updated_at": "2026-02-25T10:58:19Z",
          "url": "https://api.github.com/repos/graphql-hive/router/pulls/628",
          "user": {
            "avatar_url": "https://avatars.githubusercontent.com/u/20847995?v=4",
            "events_url": "https://api.github.com/users/ardatan/events{/privacy}",
            "followers_url": "https://api.github.com/users/ardatan/followers",
            "following_url": "https://api.github.com/users/ardatan/following{/other_user}",
            "gists_url": "https://api.github.com/users/ardatan/gists{/gist_id}",
            "gravatar_id": "",
            "html_url": "https://github.com/ardatan",
            "id": 20847995,
            "login": "ardatan",
            "node_id": "MDQ6VXNlcjIwODQ3OTk1",
            "organizations_url": "https://api.github.com/users/ardatan/orgs",
            "received_events_url": "https://api.github.com/users/ardatan/received_events",
            "repos_url": "https://api.github.com/users/ardatan/repos",
            "site_admin": false,
            "starred_url": "https://api.github.com/users/ardatan/starred{/owner}{/repo}",
            "subscriptions_url": "https://api.github.com/users/ardatan/subscriptions",
            "type": "User",
            "url": "https://api.github.com/users/ardatan",
            "user_view_type": "public"
          }
        },
        "repository": {
          "allow_forking": true,
          "archive_url": "https://api.github.com/repos/graphql-hive/router/{archive_format}{/ref}",
          "archived": false,
          "assignees_url": "https://api.github.com/repos/graphql-hive/router/assignees{/user}",
          "blobs_url": "https://api.github.com/repos/graphql-hive/router/git/blobs{/sha}",
          "branches_url": "https://api.github.com/repos/graphql-hive/router/branches{/branch}",
          "clone_url": "https://github.com/graphql-hive/router.git",
          "collaborators_url": "https://api.github.com/repos/graphql-hive/router/collaborators{/collaborator}",
          "comments_url": "https://api.github.com/repos/graphql-hive/router/comments{/number}",
          "commits_url": "https://api.github.com/repos/graphql-hive/router/commits{/sha}",
          "compare_url": "https://api.github.com/repos/graphql-hive/router/compare/{base}...{head}",
          "contents_url": "https://api.github.com/repos/graphql-hive/router/contents/{+path}",
          "contributors_url": "https://api.github.com/repos/graphql-hive/router/contributors",
          "created_at": "2024-11-20T16:16:12Z",
          "custom_properties": {
            "vanta_production_branch_name": "main"
          },
          "default_branch": "main",
          "deployments_url": "https://api.github.com/repos/graphql-hive/router/deployments",
          "description": "Open-source (MIT) GraphQL Federation Router. Built with Rust for maximum performance and robustness.",
          "disabled": false,
          "downloads_url": "https://api.github.com/repos/graphql-hive/router/downloads",
          "events_url": "https://api.github.com/repos/graphql-hive/router/events",
          "fork": false,
          "forks": 8,
          "forks_count": 8,
          "forks_url": "https://api.github.com/repos/graphql-hive/router/forks",
          "full_name": "graphql-hive/router",
          "git_commits_url": "https://api.github.com/repos/graphql-hive/router/git/commits{/sha}",
          "git_refs_url": "https://api.github.com/repos/graphql-hive/router/git/refs{/sha}",
          "git_tags_url": "https://api.github.com/repos/graphql-hive/router/git/tags{/sha}",
          "git_url": "git://github.com/graphql-hive/router.git",
          "has_discussions": false,
          "has_downloads": true,
          "has_issues": true,
          "has_pages": false,
          "has_projects": false,
          "has_pull_requests": true,
          "has_wiki": false,
          "homepage": "https://the-guild.dev/graphql/hive/docs/router",
          "hooks_url": "https://api.github.com/repos/graphql-hive/router/hooks",
          "html_url": "https://github.com/graphql-hive/router",
          "id": 891604244,
          "is_template": false,
          "issue_comment_url": "https://api.github.com/repos/graphql-hive/router/issues/comments{/number}",
          "issue_events_url": "https://api.github.com/repos/graphql-hive/router/issues/events{/number}",
          "issues_url": "https://api.github.com/repos/graphql-hive/router/issues{/number}",
          "keys_url": "https://api.github.com/repos/graphql-hive/router/keys{/key_id}",
          "labels_url": "https://api.github.com/repos/graphql-hive/router/labels{/name}",
          "language": "Rust",
          "languages_url": "https://api.github.com/repos/graphql-hive/router/languages",
          "license": {
            "key": "mit",
            "name": "MIT License",
            "node_id": "MDc6TGljZW5zZTEz",
            "spdx_id": "MIT",
            "url": "https://api.github.com/licenses/mit"
          },
          "merges_url": "https://api.github.com/repos/graphql-hive/router/merges",
          "milestones_url": "https://api.github.com/repos/graphql-hive/router/milestones{/number}",
          "mirror_url": null,
          "name": "router",
          "node_id": "R_kgDONSTNFA",
          "notifications_url": "https://api.github.com/repos/graphql-hive/router/notifications{?since,all,participating}",
          "open_issues": 58,
          "open_issues_count": 58,
          "owner": {
            "avatar_url": "https://avatars.githubusercontent.com/u/182742256?v=4",
            "events_url": "https://api.github.com/users/graphql-hive/events{/privacy}",
            "followers_url": "https://api.github.com/users/graphql-hive/followers",
            "following_url": "https://api.github.com/users/graphql-hive/following{/other_user}",
            "gists_url": "https://api.github.com/users/graphql-hive/gists{/gist_id}",
            "gravatar_id": "",
            "html_url": "https://github.com/graphql-hive",
            "id": 182742256,
            "login": "graphql-hive",
            "node_id": "O_kgDOCuRs8A",
            "organizations_url": "https://api.github.com/users/graphql-hive/orgs",
            "received_events_url": "https://api.github.com/users/graphql-hive/received_events",
            "repos_url": "https://api.github.com/users/graphql-hive/repos",
            "site_admin": false,
            "starred_url": "https://api.github.com/users/graphql-hive/starred{/owner}{/repo}",
            "subscriptions_url": "https://api.github.com/users/graphql-hive/subscriptions",
            "type": "Organization",
            "url": "https://api.github.com/users/graphql-hive",
            "user_view_type": "public"
          },
          "private": false,
          "pull_request_creation_policy": "all",
          "pulls_url": "https://api.github.com/repos/graphql-hive/router/pulls{/number}",
          "pushed_at": "2026-02-25T10:58:18Z",
          "releases_url": "https://api.github.com/repos/graphql-hive/router/releases{/id}",
          "size": 5097,
          "ssh_url": "git@github.com:graphql-hive/router.git",
          "stargazers_count": 73,
          "stargazers_url": "https://api.github.com/repos/graphql-hive/router/stargazers",
          "statuses_url": "https://api.github.com/repos/graphql-hive/router/statuses/{sha}",
          "subscribers_url": "https://api.github.com/repos/graphql-hive/router/subscribers",
          "subscription_url": "https://api.github.com/repos/graphql-hive/router/subscription",
          "svn_url": "https://github.com/graphql-hive/router",
          "tags_url": "https://api.github.com/repos/graphql-hive/router/tags",
          "teams_url": "https://api.github.com/repos/graphql-hive/router/teams",
          "topics": [
            "apollo-federation",
            "federation",
            "federation-gateway",
            "graphql",
            "graphql-federation",
            "router"
          ],
          "trees_url": "https://api.github.com/repos/graphql-hive/router/git/trees{/sha}",
          "updated_at": "2026-02-25T10:55:23Z",
          "url": "https://api.github.com/repos/graphql-hive/router",
          "visibility": "public",
          "watchers": 73,
          "watchers_count": 73,
          "web_commit_signoff_required": false
        },
        "sender": {
          "avatar_url": "https://avatars.githubusercontent.com/u/20847995?v=4",
          "events_url": "https://api.github.com/users/ardatan/events{/privacy}",
          "followers_url": "https://api.github.com/users/ardatan/followers",
          "following_url": "https://api.github.com/users/ardatan/following{/other_user}",
          "gists_url": "https://api.github.com/users/ardatan/gists{/gist_id}",
          "gravatar_id": "",
          "html_url": "https://github.com/ardatan",
          "id": 20847995,
          "login": "ardatan",
          "node_id": "MDQ6VXNlcjIwODQ3OTk1",
          "organizations_url": "https://api.github.com/users/ardatan/orgs",
          "received_events_url": "https://api.github.com/users/ardatan/received_events",
          "repos_url": "https://api.github.com/users/ardatan/repos",
          "site_admin": false,
          "starred_url": "https://api.github.com/users/ardatan/starred{/owner}{/repo}",
          "subscriptions_url": "https://api.github.com/users/ardatan/subscriptions",
          "type": "User",
          "url": "https://api.github.com/users/ardatan",
          "user_view_type": "public"
        }
      },
      "github_job": "docker",
      "github_ref": "refs/pull/628/merge",
      "github_ref_name": "628/merge",
      "github_ref_protected": "false",
      "github_ref_type": "branch",
      "github_repository": "graphql-hive/router",
      "github_repository_id": "891604244",
      "github_repository_owner": "graphql-hive",
      "github_repository_owner_id": "182742256",
      "github_run_attempt": "1",
      "github_run_id": "22393835154",
      "github_run_number": "1597",
      "github_runner_arch": "X64",
      "github_runner_environment": "github-hosted",
      "github_runner_image_os": "ubuntu24",
      "github_runner_image_version": "20260201.15.1",
      "github_runner_name": "GitHub Actions 1000590268",
      "github_runner_os": "Linux",
      "github_runner_tracking_id": "github_f0914dd2-173a-49ec-ace2-07ce9ea5a850",
      "github_server_url": "https://github.com",
      "github_triggering_actor": "ardatan",
      "github_workflow": "build-router",
      "github_workflow_ref": "graphql-hive/router/.github/workflows/build-router.yaml@refs/pull/628/merge",
      "github_workflow_sha": "879dd4a75fc20137b2cbc445c993192e12988699",
      "platform": "linux/amd64"
    }
  }
},
"buildx.build.ref": "builder-3a4ac71c-f634-4d31-acf3-eb6292305f2a/builder-3a4ac71c-f634-4d31-acf3-eb6292305f2a0/hgza85m3l7zglfqo17k7sp5l8",
"containerimage.descriptor": {
  "mediaType": "application/vnd.oci.image.index.v1+json",
  "digest": "sha256:1a59ac52a8866bb2fac3b9ff3ae0118f09db1e0ca5175b7b5396cbb4754b4a1a",
  "size": 1609
},
"containerimage.digest": "sha256:1a59ac52a8866bb2fac3b9ff3ae0118f09db1e0ca5175b7b5396cbb4754b4a1a",
"image.name": "ghcr.io/graphql-hive/router:pr-628,ghcr.io/graphql-hive/router:sha-879dd4a"
}

@ardatan ardatan force-pushed the plugin-system branch 4 times, most recently from 61deae4 to 2ba4c52 Compare January 7, 2026 13:12
@ardatan ardatan force-pushed the plugin-system branch 3 times, most recently from df0377d to a4fb2d6 Compare January 12, 2026 15:20
kamilkisiela added a commit that referenced this pull request Jan 14, 2026
Extracted from #628

Introduces `pub fn from_message_and_code` to create an error with an
error code in the extensions which reduce the code a lot in different
places.
Helpers that take `&str` or `String` are replaced with `Into<String>` so
that extra `.to_string()` or `.into()` calls for different variations of
string can be avoided.

Benefits;
- No need for `.to_string()`, `.clone()` and `.into()` for different
variations of string
```diff
let message_ref: &str = ...;
let code_ref: &str = ...;

let error_from_refs = GraphQLError::from_message_and_code(
- message_ref.to_string()
+ message_ref
- code_ref.to_string()
+ code_ref
);
```
- No need to call `GraphQLErrorExtensions::from_code` thanks to
`message_and_code` helper
```diff
- GraphQLError::from_message_and_extensions(
+ GraphQLError::from_message_and_code(
  message,
- GraphQLErrorExtensions::from_code(code
+ code
)
```

---------

Co-authored-by: Kamil Kisiela <kamil.kisiela@gmail.com>
kamilkisiela pushed a commit that referenced this pull request Jan 14, 2026
Extracted from #628

- `SubgraphExecutor` now returns `SubgraphResponse` that has the
deserialized response in it with `bytes: Bytes` to be stored in the
response storage later on.
- `HTTPSubgraphExecutor` is now responsible of deserialization instead
of Plan executor.
- No need for `Arc<Bytes>` because `Bytes` already uses `Arc` internally
so it has 0 cost of cloning

Why?
In the plugin system's `on_subgraph_execute` hook is expected to return
`SubgraphResponse` which is basically `data`, `errors` and `extensions`
(of course together with an optional `bytes` and `headers`).
In order to have a better DX, I wanted to make this flow's return value
`SubgraphResponse` while keeping `HttpResponse` as
`on_subgraph_http_request`'s return value.
In this way `SubgraphResponse` becomes HTTP-independent, and it will be
easy to handle errors and etc without generating bytes and doing
deserialization and serialization work etc for prebuilt responses.
For example `graphql_error_to_bytes` is no longer needed with this. It
can be just `SubgraphResponse { errors: vec![error],
...Default:default()`

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@ardatan ardatan force-pushed the plugin-system branch 8 times, most recently from f5ee85a to ee3641a Compare January 20, 2026 13:58
ardatan added a commit that referenced this pull request Jan 22, 2026
…cutor (#652)

Extracted from #628

Combining with #651 , the aim
is to reduce the number of extra structs.

Today, `PlanExecutionOutput` which is the return type of
`execute_query_plan` in `executor/execution/plan.rs`, returns `body:
Vec<u8>` and `headers: http::HeaderMap`.
Then, in the `router/pipeline`, `ResponseBuilder` is called with
`Bytes::from` of `PlanExecutionOutput.body` and
`PlanExecutionOutput.headers` is converted to `ntex::HeaderMap`, then
`content_type` is set here.

With this PR, the response aggregator is sent with
`PlanExecutionOutput`, and during the response build, the response
headers aggregator sets the headers into `ResponseBuilder` directly.

So now `modify_client_headers` helper accepts `ResponseBuilder`, not
`http:HeaderMap`. And since this throws `HeaderPropagationError` in the
pipeline executor, I had to add `HeaderPropagationError` to
`PipelineError`.

I also extracted `PipelineError` to `FailedExecutionResult` logic to a
`From` trait so that other future implementations that serializes and
sets the body in a different way can use it and serialize
`FailedExecutionResult` on their own.
Currently it is used here only ->
https://github.com/graphql-hive/router/pull/652/changes#diff-f3dc2f2d579374645281d6950414266d8984195dbf45c00f0a754ceca8550aadR95

----
Update:
After recent changes, I see that `project_by_operation` is used for
`dry_run` but it is actually unnecessary as we just need to serialize
`extensions` which has nothing to do with projection since it uses
`sonic_rs::Value`.
@ardatan
Copy link
Member Author

ardatan commented Feb 17, 2026

@gemini-code-assist review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive plugin system to the router, enabling custom logic injection at various stages of the request lifecycle. Key changes include adding numerous new plugin examples (e.g., Apollo Sandbox, APQ, Async Auth, Multipart, Response Cache, Root Field Limit, Usage Reporting) to the workspace and Cargo.lock, along with their dependencies. The core router logic has been refactored to integrate this system, moving authorization metadata and background task management to an internal crate (hive_router_internal). The router's entry point now accepts a PluginRegistry, and a PluginService middleware is added to the Ntex application to manage plugin hooks. Several pipeline stages (graphql_params, parse, validation, query_plan, execute, subgraph_execute, subgraph_http_request, supergraph_reload, graphql_error, shutdown) have been updated to incorporate plugin hooks, allowing plugins to modify payloads, short-circuit execution with custom responses, or register callbacks for post-processing. The e2e tests and subgraphs were also updated to support these new plugin functionalities, including adding a Mutation type for file uploads and oneOf tests. Review comments highlighted critical areas for improvement: the unwrap() call in the incoming request deduplication plugin was flagged as dangerous and a potential denial-of-service vulnerability, recommending graceful error handling; the use of StatusCode::PAYLOAD_TOO_LARGE for a @oneOf validation error was deemed semantically incorrect, suggesting StatusCode::BAD_REQUEST; and an inconsistent error code (TOO_MANY_ROOT_FIELDS) in the @oneOf validation rule was noted, recommending TOO_MANY_FIELDS_SET_IN_ONEOF for clarity and consistency.

@ardatan ardatan force-pushed the plugin-system branch 3 times, most recently from 784e21a to 0cffc2b Compare February 24, 2026 10:33
@ardatan ardatan force-pushed the plugin-system branch 4 times, most recently from 039e0e5 to a6d5894 Compare February 25, 2026 10:55
@dotansimha dotansimha changed the title Plugin System feat(router): plugin system Feb 25, 2026
@ardatan ardatan merged commit ae38bbe into main Feb 25, 2026
29 checks passed
@ardatan ardatan deleted the plugin-system branch February 25, 2026 11:15
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.

3 participants