{"id":"fcfaf32c-0a71-45f4-85a6-7a68fab9f177","shortId":"bzPLrM","kind":"skill","title":"Graphql Schema","tagline":"Skills skill by Apollographql","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"],"capabilities":["skill","source-apollographql","category-skills"],"categories":["skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/apollographql/skills/graphql-schema","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"install_from":"skills.sh"}},"qualityScore":"0.300","qualityRationale":"deterministic score 0.30 from registry signals: · indexed on skills.sh · published under apollographql/skills","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:v1","enrichmentVersion":1,"enrichedAt":"2026-04-23T09:40:27.273Z","embedding":null,"createdAt":"2026-04-18T20:31:01.731Z","updatedAt":"2026-04-23T09:40:27.273Z","lastSeenAt":"2026-04-23T09:40:27.273Z","tsv":"'1':43 '10':118 '2':68 '3':81 'across':325 'add':425 'affect':383 'alway':137,424,431,442 'api':38 'apollographql':6 'arbitrari':470 'argument':282,365,367,377,466 'around':57,390 'avoid':93,338 'backward':87,456 'base':290,313 'base64':416 'base64-encode':415 'best':14,168,302 'break':94,455 'busi':391 'cannot':439 'capabl':64 'case':59 'category-skills' 'chang':95 'clear':72 'client':46,52,189,202,351 'comment':250 'compat':88,457 'compound':418 'concept':316 'concern':34 'connect':285 'consid':364,395 'convent':277 'cover':13 'createdat':122,197 'createus':216 'createuserinput':205,218 'crud':394 'cursor':289 'cursor-bas':288 'custom':272,485 'data':318 'databas':61,450 'datetim':123,198,492 'dedic':461 'deep':339 'defin':311 'definit':99 'deprec':90,459 'descript':73,80,426 'design':9,17,27,41,44,82,267,306,310,345,373 'detail':67,259 'direct':36 'document':78,260 'domain':315,489 'domain-specif':488 'email':111,195,206,233,493 'empti':174 'encod':417 'enum':468 'error':292,294 'evolut':84 'exclus':331 'expens':361 'explicit':70,363 'expos':63,449 'field':280,324,344,346,362,430,437 'file':258 'filter':369 'first':116 'fix':473 'flatten':341 'focus':335 'global':405 'graphql':1,7,18,101,185,222,245 'ground':422 'guid':10,12 'id':109,110,193,194,225,226,231,232,239,240,402,407,419,476 'identifi':479 'impact':37 'implement':66,229,237,410 'input':181,199,204,212,217,376,380,462 'inputtyp':381 'int':117,483 'intent':77 'interfac':220,223,269,321,412 'intern':451 'intuit':22 'item':144,151,158,167,180 'keep':333 'key':307 'list':142,147,156,163,173,175,447 'maintain':25 'make':75,360 'mani':465 'may':130 'mean':127 'model':295,388 'mutat':210,215,372,379,386,389 'mutual':330 'name':74,113,208,274,276,349 'need':47,421 'nest':340 'never':448,454 'node':224,230,238,411 'non':135,149,154,161,165,434 'non-nul':134,148,153,160,164,433 'null':132,136,150,155,162,166,177,179,435,441 'nullabl':76,124,129,141,143,146,157 'object':384 'oper':392 'organ':55 'output':183,186 'pagin':283,291,371 'pattern':126,221,244,268,286,378,445 'perform':23 'perspect':353 'plan':85 'possibl':343,359,409 'post':115,236,249 'postconnect':121 'practic':15,169,303 'prefer':460,467 'primarili':29 'principl':42 'queri':51,252,254 'quick':96 'receiv':190 'refer':97,257 'references/errors.md':293 'references/naming.md':275 'references/pagination.md':284 'references/security.md':300 'references/types.md':265 'refetch':414 'remov':92 'respons':337,387 'result':297 'return':354,382,396 'rule':125,308,423 'scalar':273,486 'schema':2,8,19,26,40,305,453 'search':253 'searchresult':247,256 'secur':299,301 'send':203 'server':32 'server-sid':31 'share':323 'side':33 'singl':336,375 'skill':3,4 'sort':370 'source-apollographql' 'specif':262,357,490 'storag':319 'strategi':403 'string':112,114,120,128,133,140,145,152,159,196,207,209,234,242,255,471,481 'success/error':400 'syntax':100 'system':106 'tabl':62 'think':48 'titl':241 'topic':263 'type':56,98,107,171,184,187,191,200,213,214,227,235,251,264,266,279,298,309,312,326,332,334,358,401,428,444,463,477 'union':243,246,270,328,398 'uniqu':406 'url':494 'usabl':39 'use':58,71,89,170,211,320,327,366,374,404,432,443,475,484 'user':103,108,192,219,228,248 'valu':139,474,491 'vs':182 'without':458 'write':54","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-04-23T06:56:11.057Z"},{"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-04-23T09:40:27.273Z"}],"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","source":"skills_sh","category":"skills","skills_sh_url":"https://skills.sh/apollographql/skills/graphql-schema"},"updatedAt":"2026-04-23T09:40:27.273Z"}}