{
    "slug": "graphql",
    "term": "GraphQL",
    "category": "architecture",
    "difficulty": "intermediate",
    "short": "A query language for APIs where clients specify exactly the data they need, reducing over-fetching and under-fetching versus REST.",
    "long": "GraphQL (Facebook, 2015) allows clients to define the shape and depth of data they require in a single request, rather than fetching from multiple REST endpoints and discarding unnecessary fields. A strongly-typed schema defines all available types and operations (queries, mutations, subscriptions). PHP implementations include webonyx/graphql-php and API Platform with GraphQL support. Security considerations include: depth limiting and complexity analysis to prevent DoS, disabling introspection in production, field-level authorisation, and N+1 protection with DataLoader-style batching.",
    "aliases": [
        "GraphQL API",
        "graph query language",
        "GraphQL schema"
    ],
    "tags": [
        "architecture",
        "api",
        "query-language"
    ],
    "misconception": "GraphQL always performs better than REST by reducing over-fetching. GraphQL solves over/under-fetching but can introduce N+1 query problems server-side if resolvers are not batched with DataLoader. A poorly implemented GraphQL API can be significantly slower than an equivalent REST endpoint.",
    "why_it_matters": "GraphQL lets clients request exactly the fields they need — eliminating over-fetching and under-fetching, but introducing query complexity and security concerns that REST handles implicitly.",
    "common_mistakes": [
        "Not implementing query depth or complexity limits — attackers can craft deeply nested queries that exhaust server resources.",
        "N+1 query problem in resolvers — each list item triggers a separate database query; use DataLoader batching.",
        "Exposing the entire data model via introspection in production — disable introspection for public APIs.",
        "Not rate-limiting per query complexity — a complex query costs more than a simple one but may count as one request."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "rest",
        "api_design",
        "n_plus_one"
    ],
    "prerequisites": [
        "rest_constraints",
        "api_design",
        "n_plus_one"
    ],
    "refs": [
        "https://graphql.org/learn/",
        "https://github.com/webonyx/graphql-php"
    ],
    "bad_code": "// Resolver with N+1 problem:\n'posts' => function($root, $args, $ctx) {\n    $posts = Post::all(); // 1 query\n    return $posts; // Each post triggers author query — N+1\n},\n'author' => function($post) {\n    return User::find($post->user_id); // 1 query per post!\n}",
    "good_code": "// PHP GraphQL with webonyx/graphql-php\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\n\n\\$queryType = new ObjectType([\n    'name' => 'Query',\n    'fields' => [\n        'user' => [\n            'type'    => \\$userType,\n            'args'    => ['id' => Type::nonNull(Type::int())],\n            'resolve' => fn(\\$root, \\$args) => User::find(\\$args['id']),\n        ],\n    ],\n]);\n\n// Client query — fetch only needed fields (no over-fetching)\n// query { user(id: 1) { name email orders { total } } }\n\n// Mutations change data\n// mutation { placeOrder(cartId: 42) { id total status } }",
    "quick_fix": "Implement a DataLoader for every relation to batch N+1 queries; add query depth and complexity limits to prevent expensive introspection attacks",
    "severity": "medium",
    "effort": "high",
    "created": "2026-03-15",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/graphql",
        "html_url": "https://codeclaritylab.com/glossary/graphql",
        "json_url": "https://codeclaritylab.com/glossary/graphql.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[GraphQL](https://codeclaritylab.com/glossary/graphql) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/graphql"
            }
        }
    }
}