[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-apollo-graphql-apollo-router-plugin-creator":3,"mdc-58i2g0-key":37,"related-org-apollo-graphql-apollo-router-plugin-creator":1539,"related-repo-apollo-graphql-apollo-router-plugin-creator":1703},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":24,"repoUrl":25,"updatedAt":26,"license":27,"forks":28,"topics":29,"repo":32,"sourceUrl":35,"mdContent":36},"apollo-router-plugin-creator","write Apollo Router Rust plugins","Guide for writing Apollo Router native Rust plugins. Use this skill when: (1) users want to create a new router plugin, (2) users want to add service hooks (router_service, supergraph_service, execution_service, subgraph_service), (3) users want to modify an existing router plugin, (4) users need to understand router plugin patterns or the request lifecycle. (5) triggers on requests like \"create a new plugin\", \"add a router plugin\", \"modify the X plugin\", or \"add subgraph_service hook\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"apollo-graphql","Apollo GraphQL","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fapollo-graphql.png","apollographql",[13,17,18,21],{"name":14,"slug":15,"type":16},"GraphQL","graphql","tag",{"name":9,"slug":8,"type":16},{"name":19,"slug":20,"type":16},"Plugin Development","plugin-development",{"name":22,"slug":23,"type":16},"Rust","rust",97,"https:\u002F\u002Fgithub.com\u002Fapollographql\u002Fskills","2026-04-06T18:01:27.176974","MIT",11,[30,31,15],"agent-skills","apollo",{"repoUrl":25,"stars":24,"forks":28,"topics":33,"description":34},[30,31,15],"Apollo GraphQL Agent Skills","https:\u002F\u002Fgithub.com\u002Fapollographql\u002Fskills\u002Ftree\u002FHEAD\u002Fskills\u002Fapollo-router-plugin-creator","---\nname: apollo-router-plugin-creator\ndescription: >\n  Guide for writing Apollo Router native Rust plugins. Use this skill when:\n  (1) users want to create a new router plugin,\n  (2) users want to add service hooks (router_service, supergraph_service, execution_service, subgraph_service),\n  (3) users want to modify an existing router plugin,\n  (4) users need to understand router plugin patterns or the request lifecycle.\n  (5) triggers on requests like \"create a new plugin\", \"add a router plugin\", \"modify the X plugin\", or \"add subgraph_service hook\".\nlicense: MIT\nallowed-tools: Read Write Edit Glob Grep\nmetadata:\n  author: apollographql\n  version: \"1.0.0\"\n  compatibility: \"Requires Apollo Router with native plugin support\"\n---\n\n# Apollo Router Plugin Creator\n\nCreate native Rust plugins for Apollo Router.\n\n## Request Lifecycle\n\n```\n┌────────┐             ┌────────────────┐                                   ┌────────────────────┐               ┌───────────────────┐       ┌─────────────────────┐\n│ Client │             │ Router Service │                                   │ Supergraph Service │               │ Execution Service │       │ Subgraph Service(s) │\n└────┬───┘             └────────┬───────┘                                   └──────────┬─────────┘               └─────────┬─────────┘       └──────────┬──────────┘\n     │                          │                                                      │                                   │                            │\n     │      Sends request       │                                                      │                                   │                            │\n     │──────────────────────────▶                                                      │                                   │                            │\n     │                          │                                                      │                                   │                            │\n     │                          │  Converts raw HTTP request to GraphQL\u002FJSON request   │                                   │                            │\n     │                          │──────────────────────────────────────────────────────▶                                   │                            │\n     │                          │                                                      │                                   │                            │\n     │                          │                                                      │  Initiates query plan execution   │                            │\n     │                          │                                                      │───────────────────────────────────▶                            │\n     │                          │                                                      │                                   │                            │\n     │                          │                                                      │                               ┌par [Initiates sub-operation]───────┐\n     │                          │                                                      │                               │   │                            │   │\n     │                          │                                                      │                               │   │  Initiates sub-operation   │   │\n     │                          │                                                      │                               │   │────────────────────────────▶   │\n     │                          │                                                      │                               │   │                            │   │\n     │                          │                                                      │                               ├[Initiates sub-operation]╌╌╌╌╌╌╌╌╌╌╌┤\n     │                          │                                                      │                               │   │                            │   │\n     │                          │                                                      │                               │   │  Initiates sub-operation   │   │\n     │                          │                                                      │                               │   │────────────────────────────▶   │\n     │                          │                                                      │                               │   │                            │   │\n     │                          │                                                      │                               ├[Initiates sub-operation]╌╌╌╌╌╌╌╌╌╌╌┤\n     │                          │                                                      │                               │   │                            │   │\n     │                          │                                                      │                               │   │  Initiates sub-operation   │   │\n     │                          │                                                      │                               │   │────────────────────────────▶   │\n     │                          │                                                      │                               │   │                            │   │\n     │                          │                                                      │                               └────────────────────────────────────┘\n     │                          │                                                      │                                   │                            │\n     │                          │                                                      │  Assembles and returns response   │                            │\n     │                          │                                                      ◀╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌│                            │\n     │                          │                                                      │                                   │                            │\n     │                          │            Returns GraphQL\u002FJSON response             │                                   │                            │\n     │                          ◀╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌│                                   │                            │\n     │                          │                                                      │                                   │                            │\n     │  Returns HTTP response   │                                                      │                                   │                            │\n     ◀╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌│                                                      │                                   │                            │\n     │                          │                                                      │                                   │                            │\n┌────┴───┐             ┌────────┴───────┐                                   ┌──────────┴─────────┐               ┌─────────┴─────────┐       ┌──────────┴──────────┐\n│ Client │             │ Router Service │                                   │ Supergraph Service │               │ Execution Service │       │ Subgraph Service(s) │\n└────────┘             └────────────────┘                                   └────────────────────┘               └───────────────────┘       └─────────────────────┘\n```\n\n## Service Hooks\n\n### Service Overview\n\n| Service              | Description                                                                                                                                                                                                                                                                                                                                                                                                                                           |\n|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `router_service`     | Runs at the very beginning and very end of the HTTP request lifecycle.For example, JWT authentication is performed within the RouterService.Define router_service if your customization needs to interact with HTTP context and headers. It doesn't support access to the body property                                                                                                                                                               |\n| `supergraph_service` | Runs at the very beginning and very end of the GraphQL request lifecycle.Define supergraph_service if your customization needs to interact with the GraphQL request or the GraphQL response. For example, you can add a check for anonymous queries.                                                                                                                                                                                                  |\n| `execution_service`  | Handles initiating the execution of a query plan after it's been generated.Define execution_service if your customization includes logic to govern execution (for example, if you want to block a particular query based on a policy decision).                                                                                                                                                                                                       |\n| `subgraph_service`   | Handles communication between the router and your subgraphs.Define subgraph_service to configure this communication (for example, to dynamically add HTTP headers to pass to a subgraph).Whereas other services are called once per client request, this service is called once per subgraph request that's required to resolve the client's request. Each call is passed a subgraph parameter that indicates the name of the corresponding subgraph. |\n\n**Signatures:**\n```rust\nfn router_service(&self, service: router::BoxService) -> router::BoxService\nfn supergraph_service(&self, service: supergraph::BoxService) -> supergraph::BoxService\nfn execution_service(&self, service: execution::BoxService) -> execution::BoxService\nfn subgraph_service(&self, name: &str, service: subgraph::BoxService) -> subgraph::BoxService\n```\n\n### Individual Hooks (Tower Layers)\n\nUse `ServiceBuilder` to compose these hooks within any service:\n\n| Hook                      | Purpose                                      | Sync\u002FAsync |\n|---------------------------|----------------------------------------------|------------|\n| `map_request(fn)`         | Transform request before proceeding          | Sync       |\n| `map_response(fn)`        | Transform response before returning          | Sync       |\n| `checkpoint(fn)`          | Validate\u002Ffilter, can short-circuit           | Sync       |\n| `checkpoint_async(fn)`    | Async validation, can short-circuit          | Async      |\n| `buffered()`              | Enable service cloning (needed for async)    | -          |\n| `instrument(span)`        | Add tracing span around service              | -          |\n| `rate_limit(num, period)` | Control request throughput                   | -          |\n| `timeout(duration)`       | Set operation time limit                     | -          |\n\n### Choosing a Service Hook\n\n**By data needed:**\n- HTTP headers only → `router_service`\n- GraphQL query\u002Fvariables → `supergraph_service`\n- Query plan → `execution_service`\n- Per-subgraph control → `subgraph_service`\n\n**By timing:**\n- Before GraphQL parsing → `router_service` request\n- After parsing, before planning → `supergraph_service` request\n- After planning, before execution → `execution_service` request\n- Before\u002Fafter each subgraph call → `subgraph_service`\n- Final response to client → `router_service` response\n\nSee [references\u002Fservice-hooks.md](references\u002Fservice-hooks.md) for implementation patterns.\n\n## Quick Start\n\n### Step 1: Create Plugin File\n\nCreate a new file `src\u002Fplugins\u002Fmy_plugin.rs` with required imports:\n\n```rust\nuse std::ops::ControlFlow;\nuse apollo_router::plugin::{Plugin, PluginInit};\nuse apollo_router::register_plugin;\nuse apollo_router::services::{router, subgraph, supergraph};\nuse schemars::JsonSchema;\nuse serde::Deserialize;\nuse tower::{BoxError, ServiceBuilder, ServiceExt};\n\nconst PLUGIN_NAME: &str = \"my_plugin\";\n```\n\n### Step 2: Define Configuration Struct\n\nEvery plugin needs a configuration struct with `Deserialize` and `JsonSchema` derives. The `JsonSchema` enables configuration validation in editors:\n\n```rust\n#[derive(Debug, Clone, Default, Deserialize, JsonSchema)]\nstruct MyPluginConfig {\n  \u002F\u002F\u002F Enable the plugin\n  enabled: bool,\n  \u002F\u002F Add other configuration fields as needed\n}\n```\n\n### Step 3: Define Plugin Struct\n\n```rust\n#[derive(Debug)]\nstruct MyPlugin {\n  configuration: MyPluginConfig,\n}\n```\n\n### Step 4: Implement Plugin Trait\n\nImplement the `Plugin` trait with the required `Config` type and `new` constructor:\n\n```rust\n#[async_trait::async_trait]\nimpl Plugin for MyPlugin {\n  type Config = MyPluginConfig;\n\n  async fn new(init: PluginInit\u003CSelf::Config>) -> Result\u003CSelf, BoxError> {\n    Ok(MyPlugin { configuration: init.config })\n  }\n\n  \u002F\u002F Add service hooks based on your needs (see \"Choosing a Service Hook\" section)\n}\n```\n\n### Step 5: Add Service Hooks\n\nChoose which service(s) to hook based on your requirements, see [Service Overview](#service-overview) for details.\n\nExample service hook:\n```rust\nfn supergraph_service(&self, service: supergraph::BoxService) -> supergraph::BoxService {\n  if !self.configuration.enabled {\n    return service;\n  }\n\n  ServiceBuilder::new()\n    .map_request(|req| { \u002F* transform request *\u002F req })\n    .map_response(|res| { \u002F* transform response *\u002F res })\n    .service(service)\n    .boxed()\n}\n```\n\n### Step 6: Register Plugin\n\nAt the bottom of your plugin file, register it with the router:\n\n```rust\nregister_plugin!(\"acme\", \"my_plugin\", MyPlugin);\n```\n\n### Step 7: Add Module to mod.rs\n\nIn `src\u002Fplugins\u002Fmod.rs`, add your module:\n\n```rust\npub mod my_plugin;\n```\n\n### Step 8: Configure in YAML\n\nEnable your plugin in the router configuration:\n\n```yaml\nplugins:\n  acme.my_plugin:\n    enabled: true\n```\n\n## Common Patterns\n\nFor implementation patterns and code examples, see [references\u002Fservice-hooks.md](references\u002Fservice-hooks.md):\n- Enable\u002Fdisable pattern\n- Request\u002Fresponse transformation (`map_request`, `map_response`)\n- Checkpoint (early return\u002Fshort-circuit)\n- Context passing between hooks\n- Async operations (`checkpoint_async`, `buffered`)\n- Error response builders\n\n## Examples\n\n### Apollo Router Examples\n\nLocated in the [Apollo Router plugins directory](https:\u002F\u002Fgithub.com\u002Fapollographql\u002Frouter\u002Ftree\u002Fdev\u002Fapollo-router\u002Fsrc\u002Fplugins):\n\n| Plugin                 | Service Hook           | Pattern           | Description                 |\n|------------------------|------------------------|-------------------|-----------------------------|\n| `forbid_mutations.rs`  | `execution_service`    | checkpoint        | Simple gate on query plan   |\n| `expose_query_plan.rs` | execution + supergraph | Context passing   | Multi-service coordination  |\n| `cors.rs`              | `router_service`       | HTTP layer        | CORS handling at HTTP level |\n| `headers\u002F`             | `subgraph_service`     | Layer composition | Complex header manipulation |\n\nFor full code examples and testing patterns, see [references\u002Fexamples.md](references\u002Fexamples.md).\n\n## Prerequisites\n\nIt is advised to have the [rust-best-practices](https:\u002F\u002Fskills.sh\u002Fapollographql\u002Fskills\u002Frust-best-practices) skill installed for writing idiomatic Rust code when developing router plugins. If installed, follow those best practices when generating or modifying plugin code.\n\n## Resources\n\n- [references\u002Fservice-hooks.md](references\u002Fservice-hooks.md) - Detailed service hook implementations\n- [references\u002Fexisting-plugins.md](references\u002Fexisting-plugins.md) - Index of existing plugins\n- [references\u002Fexamples.md](references\u002Fexamples.md) - Full code examples and testing patterns\n- Apollo Router plugins: https:\u002F\u002Fgithub.com\u002Fapollographql\u002Frouter\u002Ftree\u002Fdev\u002Fapollo-router\u002Fsrc\u002Fplugins",{"data":38,"body":43},{"name":4,"description":6,"license":27,"allowed-tools":39,"metadata":40},"Read Write Edit Glob Grep",{"author":11,"version":41,"compatibility":42},"1.0.0","Requires Apollo Router with native plugin support",{"type":44,"children":45},"root",[46,54,60,67,80,86,93,189,198,244,250,263,461,467,475,520,528,587,600,606,612,625,710,716,744,799,805,843,849,878,963,969,981,986,1078,1084,1089,1103,1109,1122,1136,1142,1147,1202,1208,1218,1281,1287,1293,1307,1454,1466,1472,1486,1492,1533],{"type":47,"tag":48,"props":49,"children":50},"element","h1",{"id":4},[51],{"type":52,"value":53},"text","Apollo Router Plugin Creator",{"type":47,"tag":55,"props":56,"children":57},"p",{},[58],{"type":52,"value":59},"Create native Rust plugins for Apollo Router.",{"type":47,"tag":61,"props":62,"children":64},"h2",{"id":63},"request-lifecycle",[65],{"type":52,"value":66},"Request Lifecycle",{"type":47,"tag":68,"props":69,"children":73},"pre",{"className":70,"code":72,"language":52},[71],"language-text","┌────────┐             ┌────────────────┐                                   ┌────────────────────┐               ┌───────────────────┐       ┌─────────────────────┐\n│ Client │             │ Router Service │                                   │ Supergraph Service │               │ Execution Service │       │ Subgraph Service(s) │\n└────┬───┘             └────────┬───────┘                                   └──────────┬─────────┘               └─────────┬─────────┘       └──────────┬──────────┘\n     │                          │                                                      │                                   │                            │\n     │      Sends request       │                                                      │                                   │                            │\n     │──────────────────────────▶                                                      │                                   │                            │\n     │                          │                                                      │                                   │                            │\n     │                          │  Converts raw HTTP request to GraphQL\u002FJSON request   │                                   │                            │\n     │                          │──────────────────────────────────────────────────────▶                                   │                            │\n     │                          │                                                      │                                   │                            │\n     │                          │                                                      │  Initiates query plan execution   │                            │\n     │                          │                                                      │───────────────────────────────────▶                            │\n     │                          │                                                      │                                   │                            │\n     │                          │                                                      │                               ┌par [Initiates sub-operation]───────┐\n     │                          │                                                      │                               │   │                            │   │\n     │                          │                                                      │                               │   │  Initiates sub-operation   │   │\n     │                          │                                                      │                               │   │────────────────────────────▶   │\n     │                          │                                                      │                               │   │                            │   │\n     │                          │                                                      │                               ├[Initiates sub-operation]╌╌╌╌╌╌╌╌╌╌╌┤\n     │                          │                                                      │                               │   │                            │   │\n     │                          │                                                      │                               │   │  Initiates sub-operation   │   │\n     │                          │                                                      │                               │   │────────────────────────────▶   │\n     │                          │                                                      │                               │   │                            │   │\n     │                          │                                                      │                               ├[Initiates sub-operation]╌╌╌╌╌╌╌╌╌╌╌┤\n     │                          │                                                      │                               │   │                            │   │\n     │                          │                                                      │                               │   │  Initiates sub-operation   │   │\n     │                          │                                                      │                               │   │────────────────────────────▶   │\n     │                          │                                                      │                               │   │                            │   │\n     │                          │                                                      │                               └────────────────────────────────────┘\n     │                          │                                                      │                                   │                            │\n     │                          │                                                      │  Assembles and returns response   │                            │\n     │                          │                                                      ◀╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌│                            │\n     │                          │                                                      │                                   │                            │\n     │                          │            Returns GraphQL\u002FJSON response             │                                   │                            │\n     │                          ◀╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌│                                   │                            │\n     │                          │                                                      │                                   │                            │\n     │  Returns HTTP response   │                                                      │                                   │                            │\n     ◀╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌│                                                      │                                   │                            │\n     │                          │                                                      │                                   │                            │\n┌────┴───┐             ┌────────┴───────┐                                   ┌──────────┴─────────┐               ┌─────────┴─────────┐       ┌──────────┴──────────┐\n│ Client │             │ Router Service │                                   │ Supergraph Service │               │ Execution Service │       │ Subgraph Service(s) │\n└────────┘             └────────────────┘                                   └────────────────────┘               └───────────────────┘       └─────────────────────┘\n",[74],{"type":47,"tag":75,"props":76,"children":78},"code",{"__ignoreMap":77},"",[79],{"type":52,"value":72},{"type":47,"tag":61,"props":81,"children":83},{"id":82},"service-hooks",[84],{"type":52,"value":85},"Service Hooks",{"type":47,"tag":87,"props":88,"children":90},"h3",{"id":89},"service-overview",[91],{"type":52,"value":92},"Service Overview",{"type":47,"tag":94,"props":95,"children":96},"table",{},[97,116],{"type":47,"tag":98,"props":99,"children":100},"thead",{},[101],{"type":47,"tag":102,"props":103,"children":104},"tr",{},[105,111],{"type":47,"tag":106,"props":107,"children":108},"th",{},[109],{"type":52,"value":110},"Service",{"type":47,"tag":106,"props":112,"children":113},{},[114],{"type":52,"value":115},"Description",{"type":47,"tag":117,"props":118,"children":119},"tbody",{},[120,138,155,172],{"type":47,"tag":102,"props":121,"children":122},{},[123,133],{"type":47,"tag":124,"props":125,"children":126},"td",{},[127],{"type":47,"tag":75,"props":128,"children":130},{"className":129},[],[131],{"type":52,"value":132},"router_service",{"type":47,"tag":124,"props":134,"children":135},{},[136],{"type":52,"value":137},"Runs at the very beginning and very end of the HTTP request lifecycle.For example, JWT authentication is performed within the RouterService.Define router_service if your customization needs to interact with HTTP context and headers. It doesn't support access to the body property",{"type":47,"tag":102,"props":139,"children":140},{},[141,150],{"type":47,"tag":124,"props":142,"children":143},{},[144],{"type":47,"tag":75,"props":145,"children":147},{"className":146},[],[148],{"type":52,"value":149},"supergraph_service",{"type":47,"tag":124,"props":151,"children":152},{},[153],{"type":52,"value":154},"Runs at the very beginning and very end of the GraphQL request lifecycle.Define supergraph_service if your customization needs to interact with the GraphQL request or the GraphQL response. For example, you can add a check for anonymous queries.",{"type":47,"tag":102,"props":156,"children":157},{},[158,167],{"type":47,"tag":124,"props":159,"children":160},{},[161],{"type":47,"tag":75,"props":162,"children":164},{"className":163},[],[165],{"type":52,"value":166},"execution_service",{"type":47,"tag":124,"props":168,"children":169},{},[170],{"type":52,"value":171},"Handles initiating the execution of a query plan after it's been generated.Define execution_service if your customization includes logic to govern execution (for example, if you want to block a particular query based on a policy decision).",{"type":47,"tag":102,"props":173,"children":174},{},[175,184],{"type":47,"tag":124,"props":176,"children":177},{},[178],{"type":47,"tag":75,"props":179,"children":181},{"className":180},[],[182],{"type":52,"value":183},"subgraph_service",{"type":47,"tag":124,"props":185,"children":186},{},[187],{"type":52,"value":188},"Handles communication between the router and your subgraphs.Define subgraph_service to configure this communication (for example, to dynamically add HTTP headers to pass to a subgraph).Whereas other services are called once per client request, this service is called once per subgraph request that's required to resolve the client's request. Each call is passed a subgraph parameter that indicates the name of the corresponding subgraph.",{"type":47,"tag":55,"props":190,"children":191},{},[192],{"type":47,"tag":193,"props":194,"children":195},"strong",{},[196],{"type":52,"value":197},"Signatures:",{"type":47,"tag":68,"props":199,"children":202},{"className":200,"code":201,"language":23,"meta":77,"style":77},"language-rust shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","fn router_service(&self, service: router::BoxService) -> router::BoxService\nfn supergraph_service(&self, service: supergraph::BoxService) -> supergraph::BoxService\nfn execution_service(&self, service: execution::BoxService) -> execution::BoxService\nfn subgraph_service(&self, name: &str, service: subgraph::BoxService) -> subgraph::BoxService\n",[203],{"type":47,"tag":75,"props":204,"children":205},{"__ignoreMap":77},[206,217,226,235],{"type":47,"tag":207,"props":208,"children":211},"span",{"class":209,"line":210},"line",1,[212],{"type":47,"tag":207,"props":213,"children":214},{},[215],{"type":52,"value":216},"fn router_service(&self, service: router::BoxService) -> router::BoxService\n",{"type":47,"tag":207,"props":218,"children":220},{"class":209,"line":219},2,[221],{"type":47,"tag":207,"props":222,"children":223},{},[224],{"type":52,"value":225},"fn supergraph_service(&self, service: supergraph::BoxService) -> supergraph::BoxService\n",{"type":47,"tag":207,"props":227,"children":229},{"class":209,"line":228},3,[230],{"type":47,"tag":207,"props":231,"children":232},{},[233],{"type":52,"value":234},"fn execution_service(&self, service: execution::BoxService) -> execution::BoxService\n",{"type":47,"tag":207,"props":236,"children":238},{"class":209,"line":237},4,[239],{"type":47,"tag":207,"props":240,"children":241},{},[242],{"type":52,"value":243},"fn subgraph_service(&self, name: &str, service: subgraph::BoxService) -> subgraph::BoxService\n",{"type":47,"tag":87,"props":245,"children":247},{"id":246},"individual-hooks-tower-layers",[248],{"type":52,"value":249},"Individual Hooks (Tower Layers)",{"type":47,"tag":55,"props":251,"children":252},{},[253,255,261],{"type":52,"value":254},"Use ",{"type":47,"tag":75,"props":256,"children":258},{"className":257},[],[259],{"type":52,"value":260},"ServiceBuilder",{"type":52,"value":262}," to compose these hooks within any service:",{"type":47,"tag":94,"props":264,"children":265},{},[266,287],{"type":47,"tag":98,"props":267,"children":268},{},[269],{"type":47,"tag":102,"props":270,"children":271},{},[272,277,282],{"type":47,"tag":106,"props":273,"children":274},{},[275],{"type":52,"value":276},"Hook",{"type":47,"tag":106,"props":278,"children":279},{},[280],{"type":52,"value":281},"Purpose",{"type":47,"tag":106,"props":283,"children":284},{},[285],{"type":52,"value":286},"Sync\u002FAsync",{"type":47,"tag":117,"props":288,"children":289},{},[290,312,333,354,376,398,419,440],{"type":47,"tag":102,"props":291,"children":292},{},[293,302,307],{"type":47,"tag":124,"props":294,"children":295},{},[296],{"type":47,"tag":75,"props":297,"children":299},{"className":298},[],[300],{"type":52,"value":301},"map_request(fn)",{"type":47,"tag":124,"props":303,"children":304},{},[305],{"type":52,"value":306},"Transform request before proceeding",{"type":47,"tag":124,"props":308,"children":309},{},[310],{"type":52,"value":311},"Sync",{"type":47,"tag":102,"props":313,"children":314},{},[315,324,329],{"type":47,"tag":124,"props":316,"children":317},{},[318],{"type":47,"tag":75,"props":319,"children":321},{"className":320},[],[322],{"type":52,"value":323},"map_response(fn)",{"type":47,"tag":124,"props":325,"children":326},{},[327],{"type":52,"value":328},"Transform response before returning",{"type":47,"tag":124,"props":330,"children":331},{},[332],{"type":52,"value":311},{"type":47,"tag":102,"props":334,"children":335},{},[336,345,350],{"type":47,"tag":124,"props":337,"children":338},{},[339],{"type":47,"tag":75,"props":340,"children":342},{"className":341},[],[343],{"type":52,"value":344},"checkpoint(fn)",{"type":47,"tag":124,"props":346,"children":347},{},[348],{"type":52,"value":349},"Validate\u002Ffilter, can short-circuit",{"type":47,"tag":124,"props":351,"children":352},{},[353],{"type":52,"value":311},{"type":47,"tag":102,"props":355,"children":356},{},[357,366,371],{"type":47,"tag":124,"props":358,"children":359},{},[360],{"type":47,"tag":75,"props":361,"children":363},{"className":362},[],[364],{"type":52,"value":365},"checkpoint_async(fn)",{"type":47,"tag":124,"props":367,"children":368},{},[369],{"type":52,"value":370},"Async validation, can short-circuit",{"type":47,"tag":124,"props":372,"children":373},{},[374],{"type":52,"value":375},"Async",{"type":47,"tag":102,"props":377,"children":378},{},[379,388,393],{"type":47,"tag":124,"props":380,"children":381},{},[382],{"type":47,"tag":75,"props":383,"children":385},{"className":384},[],[386],{"type":52,"value":387},"buffered()",{"type":47,"tag":124,"props":389,"children":390},{},[391],{"type":52,"value":392},"Enable service cloning (needed for async)",{"type":47,"tag":124,"props":394,"children":395},{},[396],{"type":52,"value":397},"-",{"type":47,"tag":102,"props":399,"children":400},{},[401,410,415],{"type":47,"tag":124,"props":402,"children":403},{},[404],{"type":47,"tag":75,"props":405,"children":407},{"className":406},[],[408],{"type":52,"value":409},"instrument(span)",{"type":47,"tag":124,"props":411,"children":412},{},[413],{"type":52,"value":414},"Add tracing span around service",{"type":47,"tag":124,"props":416,"children":417},{},[418],{"type":52,"value":397},{"type":47,"tag":102,"props":420,"children":421},{},[422,431,436],{"type":47,"tag":124,"props":423,"children":424},{},[425],{"type":47,"tag":75,"props":426,"children":428},{"className":427},[],[429],{"type":52,"value":430},"rate_limit(num, period)",{"type":47,"tag":124,"props":432,"children":433},{},[434],{"type":52,"value":435},"Control request throughput",{"type":47,"tag":124,"props":437,"children":438},{},[439],{"type":52,"value":397},{"type":47,"tag":102,"props":441,"children":442},{},[443,452,457],{"type":47,"tag":124,"props":444,"children":445},{},[446],{"type":47,"tag":75,"props":447,"children":449},{"className":448},[],[450],{"type":52,"value":451},"timeout(duration)",{"type":47,"tag":124,"props":453,"children":454},{},[455],{"type":52,"value":456},"Set operation time limit",{"type":47,"tag":124,"props":458,"children":459},{},[460],{"type":52,"value":397},{"type":47,"tag":87,"props":462,"children":464},{"id":463},"choosing-a-service-hook",[465],{"type":52,"value":466},"Choosing a Service Hook",{"type":47,"tag":55,"props":468,"children":469},{},[470],{"type":47,"tag":193,"props":471,"children":472},{},[473],{"type":52,"value":474},"By data needed:",{"type":47,"tag":476,"props":477,"children":478},"ul",{},[479,490,500,510],{"type":47,"tag":480,"props":481,"children":482},"li",{},[483,485],{"type":52,"value":484},"HTTP headers only → ",{"type":47,"tag":75,"props":486,"children":488},{"className":487},[],[489],{"type":52,"value":132},{"type":47,"tag":480,"props":491,"children":492},{},[493,495],{"type":52,"value":494},"GraphQL query\u002Fvariables → ",{"type":47,"tag":75,"props":496,"children":498},{"className":497},[],[499],{"type":52,"value":149},{"type":47,"tag":480,"props":501,"children":502},{},[503,505],{"type":52,"value":504},"Query plan → ",{"type":47,"tag":75,"props":506,"children":508},{"className":507},[],[509],{"type":52,"value":166},{"type":47,"tag":480,"props":511,"children":512},{},[513,515],{"type":52,"value":514},"Per-subgraph control → ",{"type":47,"tag":75,"props":516,"children":518},{"className":517},[],[519],{"type":52,"value":183},{"type":47,"tag":55,"props":521,"children":522},{},[523],{"type":47,"tag":193,"props":524,"children":525},{},[526],{"type":52,"value":527},"By timing:",{"type":47,"tag":476,"props":529,"children":530},{},[531,543,554,565,575],{"type":47,"tag":480,"props":532,"children":533},{},[534,536,541],{"type":52,"value":535},"Before GraphQL parsing → ",{"type":47,"tag":75,"props":537,"children":539},{"className":538},[],[540],{"type":52,"value":132},{"type":52,"value":542}," request",{"type":47,"tag":480,"props":544,"children":545},{},[546,548,553],{"type":52,"value":547},"After parsing, before planning → ",{"type":47,"tag":75,"props":549,"children":551},{"className":550},[],[552],{"type":52,"value":149},{"type":52,"value":542},{"type":47,"tag":480,"props":555,"children":556},{},[557,559,564],{"type":52,"value":558},"After planning, before execution → ",{"type":47,"tag":75,"props":560,"children":562},{"className":561},[],[563],{"type":52,"value":166},{"type":52,"value":542},{"type":47,"tag":480,"props":566,"children":567},{},[568,570],{"type":52,"value":569},"Before\u002Fafter each subgraph call → ",{"type":47,"tag":75,"props":571,"children":573},{"className":572},[],[574],{"type":52,"value":183},{"type":47,"tag":480,"props":576,"children":577},{},[578,580,585],{"type":52,"value":579},"Final response to client → ",{"type":47,"tag":75,"props":581,"children":583},{"className":582},[],[584],{"type":52,"value":132},{"type":52,"value":586}," response",{"type":47,"tag":55,"props":588,"children":589},{},[590,592,598],{"type":52,"value":591},"See ",{"type":47,"tag":593,"props":594,"children":596},"a",{"href":595},"references\u002Fservice-hooks.md",[597],{"type":52,"value":595},{"type":52,"value":599}," for implementation patterns.",{"type":47,"tag":61,"props":601,"children":603},{"id":602},"quick-start",[604],{"type":52,"value":605},"Quick Start",{"type":47,"tag":87,"props":607,"children":609},{"id":608},"step-1-create-plugin-file",[610],{"type":52,"value":611},"Step 1: Create Plugin File",{"type":47,"tag":55,"props":613,"children":614},{},[615,617,623],{"type":52,"value":616},"Create a new file ",{"type":47,"tag":75,"props":618,"children":620},{"className":619},[],[621],{"type":52,"value":622},"src\u002Fplugins\u002Fmy_plugin.rs",{"type":52,"value":624}," with required imports:",{"type":47,"tag":68,"props":626,"children":628},{"className":200,"code":627,"language":23,"meta":77,"style":77},"use std::ops::ControlFlow;\nuse apollo_router::plugin::{Plugin, PluginInit};\nuse apollo_router::register_plugin;\nuse apollo_router::services::{router, subgraph, supergraph};\nuse schemars::JsonSchema;\nuse serde::Deserialize;\nuse tower::{BoxError, ServiceBuilder, ServiceExt};\n\nconst PLUGIN_NAME: &str = \"my_plugin\";\n",[629],{"type":47,"tag":75,"props":630,"children":631},{"__ignoreMap":77},[632,640,648,656,664,673,682,691,701],{"type":47,"tag":207,"props":633,"children":634},{"class":209,"line":210},[635],{"type":47,"tag":207,"props":636,"children":637},{},[638],{"type":52,"value":639},"use std::ops::ControlFlow;\n",{"type":47,"tag":207,"props":641,"children":642},{"class":209,"line":219},[643],{"type":47,"tag":207,"props":644,"children":645},{},[646],{"type":52,"value":647},"use apollo_router::plugin::{Plugin, PluginInit};\n",{"type":47,"tag":207,"props":649,"children":650},{"class":209,"line":228},[651],{"type":47,"tag":207,"props":652,"children":653},{},[654],{"type":52,"value":655},"use apollo_router::register_plugin;\n",{"type":47,"tag":207,"props":657,"children":658},{"class":209,"line":237},[659],{"type":47,"tag":207,"props":660,"children":661},{},[662],{"type":52,"value":663},"use apollo_router::services::{router, subgraph, supergraph};\n",{"type":47,"tag":207,"props":665,"children":667},{"class":209,"line":666},5,[668],{"type":47,"tag":207,"props":669,"children":670},{},[671],{"type":52,"value":672},"use schemars::JsonSchema;\n",{"type":47,"tag":207,"props":674,"children":676},{"class":209,"line":675},6,[677],{"type":47,"tag":207,"props":678,"children":679},{},[680],{"type":52,"value":681},"use serde::Deserialize;\n",{"type":47,"tag":207,"props":683,"children":685},{"class":209,"line":684},7,[686],{"type":47,"tag":207,"props":687,"children":688},{},[689],{"type":52,"value":690},"use tower::{BoxError, ServiceBuilder, ServiceExt};\n",{"type":47,"tag":207,"props":692,"children":694},{"class":209,"line":693},8,[695],{"type":47,"tag":207,"props":696,"children":698},{"emptyLinePlaceholder":697},true,[699],{"type":52,"value":700},"\n",{"type":47,"tag":207,"props":702,"children":704},{"class":209,"line":703},9,[705],{"type":47,"tag":207,"props":706,"children":707},{},[708],{"type":52,"value":709},"const PLUGIN_NAME: &str = \"my_plugin\";\n",{"type":47,"tag":87,"props":711,"children":713},{"id":712},"step-2-define-configuration-struct",[714],{"type":52,"value":715},"Step 2: Define Configuration Struct",{"type":47,"tag":55,"props":717,"children":718},{},[719,721,727,729,735,737,742],{"type":52,"value":720},"Every plugin needs a configuration struct with ",{"type":47,"tag":75,"props":722,"children":724},{"className":723},[],[725],{"type":52,"value":726},"Deserialize",{"type":52,"value":728}," and ",{"type":47,"tag":75,"props":730,"children":732},{"className":731},[],[733],{"type":52,"value":734},"JsonSchema",{"type":52,"value":736}," derives. The ",{"type":47,"tag":75,"props":738,"children":740},{"className":739},[],[741],{"type":52,"value":734},{"type":52,"value":743}," enables configuration validation in editors:",{"type":47,"tag":68,"props":745,"children":747},{"className":200,"code":746,"language":23,"meta":77,"style":77},"#[derive(Debug, Clone, Default, Deserialize, JsonSchema)]\nstruct MyPluginConfig {\n  \u002F\u002F\u002F Enable the plugin\n  enabled: bool,\n  \u002F\u002F Add other configuration fields as needed\n}\n",[748],{"type":47,"tag":75,"props":749,"children":750},{"__ignoreMap":77},[751,759,767,775,783,791],{"type":47,"tag":207,"props":752,"children":753},{"class":209,"line":210},[754],{"type":47,"tag":207,"props":755,"children":756},{},[757],{"type":52,"value":758},"#[derive(Debug, Clone, Default, Deserialize, JsonSchema)]\n",{"type":47,"tag":207,"props":760,"children":761},{"class":209,"line":219},[762],{"type":47,"tag":207,"props":763,"children":764},{},[765],{"type":52,"value":766},"struct MyPluginConfig {\n",{"type":47,"tag":207,"props":768,"children":769},{"class":209,"line":228},[770],{"type":47,"tag":207,"props":771,"children":772},{},[773],{"type":52,"value":774},"  \u002F\u002F\u002F Enable the plugin\n",{"type":47,"tag":207,"props":776,"children":777},{"class":209,"line":237},[778],{"type":47,"tag":207,"props":779,"children":780},{},[781],{"type":52,"value":782},"  enabled: bool,\n",{"type":47,"tag":207,"props":784,"children":785},{"class":209,"line":666},[786],{"type":47,"tag":207,"props":787,"children":788},{},[789],{"type":52,"value":790},"  \u002F\u002F Add other configuration fields as needed\n",{"type":47,"tag":207,"props":792,"children":793},{"class":209,"line":675},[794],{"type":47,"tag":207,"props":795,"children":796},{},[797],{"type":52,"value":798},"}\n",{"type":47,"tag":87,"props":800,"children":802},{"id":801},"step-3-define-plugin-struct",[803],{"type":52,"value":804},"Step 3: Define Plugin Struct",{"type":47,"tag":68,"props":806,"children":808},{"className":200,"code":807,"language":23,"meta":77,"style":77},"#[derive(Debug)]\nstruct MyPlugin {\n  configuration: MyPluginConfig,\n}\n",[809],{"type":47,"tag":75,"props":810,"children":811},{"__ignoreMap":77},[812,820,828,836],{"type":47,"tag":207,"props":813,"children":814},{"class":209,"line":210},[815],{"type":47,"tag":207,"props":816,"children":817},{},[818],{"type":52,"value":819},"#[derive(Debug)]\n",{"type":47,"tag":207,"props":821,"children":822},{"class":209,"line":219},[823],{"type":47,"tag":207,"props":824,"children":825},{},[826],{"type":52,"value":827},"struct MyPlugin {\n",{"type":47,"tag":207,"props":829,"children":830},{"class":209,"line":228},[831],{"type":47,"tag":207,"props":832,"children":833},{},[834],{"type":52,"value":835},"  configuration: MyPluginConfig,\n",{"type":47,"tag":207,"props":837,"children":838},{"class":209,"line":237},[839],{"type":47,"tag":207,"props":840,"children":841},{},[842],{"type":52,"value":798},{"type":47,"tag":87,"props":844,"children":846},{"id":845},"step-4-implement-plugin-trait",[847],{"type":52,"value":848},"Step 4: Implement Plugin Trait",{"type":47,"tag":55,"props":850,"children":851},{},[852,854,860,862,868,870,876],{"type":52,"value":853},"Implement the ",{"type":47,"tag":75,"props":855,"children":857},{"className":856},[],[858],{"type":52,"value":859},"Plugin",{"type":52,"value":861}," trait with the required ",{"type":47,"tag":75,"props":863,"children":865},{"className":864},[],[866],{"type":52,"value":867},"Config",{"type":52,"value":869}," type and ",{"type":47,"tag":75,"props":871,"children":873},{"className":872},[],[874],{"type":52,"value":875},"new",{"type":52,"value":877}," constructor:",{"type":47,"tag":68,"props":879,"children":881},{"className":200,"code":880,"language":23,"meta":77,"style":77},"#[async_trait::async_trait]\nimpl Plugin for MyPlugin {\n  type Config = MyPluginConfig;\n\n  async fn new(init: PluginInit\u003CSelf::Config>) -> Result\u003CSelf, BoxError> {\n    Ok(MyPlugin { configuration: init.config })\n  }\n\n  \u002F\u002F Add service hooks based on your needs (see \"Choosing a Service Hook\" section)\n}\n",[882],{"type":47,"tag":75,"props":883,"children":884},{"__ignoreMap":77},[885,893,901,909,916,924,932,940,947,955],{"type":47,"tag":207,"props":886,"children":887},{"class":209,"line":210},[888],{"type":47,"tag":207,"props":889,"children":890},{},[891],{"type":52,"value":892},"#[async_trait::async_trait]\n",{"type":47,"tag":207,"props":894,"children":895},{"class":209,"line":219},[896],{"type":47,"tag":207,"props":897,"children":898},{},[899],{"type":52,"value":900},"impl Plugin for MyPlugin {\n",{"type":47,"tag":207,"props":902,"children":903},{"class":209,"line":228},[904],{"type":47,"tag":207,"props":905,"children":906},{},[907],{"type":52,"value":908},"  type Config = MyPluginConfig;\n",{"type":47,"tag":207,"props":910,"children":911},{"class":209,"line":237},[912],{"type":47,"tag":207,"props":913,"children":914},{"emptyLinePlaceholder":697},[915],{"type":52,"value":700},{"type":47,"tag":207,"props":917,"children":918},{"class":209,"line":666},[919],{"type":47,"tag":207,"props":920,"children":921},{},[922],{"type":52,"value":923},"  async fn new(init: PluginInit\u003CSelf::Config>) -> Result\u003CSelf, BoxError> {\n",{"type":47,"tag":207,"props":925,"children":926},{"class":209,"line":675},[927],{"type":47,"tag":207,"props":928,"children":929},{},[930],{"type":52,"value":931},"    Ok(MyPlugin { configuration: init.config })\n",{"type":47,"tag":207,"props":933,"children":934},{"class":209,"line":684},[935],{"type":47,"tag":207,"props":936,"children":937},{},[938],{"type":52,"value":939},"  }\n",{"type":47,"tag":207,"props":941,"children":942},{"class":209,"line":693},[943],{"type":47,"tag":207,"props":944,"children":945},{"emptyLinePlaceholder":697},[946],{"type":52,"value":700},{"type":47,"tag":207,"props":948,"children":949},{"class":209,"line":703},[950],{"type":47,"tag":207,"props":951,"children":952},{},[953],{"type":52,"value":954},"  \u002F\u002F Add service hooks based on your needs (see \"Choosing a Service Hook\" section)\n",{"type":47,"tag":207,"props":956,"children":958},{"class":209,"line":957},10,[959],{"type":47,"tag":207,"props":960,"children":961},{},[962],{"type":52,"value":798},{"type":47,"tag":87,"props":964,"children":966},{"id":965},"step-5-add-service-hooks",[967],{"type":52,"value":968},"Step 5: Add Service Hooks",{"type":47,"tag":55,"props":970,"children":971},{},[972,974,979],{"type":52,"value":973},"Choose which service(s) to hook based on your requirements, see ",{"type":47,"tag":593,"props":975,"children":977},{"href":976},"#service-overview",[978],{"type":52,"value":92},{"type":52,"value":980}," for details.",{"type":47,"tag":55,"props":982,"children":983},{},[984],{"type":52,"value":985},"Example service hook:",{"type":47,"tag":68,"props":987,"children":989},{"className":200,"code":988,"language":23,"meta":77,"style":77},"fn supergraph_service(&self, service: supergraph::BoxService) -> supergraph::BoxService {\n  if !self.configuration.enabled {\n    return service;\n  }\n\n  ServiceBuilder::new()\n    .map_request(|req| { \u002F* transform request *\u002F req })\n    .map_response(|res| { \u002F* transform response *\u002F res })\n    .service(service)\n    .boxed()\n}\n",[990],{"type":47,"tag":75,"props":991,"children":992},{"__ignoreMap":77},[993,1001,1009,1017,1024,1031,1039,1047,1055,1063,1071],{"type":47,"tag":207,"props":994,"children":995},{"class":209,"line":210},[996],{"type":47,"tag":207,"props":997,"children":998},{},[999],{"type":52,"value":1000},"fn supergraph_service(&self, service: supergraph::BoxService) -> supergraph::BoxService {\n",{"type":47,"tag":207,"props":1002,"children":1003},{"class":209,"line":219},[1004],{"type":47,"tag":207,"props":1005,"children":1006},{},[1007],{"type":52,"value":1008},"  if !self.configuration.enabled {\n",{"type":47,"tag":207,"props":1010,"children":1011},{"class":209,"line":228},[1012],{"type":47,"tag":207,"props":1013,"children":1014},{},[1015],{"type":52,"value":1016},"    return service;\n",{"type":47,"tag":207,"props":1018,"children":1019},{"class":209,"line":237},[1020],{"type":47,"tag":207,"props":1021,"children":1022},{},[1023],{"type":52,"value":939},{"type":47,"tag":207,"props":1025,"children":1026},{"class":209,"line":666},[1027],{"type":47,"tag":207,"props":1028,"children":1029},{"emptyLinePlaceholder":697},[1030],{"type":52,"value":700},{"type":47,"tag":207,"props":1032,"children":1033},{"class":209,"line":675},[1034],{"type":47,"tag":207,"props":1035,"children":1036},{},[1037],{"type":52,"value":1038},"  ServiceBuilder::new()\n",{"type":47,"tag":207,"props":1040,"children":1041},{"class":209,"line":684},[1042],{"type":47,"tag":207,"props":1043,"children":1044},{},[1045],{"type":52,"value":1046},"    .map_request(|req| { \u002F* transform request *\u002F req })\n",{"type":47,"tag":207,"props":1048,"children":1049},{"class":209,"line":693},[1050],{"type":47,"tag":207,"props":1051,"children":1052},{},[1053],{"type":52,"value":1054},"    .map_response(|res| { \u002F* transform response *\u002F res })\n",{"type":47,"tag":207,"props":1056,"children":1057},{"class":209,"line":703},[1058],{"type":47,"tag":207,"props":1059,"children":1060},{},[1061],{"type":52,"value":1062},"    .service(service)\n",{"type":47,"tag":207,"props":1064,"children":1065},{"class":209,"line":957},[1066],{"type":47,"tag":207,"props":1067,"children":1068},{},[1069],{"type":52,"value":1070},"    .boxed()\n",{"type":47,"tag":207,"props":1072,"children":1073},{"class":209,"line":28},[1074],{"type":47,"tag":207,"props":1075,"children":1076},{},[1077],{"type":52,"value":798},{"type":47,"tag":87,"props":1079,"children":1081},{"id":1080},"step-6-register-plugin",[1082],{"type":52,"value":1083},"Step 6: Register Plugin",{"type":47,"tag":55,"props":1085,"children":1086},{},[1087],{"type":52,"value":1088},"At the bottom of your plugin file, register it with the router:",{"type":47,"tag":68,"props":1090,"children":1092},{"className":200,"code":1091,"language":23,"meta":77,"style":77},"register_plugin!(\"acme\", \"my_plugin\", MyPlugin);\n",[1093],{"type":47,"tag":75,"props":1094,"children":1095},{"__ignoreMap":77},[1096],{"type":47,"tag":207,"props":1097,"children":1098},{"class":209,"line":210},[1099],{"type":47,"tag":207,"props":1100,"children":1101},{},[1102],{"type":52,"value":1091},{"type":47,"tag":87,"props":1104,"children":1106},{"id":1105},"step-7-add-module-to-modrs",[1107],{"type":52,"value":1108},"Step 7: Add Module to mod.rs",{"type":47,"tag":55,"props":1110,"children":1111},{},[1112,1114,1120],{"type":52,"value":1113},"In ",{"type":47,"tag":75,"props":1115,"children":1117},{"className":1116},[],[1118],{"type":52,"value":1119},"src\u002Fplugins\u002Fmod.rs",{"type":52,"value":1121},", add your module:",{"type":47,"tag":68,"props":1123,"children":1125},{"className":200,"code":1124,"language":23,"meta":77,"style":77},"pub mod my_plugin;\n",[1126],{"type":47,"tag":75,"props":1127,"children":1128},{"__ignoreMap":77},[1129],{"type":47,"tag":207,"props":1130,"children":1131},{"class":209,"line":210},[1132],{"type":47,"tag":207,"props":1133,"children":1134},{},[1135],{"type":52,"value":1124},{"type":47,"tag":87,"props":1137,"children":1139},{"id":1138},"step-8-configure-in-yaml",[1140],{"type":52,"value":1141},"Step 8: Configure in YAML",{"type":47,"tag":55,"props":1143,"children":1144},{},[1145],{"type":52,"value":1146},"Enable your plugin in the router configuration:",{"type":47,"tag":68,"props":1148,"children":1152},{"className":1149,"code":1150,"language":1151,"meta":77,"style":77},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","plugins:\n  acme.my_plugin:\n    enabled: true\n","yaml",[1153],{"type":47,"tag":75,"props":1154,"children":1155},{"__ignoreMap":77},[1156,1171,1183],{"type":47,"tag":207,"props":1157,"children":1158},{"class":209,"line":210},[1159,1165],{"type":47,"tag":207,"props":1160,"children":1162},{"style":1161},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[1163],{"type":52,"value":1164},"plugins",{"type":47,"tag":207,"props":1166,"children":1168},{"style":1167},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[1169],{"type":52,"value":1170},":\n",{"type":47,"tag":207,"props":1172,"children":1173},{"class":209,"line":219},[1174,1179],{"type":47,"tag":207,"props":1175,"children":1176},{"style":1161},[1177],{"type":52,"value":1178},"  acme.my_plugin",{"type":47,"tag":207,"props":1180,"children":1181},{"style":1167},[1182],{"type":52,"value":1170},{"type":47,"tag":207,"props":1184,"children":1185},{"class":209,"line":228},[1186,1191,1196],{"type":47,"tag":207,"props":1187,"children":1188},{"style":1161},[1189],{"type":52,"value":1190},"    enabled",{"type":47,"tag":207,"props":1192,"children":1193},{"style":1167},[1194],{"type":52,"value":1195},":",{"type":47,"tag":207,"props":1197,"children":1199},{"style":1198},"--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC",[1200],{"type":52,"value":1201}," true\n",{"type":47,"tag":61,"props":1203,"children":1205},{"id":1204},"common-patterns",[1206],{"type":52,"value":1207},"Common Patterns",{"type":47,"tag":55,"props":1209,"children":1210},{},[1211,1213,1217],{"type":52,"value":1212},"For implementation patterns and code examples, see ",{"type":47,"tag":593,"props":1214,"children":1215},{"href":595},[1216],{"type":52,"value":595},{"type":52,"value":1195},{"type":47,"tag":476,"props":1219,"children":1220},{},[1221,1226,1247,1252,1257,1276],{"type":47,"tag":480,"props":1222,"children":1223},{},[1224],{"type":52,"value":1225},"Enable\u002Fdisable pattern",{"type":47,"tag":480,"props":1227,"children":1228},{},[1229,1231,1237,1239,1245],{"type":52,"value":1230},"Request\u002Fresponse transformation (",{"type":47,"tag":75,"props":1232,"children":1234},{"className":1233},[],[1235],{"type":52,"value":1236},"map_request",{"type":52,"value":1238},", ",{"type":47,"tag":75,"props":1240,"children":1242},{"className":1241},[],[1243],{"type":52,"value":1244},"map_response",{"type":52,"value":1246},")",{"type":47,"tag":480,"props":1248,"children":1249},{},[1250],{"type":52,"value":1251},"Checkpoint (early return\u002Fshort-circuit)",{"type":47,"tag":480,"props":1253,"children":1254},{},[1255],{"type":52,"value":1256},"Context passing between hooks",{"type":47,"tag":480,"props":1258,"children":1259},{},[1260,1262,1268,1269,1275],{"type":52,"value":1261},"Async operations (",{"type":47,"tag":75,"props":1263,"children":1265},{"className":1264},[],[1266],{"type":52,"value":1267},"checkpoint_async",{"type":52,"value":1238},{"type":47,"tag":75,"props":1270,"children":1272},{"className":1271},[],[1273],{"type":52,"value":1274},"buffered",{"type":52,"value":1246},{"type":47,"tag":480,"props":1277,"children":1278},{},[1279],{"type":52,"value":1280},"Error response builders",{"type":47,"tag":61,"props":1282,"children":1284},{"id":1283},"examples",[1285],{"type":52,"value":1286},"Examples",{"type":47,"tag":87,"props":1288,"children":1290},{"id":1289},"apollo-router-examples",[1291],{"type":52,"value":1292},"Apollo Router Examples",{"type":47,"tag":55,"props":1294,"children":1295},{},[1296,1298,1306],{"type":52,"value":1297},"Located in the ",{"type":47,"tag":593,"props":1299,"children":1303},{"href":1300,"rel":1301},"https:\u002F\u002Fgithub.com\u002Fapollographql\u002Frouter\u002Ftree\u002Fdev\u002Fapollo-router\u002Fsrc\u002Fplugins",[1302],"nofollow",[1304],{"type":52,"value":1305},"Apollo Router plugins directory",{"type":52,"value":1195},{"type":47,"tag":94,"props":1308,"children":1309},{},[1310,1334],{"type":47,"tag":98,"props":1311,"children":1312},{},[1313],{"type":47,"tag":102,"props":1314,"children":1315},{},[1316,1320,1325,1330],{"type":47,"tag":106,"props":1317,"children":1318},{},[1319],{"type":52,"value":859},{"type":47,"tag":106,"props":1321,"children":1322},{},[1323],{"type":52,"value":1324},"Service Hook",{"type":47,"tag":106,"props":1326,"children":1327},{},[1328],{"type":52,"value":1329},"Pattern",{"type":47,"tag":106,"props":1331,"children":1332},{},[1333],{"type":52,"value":115},{"type":47,"tag":117,"props":1335,"children":1336},{},[1337,1367,1394,1424],{"type":47,"tag":102,"props":1338,"children":1339},{},[1340,1349,1357,1362],{"type":47,"tag":124,"props":1341,"children":1342},{},[1343],{"type":47,"tag":75,"props":1344,"children":1346},{"className":1345},[],[1347],{"type":52,"value":1348},"forbid_mutations.rs",{"type":47,"tag":124,"props":1350,"children":1351},{},[1352],{"type":47,"tag":75,"props":1353,"children":1355},{"className":1354},[],[1356],{"type":52,"value":166},{"type":47,"tag":124,"props":1358,"children":1359},{},[1360],{"type":52,"value":1361},"checkpoint",{"type":47,"tag":124,"props":1363,"children":1364},{},[1365],{"type":52,"value":1366},"Simple gate on query plan",{"type":47,"tag":102,"props":1368,"children":1369},{},[1370,1379,1384,1389],{"type":47,"tag":124,"props":1371,"children":1372},{},[1373],{"type":47,"tag":75,"props":1374,"children":1376},{"className":1375},[],[1377],{"type":52,"value":1378},"expose_query_plan.rs",{"type":47,"tag":124,"props":1380,"children":1381},{},[1382],{"type":52,"value":1383},"execution + supergraph",{"type":47,"tag":124,"props":1385,"children":1386},{},[1387],{"type":52,"value":1388},"Context passing",{"type":47,"tag":124,"props":1390,"children":1391},{},[1392],{"type":52,"value":1393},"Multi-service coordination",{"type":47,"tag":102,"props":1395,"children":1396},{},[1397,1406,1414,1419],{"type":47,"tag":124,"props":1398,"children":1399},{},[1400],{"type":47,"tag":75,"props":1401,"children":1403},{"className":1402},[],[1404],{"type":52,"value":1405},"cors.rs",{"type":47,"tag":124,"props":1407,"children":1408},{},[1409],{"type":47,"tag":75,"props":1410,"children":1412},{"className":1411},[],[1413],{"type":52,"value":132},{"type":47,"tag":124,"props":1415,"children":1416},{},[1417],{"type":52,"value":1418},"HTTP layer",{"type":47,"tag":124,"props":1420,"children":1421},{},[1422],{"type":52,"value":1423},"CORS handling at HTTP level",{"type":47,"tag":102,"props":1425,"children":1426},{},[1427,1436,1444,1449],{"type":47,"tag":124,"props":1428,"children":1429},{},[1430],{"type":47,"tag":75,"props":1431,"children":1433},{"className":1432},[],[1434],{"type":52,"value":1435},"headers\u002F",{"type":47,"tag":124,"props":1437,"children":1438},{},[1439],{"type":47,"tag":75,"props":1440,"children":1442},{"className":1441},[],[1443],{"type":52,"value":183},{"type":47,"tag":124,"props":1445,"children":1446},{},[1447],{"type":52,"value":1448},"Layer composition",{"type":47,"tag":124,"props":1450,"children":1451},{},[1452],{"type":52,"value":1453},"Complex header manipulation",{"type":47,"tag":55,"props":1455,"children":1456},{},[1457,1459,1464],{"type":52,"value":1458},"For full code examples and testing patterns, see ",{"type":47,"tag":593,"props":1460,"children":1462},{"href":1461},"references\u002Fexamples.md",[1463],{"type":52,"value":1461},{"type":52,"value":1465},".",{"type":47,"tag":61,"props":1467,"children":1469},{"id":1468},"prerequisites",[1470],{"type":52,"value":1471},"Prerequisites",{"type":47,"tag":55,"props":1473,"children":1474},{},[1475,1477,1484],{"type":52,"value":1476},"It is advised to have the ",{"type":47,"tag":593,"props":1478,"children":1481},{"href":1479,"rel":1480},"https:\u002F\u002Fskills.sh\u002Fapollographql\u002Fskills\u002Frust-best-practices",[1302],[1482],{"type":52,"value":1483},"rust-best-practices",{"type":52,"value":1485}," skill installed for writing idiomatic Rust code when developing router plugins. If installed, follow those best practices when generating or modifying plugin code.",{"type":47,"tag":61,"props":1487,"children":1489},{"id":1488},"resources",[1490],{"type":52,"value":1491},"Resources",{"type":47,"tag":476,"props":1493,"children":1494},{},[1495,1504,1514,1523],{"type":47,"tag":480,"props":1496,"children":1497},{},[1498,1502],{"type":47,"tag":593,"props":1499,"children":1500},{"href":595},[1501],{"type":52,"value":595},{"type":52,"value":1503}," - Detailed service hook implementations",{"type":47,"tag":480,"props":1505,"children":1506},{},[1507,1512],{"type":47,"tag":593,"props":1508,"children":1510},{"href":1509},"references\u002Fexisting-plugins.md",[1511],{"type":52,"value":1509},{"type":52,"value":1513}," - Index of existing plugins",{"type":47,"tag":480,"props":1515,"children":1516},{},[1517,1521],{"type":47,"tag":593,"props":1518,"children":1519},{"href":1461},[1520],{"type":52,"value":1461},{"type":52,"value":1522}," - Full code examples and testing patterns",{"type":47,"tag":480,"props":1524,"children":1525},{},[1526,1528],{"type":52,"value":1527},"Apollo Router plugins: ",{"type":47,"tag":593,"props":1529,"children":1531},{"href":1300,"rel":1530},[1302],[1532],{"type":52,"value":1300},{"type":47,"tag":1534,"props":1535,"children":1536},"style",{},[1537],{"type":52,"value":1538},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":1540,"total":1702},[1541,1556,1571,1584,1605,1620,1633,1646,1653,1669,1679,1690],{"slug":1542,"name":1542,"fn":1543,"description":1544,"org":1545,"tags":1546,"stars":24,"repoUrl":25,"updatedAt":1555},"apollo-client","build React apps with Apollo Client","Guide for building React applications with Apollo Client 4.x. Use this skill when: (1) setting up Apollo Client in a React project, (2) writing GraphQL queries or mutations with hooks, (3) configuring caching or cache policies, (4) managing local state with reactive variables, (5) troubleshooting Apollo Client errors or performance issues.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1547,1548,1551,1552],{"name":9,"slug":8,"type":16},{"name":1549,"slug":1550,"type":16},"Frontend","frontend",{"name":14,"slug":15,"type":16},{"name":1553,"slug":1554,"type":16},"React","react","2026-04-06T18:01:12.268638",{"slug":1557,"name":1557,"fn":1558,"description":1559,"org":1560,"tags":1561,"stars":24,"repoUrl":25,"updatedAt":1570},"apollo-connectors","integrate REST APIs with Apollo Connectors","Guide for integrating REST APIs into GraphQL supergraphs using Apollo Connectors with @source and @connect directives. Use this skill when the user: (1) mentions \"connectors\", \"Apollo Connectors\", or \"REST Connector\", (2) wants to integrate a REST API into GraphQL, (3) references @source or @connect directives, (4) works with files containing \"# Note to AI Friends: This is an Apollo Connectors schema\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1562,1565,1566,1567],{"name":1563,"slug":1564,"type":16},"API Development","api-development",{"name":9,"slug":8,"type":16},{"name":14,"slug":15,"type":16},{"name":1568,"slug":1569,"type":16},"REST API","rest-api","2026-04-06T18:01:23.758345",{"slug":1572,"name":1572,"fn":1573,"description":1574,"org":1575,"tags":1576,"stars":24,"repoUrl":25,"updatedAt":1583},"apollo-federation","author Apollo Federation subgraph schemas","Guide for authoring Apollo Federation subgraph schemas. Use this skill when: (1) creating new subgraph schemas for a federated supergraph, (2) defining or modifying entities with @key, (3) sharing types\u002Ffields across subgraphs with @shareable, (4) working with federation directives (@external, @requires, @provides, @override, @inaccessible), (5) troubleshooting composition errors, (6) any task involving federation schema design patterns.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1577,1578,1579,1582],{"name":1563,"slug":1564,"type":16},{"name":9,"slug":8,"type":16},{"name":1580,"slug":1581,"type":16},"Architecture","architecture",{"name":14,"slug":15,"type":16},"2026-07-30T05:31:51.648593",{"slug":1585,"name":1585,"fn":1586,"description":1587,"org":1588,"tags":1589,"stars":24,"repoUrl":25,"updatedAt":1604},"apollo-ios","build Apple apps with Apollo iOS","Guide for building Apple-platform applications with Apollo iOS, the strongly-typed GraphQL client for Swift. Use this skill when: (1) adding Apollo iOS to a Swift Package Manager or Xcode project, (2) configuring `apollo-codegen-config.json` and running code generation, (3) configuring an `ApolloClient` with auth, interceptors, and caching, (4) writing queries, mutations, or subscriptions from SwiftUI views, (5) writing tests against generated operation mocks.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1590,1591,1592,1595,1598,1601],{"name":9,"slug":8,"type":16},{"name":14,"slug":15,"type":16},{"name":1593,"slug":1594,"type":16},"iOS","ios",{"name":1596,"slug":1597,"type":16},"Mobile","mobile",{"name":1599,"slug":1600,"type":16},"Swift","swift",{"name":1602,"slug":1603,"type":16},"Xcode","xcode","2026-04-29T05:35:21.329969",{"slug":1606,"name":1606,"fn":1607,"description":1608,"org":1609,"tags":1610,"stars":24,"repoUrl":25,"updatedAt":1619},"apollo-kotlin","build Kotlin apps with Apollo GraphQL","Guide for building applications with Apollo Kotlin, the GraphQL client library for Android and Kotlin. Use this skill when: (1) setting up Apollo Kotlin in a Gradle project for Android, Kotlin\u002FJVM, or KMP, (2) configuring schema download and codegen for GraphQL services, (3) configuring an `ApolloClient` with auth, interceptors, and caching, (4) writing queries, mutations, or subscriptions,\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1611,1614,1615,1616],{"name":1612,"slug":1613,"type":16},"Android","android",{"name":9,"slug":8,"type":16},{"name":14,"slug":15,"type":16},{"name":1617,"slug":1618,"type":16},"Kotlin","kotlin","2026-04-06T18:01:15.005978",{"slug":1621,"name":1621,"fn":1622,"description":1623,"org":1624,"tags":1625,"stars":24,"repoUrl":25,"updatedAt":1632},"apollo-mcp-server","connect MCP agents to GraphQL APIs","Guide for using Apollo MCP Server to connect AI agents with GraphQL APIs. Use this skill when: (1) setting up or configuring Apollo MCP Server, (2) defining MCP tools from GraphQL operations, (3) using introspection tools (introspect, search, validate, execute), (4) troubleshooting MCP server connectivity or tool execution issues.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1626,1627,1628,1629],{"name":1563,"slug":1564,"type":16},{"name":9,"slug":8,"type":16},{"name":14,"slug":15,"type":16},{"name":1630,"slug":1631,"type":16},"MCP","mcp","2026-04-06T18:01:20.578589",{"slug":1634,"name":1634,"fn":1635,"description":1636,"org":1637,"tags":1638,"stars":24,"repoUrl":25,"updatedAt":1645},"apollo-router","configure Apollo Router for GraphQL federation","Version-aware guide for configuring and running Apollo Router for federated GraphQL supergraphs. Generates correct YAML for both Router v1.x and v2.x. Use this skill when: (1) setting up Apollo Router to run a supergraph, (2) configuring routing, headers, or CORS, (3) implementing custom plugins (Rhai scripts or coprocessors), (4) configuring telemetry (tracing, metrics, logging), (5) troubleshooting Router performance or connectivity issues, (6) securing the graph with JWT, declarative field-level authorization directives, or persisted-query safelisting, (7) managing router.yaml as version-controlled config with CI\u002FCD validation.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1639,1640,1641,1644],{"name":9,"slug":8,"type":16},{"name":1580,"slug":1581,"type":16},{"name":1642,"slug":1643,"type":16},"Deployment","deployment",{"name":14,"slug":15,"type":16},"2026-07-30T05:31:54.665938",{"slug":4,"name":4,"fn":5,"description":6,"org":1647,"tags":1648,"stars":24,"repoUrl":25,"updatedAt":26},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1649,1650,1651,1652],{"name":9,"slug":8,"type":16},{"name":14,"slug":15,"type":16},{"name":19,"slug":20,"type":16},{"name":22,"slug":23,"type":16},{"slug":1654,"name":1654,"fn":1655,"description":1656,"org":1657,"tags":1658,"stars":24,"repoUrl":25,"updatedAt":1668},"apollo-server","build GraphQL servers with Apollo Server","Guide for building GraphQL servers with Apollo Server 5.x. Use this skill when: (1) setting up a new Apollo Server project, (2) writing resolvers or defining GraphQL schemas, (3) implementing authentication or authorization, (4) creating plugins or custom data sources, (5) troubleshooting Apollo Server errors or performance issues.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1659,1660,1661,1662,1665],{"name":1563,"slug":1564,"type":16},{"name":9,"slug":8,"type":16},{"name":14,"slug":15,"type":16},{"name":1663,"slug":1664,"type":16},"Node.js","nodejs",{"name":1666,"slug":1667,"type":16},"TypeScript","typescript","2026-04-06T18:01:13.653038",{"slug":1670,"name":1670,"fn":1671,"description":1672,"org":1673,"tags":1674,"stars":24,"repoUrl":25,"updatedAt":1678},"graphql-operations","write GraphQL queries and mutations","Guide for writing GraphQL operations (queries, mutations, fragments) following best practices. Use this skill when: (1) writing GraphQL queries or mutations, (2) organizing operations with fragments, (3) optimizing data fetching patterns, (4) setting up type generation or linting, (5) reviewing operations for efficiency.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1675,1676,1677],{"name":1563,"slug":1564,"type":16},{"name":9,"slug":8,"type":16},{"name":14,"slug":15,"type":16},"2026-04-06T18:01:25.530906",{"slug":1680,"name":1680,"fn":1681,"description":1682,"org":1683,"tags":1684,"stars":24,"repoUrl":25,"updatedAt":1689},"graphql-schema","design GraphQL schemas","Guide for designing GraphQL schemas following industry best practices. Use this skill when: (1) designing a new GraphQL schema or API, (2) reviewing existing schema for improvements, (3) deciding on type structures or nullability, (4) implementing pagination or error patterns, (5) ensuring security in schema design.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1685,1686,1687,1688],{"name":1563,"slug":1564,"type":16},{"name":9,"slug":8,"type":16},{"name":1580,"slug":1581,"type":16},{"name":14,"slug":15,"type":16},"2026-04-06T18:01:19.140592",{"slug":1691,"name":1691,"fn":1692,"description":1693,"org":1694,"tags":1695,"stars":24,"repoUrl":25,"updatedAt":1701},"rover","manage GraphQL schemas with Apollo Rover","Guide for using Apollo Rover CLI to manage GraphQL schemas and federation. Use this skill when: (1) publishing or fetching subgraph\u002Fgraph schemas, (2) composing supergraph schemas locally or via GraphOS, (3) running local supergraph development with rover dev, (4) validating schemas with check and lint commands, (5) configuring Rover authentication and environment, (6) exploring or searching a graph's schema for agent-driven discovery (rover schema describe \u002F rover schema search).\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1696,1697,1700],{"name":9,"slug":8,"type":16},{"name":1698,"slug":1699,"type":16},"CLI","cli",{"name":14,"slug":15,"type":16},"2026-07-30T05:31:52.675547",15,{"items":1704,"total":1756},[1705,1712,1719,1726,1735,1742,1749],{"slug":1542,"name":1542,"fn":1543,"description":1544,"org":1706,"tags":1707,"stars":24,"repoUrl":25,"updatedAt":1555},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1708,1709,1710,1711],{"name":9,"slug":8,"type":16},{"name":1549,"slug":1550,"type":16},{"name":14,"slug":15,"type":16},{"name":1553,"slug":1554,"type":16},{"slug":1557,"name":1557,"fn":1558,"description":1559,"org":1713,"tags":1714,"stars":24,"repoUrl":25,"updatedAt":1570},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1715,1716,1717,1718],{"name":1563,"slug":1564,"type":16},{"name":9,"slug":8,"type":16},{"name":14,"slug":15,"type":16},{"name":1568,"slug":1569,"type":16},{"slug":1572,"name":1572,"fn":1573,"description":1574,"org":1720,"tags":1721,"stars":24,"repoUrl":25,"updatedAt":1583},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1722,1723,1724,1725],{"name":1563,"slug":1564,"type":16},{"name":9,"slug":8,"type":16},{"name":1580,"slug":1581,"type":16},{"name":14,"slug":15,"type":16},{"slug":1585,"name":1585,"fn":1586,"description":1587,"org":1727,"tags":1728,"stars":24,"repoUrl":25,"updatedAt":1604},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1729,1730,1731,1732,1733,1734],{"name":9,"slug":8,"type":16},{"name":14,"slug":15,"type":16},{"name":1593,"slug":1594,"type":16},{"name":1596,"slug":1597,"type":16},{"name":1599,"slug":1600,"type":16},{"name":1602,"slug":1603,"type":16},{"slug":1606,"name":1606,"fn":1607,"description":1608,"org":1736,"tags":1737,"stars":24,"repoUrl":25,"updatedAt":1619},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1738,1739,1740,1741],{"name":1612,"slug":1613,"type":16},{"name":9,"slug":8,"type":16},{"name":14,"slug":15,"type":16},{"name":1617,"slug":1618,"type":16},{"slug":1621,"name":1621,"fn":1622,"description":1623,"org":1743,"tags":1744,"stars":24,"repoUrl":25,"updatedAt":1632},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1745,1746,1747,1748],{"name":1563,"slug":1564,"type":16},{"name":9,"slug":8,"type":16},{"name":14,"slug":15,"type":16},{"name":1630,"slug":1631,"type":16},{"slug":1634,"name":1634,"fn":1635,"description":1636,"org":1750,"tags":1751,"stars":24,"repoUrl":25,"updatedAt":1645},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1752,1753,1754,1755],{"name":9,"slug":8,"type":16},{"name":1580,"slug":1581,"type":16},{"name":1642,"slug":1643,"type":16},{"name":14,"slug":15,"type":16},14]