{
    "slug": "api_design",
    "term": "API Design Principles",
    "category": "architecture",
    "difficulty": "intermediate",
    "short": "Guidelines for designing interfaces — method signatures, HTTP endpoints, error responses — that are intuitive, consistent, and evolvable.",
    "long": "Good API design principles include: consistency (uniform naming, error format, versioning), minimal surface area (expose only what's needed), principle of least surprise (methods do what their name implies), clear error messages with actionable guidance, backward-compatible evolution (additive changes before breaking), and documentation with examples. For HTTP APIs, REST or GraphQL conventions, semantic HTTP status codes, and standard formats (JSON:API, OpenAPI) aid consumer developers. For PHP class APIs, method cohesion, immutability of value objects, and narrow parameter types improve ergonomics.",
    "aliases": [
        "API design principles",
        "REST API design",
        "API best practices"
    ],
    "tags": [
        "architecture",
        "api",
        "rest",
        "principles"
    ],
    "misconception": "A well-designed API just needs clear endpoint names. Good API design also covers consistent error responses, versioning strategy, pagination, idempotency, authentication, and backwards compatibility — naming is a small part of a much larger contract with consumers.",
    "why_it_matters": "A well-designed API is a contract — breaking changes, inconsistent naming, or missing error detail frustrate integrators and require costly versioning; good design reduces support burden and adoption friction.",
    "common_mistakes": [
        "Returning HTTP 200 with an error body — consumers must parse every response to detect failure.",
        "No versioning strategy from day one — breaking changes in v1 force all consumers to update simultaneously.",
        "Inconsistent resource naming (users vs user vs Users across endpoints).",
        "Not including a problem detail (RFC 7807) or similar structured error object — raw error strings are unusable programmatically."
    ],
    "when_to_use": [
        "Define the API contract before implementation — consumers and producers can work in parallel.",
        "Use resource-oriented URLs for REST — nouns not verbs, plural collections, nested sub-resources.",
        "Version from day one for any external-facing API — retrofitting versioning is painful.",
        "Design for the consumer's mental model, not your internal architecture."
    ],
    "avoid_when": [
        "Exposing your internal domain model directly — implementation details leak and become a public contract.",
        "Using GET for state-changing operations — GET must be safe and idempotent per HTTP semantics.",
        "Returning different shapes for the same resource in different endpoints — consistency is more important than brevity.",
        "Designing the API before understanding consumer needs — API-first works; guessing-first does not."
    ],
    "related": [
        "rest",
        "semantic_versioning",
        "interface_segregation"
    ],
    "prerequisites": [
        "rest_constraints",
        "api_versioning",
        "api_error_handling"
    ],
    "refs": [
        "https://restfulapi.net/",
        "https://google.aip.dev/"
    ],
    "bad_code": "// 200 OK with error payload — forces body parsing for failure detection:\n{\n  \"status\": \"error\",\n  \"msg\": \"User not found\"\n}\n// HTTP 404 with structured body is correct:\n// HTTP/1.1 404 Not Found\n// {\"type\": \"not_found\", \"title\": \"User not found\", \"detail\": \"No user with id 42\"}",
    "good_code": "// Consistent error response shape — every error looks the same\nreturn response()->json([\n    'error' => [\n        'code'    => 'VALIDATION_FAILED',\n        'message' => 'The given data was invalid.',\n        'details' => \\$validator->errors(),\n    ],\n], 422);\n\n// Resource naming — nouns, plural, nested for relationships\nGET  /api/users/{id}/orders\nGET  /api/orders?status=paid&page=2\nPOST /api/orders/{id}/cancel   // action as sub-resource\n\n// Pagination envelope\n{\n  \"data\": [...],\n  \"meta\": { \"total\": 1420, \"page\": 1, \"per_page\": 20, \"last_page\": 71 },\n  \"links\": { \"next\": \"/api/orders?page=2\", \"prev\": null }\n}",
    "quick_fix": "Use nouns for resources, HTTP verbs for actions, consistent JSON response structure, and meaningful error messages with error codes — then document with OpenAPI",
    "severity": "medium",
    "effort": "medium",
    "created": "2026-03-15",
    "updated": "2026-03-25",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/api_design",
        "html_url": "https://codeclaritylab.com/glossary/api_design",
        "json_url": "https://codeclaritylab.com/glossary/api_design.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": "[API Design Principles](https://codeclaritylab.com/glossary/api_design) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/api_design"
            }
        }
    }
}