{"id":"64fbdaf5-9875-48e2-a6ee-019e7b123b94","shortId":"YtRX6h","kind":"skill","title":"graphql-federation","tagline":"GraphQL Federation skill for creating correct federation subgraphs. Use when: (1) Creating new federation subgraphs, (2) Adding entities with @key directives, (3) Extending types across subgraphs, (4) Using federation directives (@shareable, @external, @override, @provides, @requ","description":"# GraphQL Federation Skill\n\nCreate correct GraphQL federation subgraphs following WunderGraph Cosmo composition rules.\n\n## Core Concepts\n\n**Subgraph**: A GraphQL microservice contributing to the federated graph.\n**Federated Graph/Supergraph**: The composed GraphQL interface for clients.\n**Router**: Plans operations, routes requests to subgraphs, joins data.\n**Entity**: A type with `@key` directive resolvable across subgraphs.\n**Router Schema vs Client Schema**: Router sees all fields; clients don't see `@inaccessible` items.\n\n## Essential Directives\n\n### @key - Define Entities\n\n```graphql\n# Basic entity\ntype User @key(fields: \"id\") {\n  id: ID!\n  name: String!\n}\n\n# Multiple keys\ntype Product @key(fields: \"id\") @key(fields: \"sku\") {\n  id: ID!\n  sku: String!\n  name: String!\n}\n\n# Composite key\ntype Review @key(fields: \"author { id } product { id }\") {\n  author: User!\n  product: Product!\n  rating: Int!\n}\n\n# Non-resolvable key (reference only, can't resolve this entity)\ntype User @key(fields: \"id\", resolvable: false) {\n  id: ID!\n}\n```\n\n**Key Rules:**\n- Key fields cannot have arguments\n- Key fields cannot be abstract types (interfaces/unions)\n- Key fields must select leaf scalars or nested objects with selections\n- Multiple keys provide alternative resolution paths\n\n### @shareable - Allow Multiple Definitions\n\n```graphql\n# When same field exists in multiple subgraphs\ntype User @key(fields: \"id\") {\n  id: ID!\n  name: String! @shareable  # Can be defined in other subgraphs\n}\n\n# Object-level shareable applies to all fields\ntype User @key(fields: \"id\") @shareable {\n  id: ID!\n  name: String!\n  email: String!\n}\n```\n\n**Shareable Rules:**\n- Fields defined in multiple subgraphs MUST be @shareable\n- Key fields used in other subgraphs' keys must be @shareable\n- Root type fields (Query, Mutation) are implicitly shareable\n\n### @external - Reference External Fields\n\n```graphql\n# Mark fields resolved by another subgraph\nextend type User @key(fields: \"id\") {\n  id: ID! @external\n  name: String! @external\n  reviews: [Review!]!  # This subgraph resolves reviews\n}\n```\n\n**External Rules:**\n- Use on key fields when extending entities\n- Use on fields referenced in @requires\n- Use on fields referenced in @provides\n- External fields are NOT resolved by this subgraph\n\n### @requires - Depend on External Data\n\n```graphql\ntype Product @key(fields: \"id\") {\n  id: ID!\n  price: Float! @external\n  currency: String! @external\n  formattedPrice: String! @requires(fields: \"price currency\")\n}\n```\n\n**Requires Rules:**\n- Referenced fields must be @external\n- Can reference nested fields: `@requires(fields: \"details { weight }\")`\n- Router fetches required fields before calling this resolver\n\n### @provides - Declare Additional Fields\n\n```graphql\ntype Query {\n  topProducts: [Product!]! @provides(fields: \"name description\")\n}\n\ntype Product @key(fields: \"id\") {\n  id: ID!\n  name: String! @external\n  description: String! @external\n}\n```\n\n**Provides Rules:**\n- Declares that a resolver provides additional fields\n- Referenced fields must be @external in this subgraph\n- Optimizes router query planning\n\n### @override - Transfer Field Ownership\n\n```graphql\n# In new subgraph, taking over from \"old-service\"\ntype User @key(fields: \"id\") {\n  id: ID!\n  name: String! @override(from: \"old-service\")\n}\n```\n\n**Override Rules:**\n- Cannot override from same subgraph\n- Overridden field in source doesn't need @shareable\n- Used for gradual migration between subgraphs\n\n### @inaccessible - Hide from Client Schema\n\n```graphql\ntype User @key(fields: \"id\") {\n  id: ID!\n  name: String!\n  internalId: String! @inaccessible  # Hidden from clients\n}\n\n# Entire type can be inaccessible\ntype InternalMetrics @inaccessible {\n  requestCount: Int!\n}\n```\n\n**Inaccessible Rules:**\n- Field exists in router schema but not client schema\n- Still subject to @shareable rules\n- All fields on a type cannot be @inaccessible (type becomes useless)\n- Required arguments cannot be @inaccessible alone\n\n### @interfaceObject - Treat Interface as Object\n\n```graphql\n# Subgraph A defines the interface\ninterface Media @key(fields: \"id\") {\n  id: ID!\n  title: String!\n}\n\ntype Book implements Media @key(fields: \"id\") {\n  id: ID!\n  title: String!\n  author: String!\n}\n\n# Subgraph B adds fields to ALL implementations\ntype Media @key(fields: \"id\") @interfaceObject {\n  id: ID!\n  reviews: [Review!]!  # Added to Book and all Media types\n}\n```\n\n**InterfaceObject Rules:**\n- Cannot define implementations alongside @interfaceObject\n- Fields propagate to all concrete implementations\n- Must have @key matching the interface's key\n\n### Authorization Directives\n\n```graphql\ntype Query {\n  publicData: String!\n  privateData: String! @authenticated\n  adminData: String! @requiresScopes(scopes: [[\"admin\"], [\"superuser\"]])\n}\n\n# Type-level auth\ntype SecretDocument @authenticated @requiresScopes(scopes: [[\"read:secrets\"]]) {\n  content: String!\n}\n```\n\n## Common Patterns\n\n### Entity Extension\n\n```graphql\n# Subgraph A - owns User\ntype User @key(fields: \"id\") {\n  id: ID!\n  name: String!\n  email: String!\n}\n\n# Subgraph B - extends User with posts\nextend type User @key(fields: \"id\") {\n  id: ID! @external\n  posts: [Post!]!\n}\n\ntype Post @key(fields: \"id\") {\n  id: ID!\n  title: String!\n  author: User!\n}\n```\n\n### Federated Mutations\n\n```graphql\ntype Mutation {\n  createUser(input: CreateUserInput!): User!\n}\n\n# Entity returned from mutation allows field resolution from other subgraphs\ntype User @key(fields: \"id\") {\n  id: ID!\n  name: String!\n}\n```\n\n### Interface Entities\n\n```graphql\ninterface Node @key(fields: \"id\") {\n  id: ID!\n}\n\ntype User implements Node @key(fields: \"id\") {\n  id: ID!\n  name: String!\n}\n\ntype Product implements Node @key(fields: \"id\") {\n  id: ID!\n  title: String!\n}\n```\n\n## Error Prevention\n\n### Shareability Errors\n\n```graphql\n# ERROR: Field defined in multiple subgraphs without @shareable\n# Subgraph A\ntype User @key(fields: \"id\") {\n  id: ID!\n  name: String!  # Missing @shareable\n}\n\n# Subgraph B\ntype User @key(fields: \"id\") {\n  id: ID!\n  name: String!  # Conflict!\n}\n\n# FIX: Add @shareable to both\ntype User @key(fields: \"id\") {\n  id: ID!\n  name: String! @shareable\n}\n```\n\n### Resolvability Errors\n\n```graphql\n# ERROR: Field cannot be resolved from Query entry point\n# Subgraph A\ntype Query {\n  user: User!  # Only in A\n}\n\ntype User {\n  id: ID!\n  name: String!  # Only in A\n}\n\n# Subgraph B\ntype User {\n  email: String!  # Only in B, but User has no @key!\n}\n\n# FIX: Add @key to make User an entity\ntype User @key(fields: \"id\") {\n  id: ID!\n  name: String!\n}\n```\n\n### External Field Errors\n\n```graphql\n# ERROR: @requires on non-external field\ntype Product @key(fields: \"id\") {\n  id: ID!\n  price: Float!  # Missing @external\n  formattedPrice: String! @requires(fields: \"price\")\n}\n\n# FIX: Mark as external\ntype Product @key(fields: \"id\") {\n  id: ID!\n  price: Float! @external\n  formattedPrice: String! @requires(fields: \"price\")\n}\n```\n\n## Reference Files\n\nFor detailed directive specifications, see:\n- `references/directives.md` - Complete directive documentation\n- `references/composition-rules.md` - Composition validation rules\n- `references/patterns.md` - Advanced federation patterns","tags":["graphql","federation","skill","wundergraph","agent-skills","apollo-federation","claude-code","claude-code-skills","graphql-federation"],"capabilities":["skill","source-wundergraph","skill-graphql-federation","topic-agent-skills","topic-apollo-federation","topic-claude-code","topic-claude-code-skills","topic-graphql","topic-graphql-federation","topic-wundergraph"],"categories":["graphql-federation-skill"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/wundergraph/graphql-federation-skill/graphql-federation","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add wundergraph/graphql-federation-skill","source_repo":"https://github.com/wundergraph/graphql-federation-skill","install_from":"skills.sh"}},"qualityScore":"0.453","qualityRationale":"deterministic score 0.45 from registry signals: · indexed on github topic:agent-skills · 6 github stars · SKILL.md body (7,152 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:14:46.494Z","embedding":null,"createdAt":"2026-05-18T13:22:15.438Z","updatedAt":"2026-05-18T19:14:46.494Z","lastSeenAt":"2026-05-18T19:14:46.494Z","tsv":"'1':14 '2':19 '3':25 '4':30 'abstract':184 'across':28,87 'ad':20,596 'add':581,800,859 'addit':388,419 'admin':638 'admindata':634 'advanc':937 'allow':205,714 'alon':545 'alongsid':608 'altern':201 'anoth':289 'appli':236 'argument':179,541 'auth':643 'authent':633,646 'author':143,147,577,624,699 'b':580,674,788,845,852 'basic':110 'becom':538 'book':567,598 'call':383 'cannot':177,182,463,534,542,605,819 'client':70,92,98,485,502,522 'common':653 'complet':929 'compos':66 'composit':50,137,933 'concept':53 'concret':614 'conflict':798 'content':651 'contribut':58 'core':52 'correct':9,43 'cosmo':49 'creat':8,15,42 'createus':706 'createuserinput':708 'currenc':354,362 'data':79,342 'declar':387,414 'defin':107,228,255,554,606,768 'definit':207 'depend':339 'descript':398,409 'detail':376,924 'direct':24,33,85,105,625,925,930 'document':931 'doesn':472 'email':250,671,848 'entir':503 'entiti':21,80,108,111,163,317,655,710,730,865 'entri':824 'error':761,764,766,815,817,877,879 'essenti':104 'exist':212,516 'extend':26,291,316,675,679 'extens':656 'extern':35,280,282,299,302,309,330,341,353,356,369,408,411,425,687,875,884,896,905,915 'fals':170 'feder':3,5,10,17,32,40,45,61,63,701,938 'fetch':379 'field':97,115,126,129,142,167,176,181,188,211,219,239,243,254,263,274,283,286,295,314,320,326,331,347,360,366,373,375,381,389,396,402,420,422,435,450,469,491,515,530,560,571,582,589,610,665,683,693,715,723,735,744,755,767,779,792,807,818,869,876,885,889,900,909,919 'file':922 'fix':799,858,902 'float':352,894,914 'follow':47 'formattedpric':357,897,916 'gradual':478 'graph':62 'graph/supergraph':64 'graphql':2,4,39,44,56,67,109,208,284,343,390,437,487,551,626,657,703,731,765,816,878 'graphql-feder':1 'hidden':500 'hide':483 'id':116,117,118,127,131,132,144,146,168,171,172,220,221,222,244,246,247,296,297,298,348,349,350,403,404,405,451,452,453,492,493,494,561,562,563,572,573,574,590,592,593,666,667,668,684,685,686,694,695,696,724,725,726,736,737,738,745,746,747,756,757,758,780,781,782,793,794,795,808,809,810,837,838,870,871,872,890,891,892,910,911,912 'implement':568,585,607,615,741,752 'implicit':278 'inaccess':102,482,499,507,510,513,536,544 'input':707 'int':152,512 'interfac':68,548,556,557,621,729,732 'interfaceobject':546,591,603,609 'interfaces/unions':186 'internalid':497 'internalmetr':509 'item':103 'join':78 'key':23,84,106,114,122,125,128,138,141,156,166,173,175,180,187,199,218,242,262,268,294,313,346,401,449,490,559,570,588,618,623,664,682,692,722,734,743,754,778,791,806,857,860,868,888,908 'leaf':191 'level':234,642 'make':862 'mark':285,903 'match':619 'media':558,569,587,601 'microservic':57 'migrat':479 'miss':785,895 'multipl':121,198,206,214,257,770 'must':189,259,269,367,423,616 'mutat':276,702,705,713 'name':119,135,223,248,300,397,406,454,495,669,727,748,783,796,811,839,873 'need':474 'nest':194,372 'new':16,439 'node':733,742,753 'non':154,883 'non-extern':882 'non-resolv':153 'object':195,233,550 'object-level':232 'old':445,459 'old-servic':444,458 'oper':73 'optim':429 'overrid':36,433,456,461,464 'overridden':468 'own':660 'ownership':436 'path':203 'pattern':654,939 'plan':72,432 'point':825 'post':678,688,689,691 'prevent':762 'price':351,361,893,901,913,920 'privatedata':631 'product':124,145,149,150,345,394,400,751,887,907 'propag':611 'provid':37,200,329,386,395,412,418 'publicdata':629 'queri':275,392,431,628,823,829 'rate':151 'read':649 'refer':157,281,371,921 'referenc':321,327,365,421 'references/composition-rules.md':932 'references/directives.md':928 'references/patterns.md':936 'requ':38 'request':75 'requestcount':511 'requir':323,338,359,363,374,380,540,880,899,918 'requiresscop':636,647 'resolut':202,716 'resolv':86,155,161,169,287,307,334,385,417,814,821 'return':711 'review':140,303,304,308,594,595 'root':272 'rout':74 'router':71,89,94,378,430,518 'rule':51,174,253,310,364,413,462,514,528,604,935 'scalar':192 'schema':90,93,486,519,523 'scope':637,648 'secret':650 'secretdocu':645 'see':95,101,927 'select':190,197 'servic':446,460 'shareabl':34,204,225,235,245,252,261,271,279,475,527,763,773,786,801,813 'skill':6,41 'skill-graphql-federation' 'sku':130,133 'sourc':471 'source-wundergraph' 'specif':926 'still':524 'string':120,134,136,224,249,251,301,355,358,407,410,455,496,498,565,576,578,630,632,635,652,670,672,698,728,749,760,784,797,812,840,849,874,898,917 'subgraph':11,18,29,46,54,77,88,215,231,258,267,290,306,337,428,440,467,481,552,579,658,673,719,771,774,787,826,844 'subject':525 'superus':639 'take':441 'titl':564,575,697,759 'topic-agent-skills' 'topic-apollo-federation' 'topic-claude-code' 'topic-claude-code-skills' 'topic-graphql' 'topic-graphql-federation' 'topic-wundergraph' 'topproduct':393 'transfer':434 'treat':547 'type':27,82,112,123,139,164,185,216,240,273,292,344,391,399,447,488,504,508,533,537,566,586,602,627,641,644,662,680,690,704,720,739,750,776,789,804,828,835,846,866,886,906 'type-level':640 'use':12,31,264,311,318,324,476 'useless':539 'user':113,148,165,217,241,293,448,489,661,663,676,681,700,709,721,740,777,790,805,830,831,836,847,854,863,867 'valid':934 'vs':91 'weight':377 'without':772 'wundergraph':48","prices":[{"id":"00103a38-90c1-4406-aeff-3b2b7274b0b4","listingId":"64fbdaf5-9875-48e2-a6ee-019e7b123b94","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"wundergraph","category":"graphql-federation-skill","install_from":"skills.sh"},"createdAt":"2026-05-18T13:22:15.438Z"}],"sources":[{"listingId":"64fbdaf5-9875-48e2-a6ee-019e7b123b94","source":"github","sourceId":"wundergraph/graphql-federation-skill/graphql-federation","sourceUrl":"https://github.com/wundergraph/graphql-federation-skill/tree/main/skills/graphql-federation","isPrimary":false,"firstSeenAt":"2026-05-18T13:22:15.438Z","lastSeenAt":"2026-05-18T19:14:46.494Z"}],"details":{"listingId":"64fbdaf5-9875-48e2-a6ee-019e7b123b94","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"wundergraph","slug":"graphql-federation","github":{"repo":"wundergraph/graphql-federation-skill","stars":6,"topics":["agent-skills","apollo-federation","claude-code","claude-code-skills","graphql","graphql-federation","wundergraph"],"license":"apache-2.0","html_url":"https://github.com/wundergraph/graphql-federation-skill","pushed_at":"2026-02-16T22:28:10Z","description":"Agentic Coding Skill for GraphQL Federation / Apollo Federation","skill_md_sha":"47e7c231809d2cc98ef18b2beae79a40d39e1dd8","skill_md_path":"skills/graphql-federation/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/wundergraph/graphql-federation-skill/tree/main/skills/graphql-federation"},"layout":"multi","source":"github","category":"graphql-federation-skill","frontmatter":{"name":"graphql-federation","description":"GraphQL Federation skill for creating correct federation subgraphs. Use when: (1) Creating new federation subgraphs, (2) Adding entities with @key directives, (3) Extending types across subgraphs, (4) Using federation directives (@shareable, @external, @override, @provides, @requires, @inaccessible, @interfaceObject, @authenticated, @requiresScopes), (5) Debugging composition errors, (6) Understanding federation rules and patterns.\nMANDATORY TRIGGERS: federation, subgraph, @key, entity, federated graph, supergraph, GraphQL composition, router schema"},"skills_sh_url":"https://skills.sh/wundergraph/graphql-federation-skill/graphql-federation"},"updatedAt":"2026-05-18T19:14:46.494Z"}}