{
  "schemaVersion": "1.0",
  "item": {
    "slug": "graphql",
    "name": "GraphQL",
    "source": "tencent",
    "type": "skill",
    "category": "AI 智能",
    "sourceUrl": "https://clawhub.ai/ivangdavila/graphql",
    "canonicalUrl": "https://clawhub.ai/ivangdavila/graphql",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/graphql",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=graphql",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "client.md",
      "performance.md",
      "schema.md",
      "security.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "slug": "graphql",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-01T18:54:06.379Z",
      "expiresAt": "2026-05-08T18:54:06.379Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=graphql",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=graphql",
        "contentDisposition": "attachment; filename=\"graphql-1.0.1.zip\"",
        "redirectLocation": null,
        "bodySnippet": null,
        "slug": "graphql"
      },
      "scope": "item",
      "summary": "Item download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this item.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/graphql"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/graphql",
    "agentPageUrl": "https://openagent3.xyz/skills/graphql/agent",
    "manifestUrl": "https://openagent3.xyz/skills/graphql/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/graphql/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Quick Reference",
        "body": "TopicFileSchema design patternsschema.mdSecurity and limitssecurity.mdPerformance optimizationperformance.mdClient-side patternsclient.md"
      },
      {
        "title": "N+1 Problem (Critical)",
        "body": "Each resolver runs independently—fetching user for each of 100 posts = 100 queries\nDataLoader required: batches requests within single tick—100 posts = 1 user query\nDataLoader per-request: create new instance per request—prevents cross-request caching\nEven with DataLoader, watch for nested N+1—posts → comments → authors chains"
      },
      {
        "title": "Schema Design",
        "body": "Fields nullable by default—make non-null explicit: name: String!\nInput types separate from output—CreateUserInput vs User; allows different validation\nConnections for pagination: users(first: 10, after: \"cursor\") returns edges + pageInfo\nAvoid deeply nested types—flatten where possible; 5+ levels = resolver complexity"
      },
      {
        "title": "Pagination",
        "body": "Cursor-based (Relay style): first/after, last/before—stable across insertions\nOffset-based: limit/offset—simpler but skips or duplicates on concurrent writes\nReturn pageInfo { hasNextPage, endCursor }—client knows when to stop\ntotalCount expensive on large datasets—make optional or estimate"
      },
      {
        "title": "Security Traps",
        "body": "Query depth limiting—prevent { user { friends { friends { friends... } } } }\nQuery complexity scoring—count fields, multiply by list sizes; reject above threshold\nDisable introspection in production—or protect with auth; schema is attack surface\nTimeout per query—malicious queries can be slow without being deep\nRate limit by complexity, not just requests—one complex query = many simple ones"
      },
      {
        "title": "Error Handling",
        "body": "Partial success normal—query returns data AND errors; check both\nErrors array with path—shows which field failed: \"path\": [\"user\", \"posts\", 0]\nError extensions for codes—\"extensions\": {\"code\": \"FORBIDDEN\"}; don't parse message\nThrow in resolver = null + error—parent nullable = partial data; parent non-null = error propagates up"
      },
      {
        "title": "Resolver Patterns",
        "body": "Return object with ID, let sub-resolvers fetch details—avoids over-fetching at top level\n__resolveType for unions/interfaces—required to determine concrete type\nContext for auth, DataLoaders, DB connection—pass through resolver chain\nField-level auth in resolvers—check permissions per field, not just per query"
      },
      {
        "title": "Mutations",
        "body": "Return modified object—client updates cache without re-fetch\nInput validation before DB—return user-friendly error, not DB constraint violation\nIdempotency for critical mutations—accept client-generated ID or idempotency key\nOne mutation per operation typically—batch mutations exist but complicate error handling"
      },
      {
        "title": "Performance",
        "body": "Persisted queries: hash → query mapping—smaller payloads, prevents arbitrary queries\n@defer for slow fields—returns fast fields first, streams slow ones (if supported)\nFragment colocation: components define data needs—reduces over-fetching\nQuery allowlisting: only registered queries in production—blocks exploratory attacks"
      },
      {
        "title": "Subscriptions",
        "body": "WebSocket-based—graphql-ws protocol; separate from HTTP\nScaling: pub/sub needed—Redis or similar for multi-server broadcast\nFilter at subscription level—don't push everything and filter client-side\nUnsubscribe on disconnect—clean up resources; connection tracking required"
      },
      {
        "title": "Client-Side",
        "body": "Normalized cache (Apollo, Relay)—deduplicate by ID; updates propagate automatically\nOptimistic UI: predict mutation result—rollback if server differs\nError policies: decide per-query—ignore errors, return partial, or treat as failure\nFragment reuse—define once, use in multiple queries; keeps fields in sync"
      },
      {
        "title": "Common Mistakes",
        "body": "No DataLoader—N+1 kills performance; one query becomes hundreds\nExposing internal errors—stack traces leak implementation details\nNo query limits—attackers craft expensive queries; DoS with single request\nOver-fetching in resolvers—fetching full object when query only needs ID + name\nTreating like REST—GraphQL is a graph; design for traversal, not resources"
      }
    ],
    "body": "Quick Reference\nTopic\tFile\nSchema design patterns\tschema.md\nSecurity and limits\tsecurity.md\nPerformance optimization\tperformance.md\nClient-side patterns\tclient.md\nN+1 Problem (Critical)\nEach resolver runs independently—fetching user for each of 100 posts = 100 queries\nDataLoader required: batches requests within single tick—100 posts = 1 user query\nDataLoader per-request: create new instance per request—prevents cross-request caching\nEven with DataLoader, watch for nested N+1—posts → comments → authors chains\nSchema Design\nFields nullable by default—make non-null explicit: name: String!\nInput types separate from output—CreateUserInput vs User; allows different validation\nConnections for pagination: users(first: 10, after: \"cursor\") returns edges + pageInfo\nAvoid deeply nested types—flatten where possible; 5+ levels = resolver complexity\nPagination\nCursor-based (Relay style): first/after, last/before—stable across insertions\nOffset-based: limit/offset—simpler but skips or duplicates on concurrent writes\nReturn pageInfo { hasNextPage, endCursor }—client knows when to stop\ntotalCount expensive on large datasets—make optional or estimate\nSecurity Traps\nQuery depth limiting—prevent { user { friends { friends { friends... } } } }\nQuery complexity scoring—count fields, multiply by list sizes; reject above threshold\nDisable introspection in production—or protect with auth; schema is attack surface\nTimeout per query—malicious queries can be slow without being deep\nRate limit by complexity, not just requests—one complex query = many simple ones\nError Handling\nPartial success normal—query returns data AND errors; check both\nErrors array with path—shows which field failed: \"path\": [\"user\", \"posts\", 0]\nError extensions for codes—\"extensions\": {\"code\": \"FORBIDDEN\"}; don't parse message\nThrow in resolver = null + error—parent nullable = partial data; parent non-null = error propagates up\nResolver Patterns\nReturn object with ID, let sub-resolvers fetch details—avoids over-fetching at top level\n__resolveType for unions/interfaces—required to determine concrete type\nContext for auth, DataLoaders, DB connection—pass through resolver chain\nField-level auth in resolvers—check permissions per field, not just per query\nMutations\nReturn modified object—client updates cache without re-fetch\nInput validation before DB—return user-friendly error, not DB constraint violation\nIdempotency for critical mutations—accept client-generated ID or idempotency key\nOne mutation per operation typically—batch mutations exist but complicate error handling\nPerformance\nPersisted queries: hash → query mapping—smaller payloads, prevents arbitrary queries\n@defer for slow fields—returns fast fields first, streams slow ones (if supported)\nFragment colocation: components define data needs—reduces over-fetching\nQuery allowlisting: only registered queries in production—blocks exploratory attacks\nSubscriptions\nWebSocket-based—graphql-ws protocol; separate from HTTP\nScaling: pub/sub needed—Redis or similar for multi-server broadcast\nFilter at subscription level—don't push everything and filter client-side\nUnsubscribe on disconnect—clean up resources; connection tracking required\nClient-Side\nNormalized cache (Apollo, Relay)—deduplicate by ID; updates propagate automatically\nOptimistic UI: predict mutation result—rollback if server differs\nError policies: decide per-query—ignore errors, return partial, or treat as failure\nFragment reuse—define once, use in multiple queries; keeps fields in sync\nCommon Mistakes\nNo DataLoader—N+1 kills performance; one query becomes hundreds\nExposing internal errors—stack traces leak implementation details\nNo query limits—attackers craft expensive queries; DoS with single request\nOver-fetching in resolvers—fetching full object when query only needs ID + name\nTreating like REST—GraphQL is a graph; design for traversal, not resources"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/ivangdavila/graphql",
    "publisherUrl": "https://clawhub.ai/ivangdavila/graphql",
    "owner": "ivangdavila",
    "version": "1.0.1",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/graphql",
    "downloadUrl": "https://openagent3.xyz/downloads/graphql",
    "agentUrl": "https://openagent3.xyz/skills/graphql/agent",
    "manifestUrl": "https://openagent3.xyz/skills/graphql/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/graphql/agent.md"
  }
}