{"id":"fcfaf32c-0a71-45f4-85a6-7a68fab9f177","shortId":"bzPLrM","kind":"skill","title":"graphql-schema","tagline":"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","description":"# GraphQL Schema Design Guide\n\nThis guide covers best practices for designing GraphQL schemas that are intuitive, performant, and maintainable. Schema design is primarily a server-side concern that directly impacts API usability.\n\n## Schema Design Principles\n\n### 1. Design for Client Needs\n\n- Think about what queries clients will write\n- Organize types around use cases, not database tables\n- Expose capabilities, not implementation details\n\n### 2. Be Explicit\n\n- Use clear, descriptive names\n- Make nullability intentional\n- Document with descriptions\n\n### 3. Design for Evolution\n\n- Plan for backwards compatibility\n- Use deprecation before removal\n- Avoid breaking changes\n\n## Quick Reference\n\n### Type Definition Syntax\n\n```graphql\n\"\"\"\nA user in the system.\n\"\"\"\ntype User {\n  id: ID!\n  email: String!\n  name: String\n  posts(first: Int = 10, after: String): PostConnection!\n  createdAt: DateTime!\n}\n```\n\n### Nullability Rules\n\n| Pattern | Meaning |\n|---------|---------|\n| String | Nullable - may be null |\n| String! | Non-null - always has value |\n| [String] | Nullable list, nullable items |\n| [String!] | Nullable list, non-null items |\n| [String]! | Non-null list, nullable items |\n| [String!]! | Non-null list, non-null items |\n\n**Best Practice:** Use **[Type!]!** for lists - empty list over null, no null items.\n\n### Input vs Output Types\n\n```graphql\n# Output type - what clients receive\ntype User {\n  id: ID!\n  email: String!\n  createdAt: DateTime!\n}\n\n# Input type - what clients send\ninput CreateUserInput {\n  email: String!\n  name: String\n}\n\n# Mutation using input type\ntype Mutation {\n  createUser(input: CreateUserInput!): User!\n}\n```\n\n### Interface Pattern\n\n```graphql\ninterface Node {\n  id: ID!\n}\n\ntype User implements Node {\n  id: ID!\n  email: String!\n}\n\ntype Post implements Node {\n  id: ID!\n  title: String!\n}\n```\n\n### Union Pattern\n\n```graphql\nunion SearchResult = User | Post | Comment\n\ntype Query {\n  search(query: String!): [SearchResult!]!\n}\n```\n\n## Reference Files\n\nDetailed documentation for specific topics:\n\n- [Types](references/types.md) - Type design patterns, interfaces, unions, and custom scalars\n- [Naming](references/naming.md) - Naming conventions for types, fields, and arguments\n- [Pagination](references/pagination.md) - Connection pattern and cursor-based pagination\n- [Errors](references/errors.md) - Error modeling and result types\n- [Security](references/security.md) - Security best practices for schema design\n\n## Key Rules\n\n### Type Design\n\n- Define types based on domain concepts, not data storage\n- Use interfaces for shared fields across types\n- Use unions for mutually exclusive types\n- Keep types focused (single responsibility)\n- Avoid deep nesting - flatten when possible\n\n### Field Design\n\n- Fields should be named from client's perspective\n- Return the most specific type possible\n- Make expensive fields explicit (consider arguments)\n- Use arguments for filtering, sorting, pagination\n\n### Mutation Design\n\n- Use single input argument pattern: `mutation(input: InputType!)`\n- Return affected objects in mutation responses\n- Model mutations around business operations, not CRUD\n- Consider returning a union of success/error types\n\n### ID Strategy\n\n- Use globally unique IDs when possible\n- Implement `Node` interface for refetchability\n- Base64-encode compound IDs if needed\n\n## Ground Rules\n\n- ALWAYS add descriptions to types and fields\n- ALWAYS use non-null (**!**) for fields that cannot be null\n- ALWAYS use **[Type!]!** pattern for lists\n- NEVER expose database internals in schema\n- NEVER break backwards compatibility without deprecation\n- PREFER dedicated input types over many arguments\n- PREFER enums over arbitrary strings for fixed values\n- USE `ID` type for identifiers, not `String` or `Int`\n- USE custom scalars for domain-specific values (DateTime, Email, URL)","tags":["graphql","schema","skills","apollographql","agent-skills","apollo"],"capabilities":["skill","source-apollographql","skill-graphql-schema","topic-agent-skills","topic-apollo","topic-graphql"],"categories":["skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/apollographql/skills/graphql-schema","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add apollographql/skills","source_repo":"https://github.com/apollographql/skills","install_from":"skills.sh"}},"qualityScore":"0.736","qualityRationale":"deterministic score 0.74 from registry signals: · indexed on github topic:agent-skills · official publisher · 71 github stars · SKILL.md body (3,835 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-18T18:57:02.307Z","embedding":null,"createdAt":"2026-04-18T20:31:01.731Z","updatedAt":"2026-05-18T18:57:02.307Z","lastSeenAt":"2026-05-18T18:57:02.307Z","tsv":"'1':17,81 '10':156 '2':25,106 '3':31,119 '4':38 '5':44 'across':363 'add':463 'affect':421 'alway':175,462,469,480 'api':24,76 'arbitrari':508 'argument':320,403,405,415,504 'around':95,428 'avoid':131,376 'backward':125,494 'base':328,351 'base64':454 'base64-encode':453 'best':11,52,206,340 'break':132,493 'busi':429 'cannot':477 'capabl':102 'case':97 'chang':133 'clear':110 'client':84,90,227,240,389 'comment':288 'compat':126,495 'compound':456 'concept':354 'concern':72 'connect':323 'consid':402,433 'convent':315 'cover':51 'createdat':160,235 'createus':254 'createuserinput':243,256 'crud':432 'cursor':327 'cursor-bas':326 'custom':310,523 'data':356 'databas':99,488 'datetim':161,236,530 'decid':32 'dedic':499 'deep':377 'defin':349 'definit':137 'deprec':128,497 'descript':111,118,464 'design':6,18,47,55,65,79,82,120,305,344,348,383,411 'detail':105,297 'direct':74 'document':116,298 'domain':353,527 'domain-specif':526 'email':149,233,244,271,531 'empti':212 'encod':455 'enum':506 'error':42,330,332 'evolut':122 'exclus':369 'exist':27 'expens':399 'explicit':108,401 'expos':101,487 'field':318,362,382,384,400,468,475 'file':296 'filter':407 'first':154 'fix':511 'flatten':379 'focus':373 'follow':9 'global':443 'graphql':2,7,21,45,56,139,223,260,283 'graphql-schema':1 'ground':460 'guid':4,48,50 'id':147,148,231,232,263,264,269,270,277,278,440,445,457,514 'identifi':517 'impact':75 'implement':39,104,267,275,448 'improv':30 'industri':10 'input':219,237,242,250,255,414,418,500 'inputtyp':419 'int':155,521 'intent':115 'interfac':258,261,307,359,450 'intern':489 'intuit':60 'item':182,189,196,205,218 'keep':371 'key':345 'list':180,185,194,201,211,213,485 'maintain':63 'make':113,398 'mani':503 'may':168 'mean':165 'model':333,426 'mutat':248,253,410,417,424,427 'mutual':368 'name':112,151,246,312,314,387 'need':85,459 'nest':378 'never':486,492 'new':20 'node':262,268,276,449 'non':173,187,192,199,203,472 'non-nul':172,186,191,198,202,471 'null':170,174,188,193,200,204,215,217,473,479 'nullabl':37,114,162,167,179,181,184,195 'object':422 'oper':430 'organ':93 'output':221,224 'pagin':40,321,329,409 'pattern':43,164,259,282,306,324,416,483 'perform':61 'perspect':391 'plan':123 'possibl':381,397,447 'post':153,274,287 'postconnect':159 'practic':12,53,207,341 'prefer':498,505 'primarili':67 'principl':80 'queri':89,290,292 'quick':134 'receiv':228 'refer':135,295 'references/errors.md':331 'references/naming.md':313 'references/pagination.md':322 'references/security.md':338 'references/types.md':303 'refetch':452 'remov':130 'respons':375,425 'result':335 'return':392,420,434 'review':26 'rule':163,346,461 'scalar':311,524 'schema':3,8,22,28,46,57,64,78,343,491 'search':291 'searchresult':285,294 'secur':337,339 'send':241 'server':70 'server-sid':69 'share':361 'side':71 'singl':374,413 'skill':15 'skill-graphql-schema' 'sort':408 'source-apollographql' 'specif':300,395,528 'storag':357 'strategi':441 'string':150,152,158,166,171,178,183,190,197,234,245,247,272,280,293,509,519 'structur':35 'success/error':438 'syntax':138 'system':144 'tabl':100 'think':86 'titl':279 'topic':301 'topic-agent-skills' 'topic-apollo' 'topic-graphql' 'type':34,94,136,145,209,222,225,229,238,251,252,265,273,289,302,304,317,336,347,350,364,370,372,396,439,466,482,501,515 'union':281,284,308,366,436 'uniqu':444 'url':532 'usabl':77 'use':13,96,109,127,208,249,358,365,404,412,442,470,481,513,522 'user':141,146,230,257,266,286 'valu':177,512,529 'vs':220 'without':496 'write':92","prices":[{"id":"99c015a6-19b9-4a02-91ba-af1f88c3e3ff","listingId":"fcfaf32c-0a71-45f4-85a6-7a68fab9f177","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"apollographql","category":"skills","install_from":"skills.sh"},"createdAt":"2026-04-18T20:31:01.731Z"}],"sources":[{"listingId":"fcfaf32c-0a71-45f4-85a6-7a68fab9f177","source":"github","sourceId":"apollographql/skills/graphql-schema","sourceUrl":"https://github.com/apollographql/skills/tree/main/skills/graphql-schema","isPrimary":false,"firstSeenAt":"2026-04-18T22:17:26.811Z","lastSeenAt":"2026-05-18T18:57:02.307Z"},{"listingId":"fcfaf32c-0a71-45f4-85a6-7a68fab9f177","source":"skills_sh","sourceId":"apollographql/skills/graphql-schema","sourceUrl":"https://skills.sh/apollographql/skills/graphql-schema","isPrimary":true,"firstSeenAt":"2026-04-18T20:31:01.731Z","lastSeenAt":"2026-05-07T22:40:29.256Z"}],"details":{"listingId":"fcfaf32c-0a71-45f4-85a6-7a68fab9f177","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"apollographql","slug":"graphql-schema","github":{"repo":"apollographql/skills","stars":71,"topics":["agent-skills","apollo","graphql"],"license":"mit","html_url":"https://github.com/apollographql/skills","pushed_at":"2026-05-14T17:14:05Z","description":"Apollo GraphQL Agent Skills","skill_md_sha":"b7c2abe3de5409a838ed04fe9f214e126db41faa","skill_md_path":"skills/graphql-schema/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/apollographql/skills/tree/main/skills/graphql-schema"},"layout":"multi","source":"github","category":"skills","frontmatter":{"name":"graphql-schema","license":"MIT","description":"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.","compatibility":"Any GraphQL implementation (Apollo Server, graphql-js, Yoga, etc.)"},"skills_sh_url":"https://skills.sh/apollographql/skills/graphql-schema"},"updatedAt":"2026-05-18T18:57:02.307Z"}}