manutej/luxor-claude-marketplace/graphql-api-development

Claude Code and agent skill by manutej/luxor-claude-marketplace

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Comprehensive guide for building GraphQL APIs including schema design, queries, mutations, subscriptions, resolvers, type system, error handling, authentication, authorization, caching strategies, and production best practices

Install

npx vskill@latest install manutej/luxor-claude-marketplace/graphql-api-development

SKILL.md

GraphQL API Development

A comprehensive skill for building production-ready GraphQL APIs using graphql-js. Master schema design, type systems, resolvers, queries, mutations, subscriptions, authentication, authorization, caching, testing, and deployment strategies.

When to Use This Skill

Use this skill when:

  • Building a new API that requires flexible data fetching for web or mobile clients
  • Replacing or augmenting REST APIs with more efficient data access patterns
  • Developing APIs for applications with complex, nested data relationships
  • Creating APIs that serve multiple client types (web, mobile, desktop) with different data needs
  • Building real-time applications requiring subscriptions and live updates
  • Designing APIs where clients need to specify exactly what data they need
  • Developing GraphQL servers with Node.js and Express
  • Implementing type-safe APIs with strong schema validation
  • Creating self-documenting APIs with built-in introspection
  • Building microservices that need to be composed into a unified API

When GraphQL Excels Over REST

GraphQL Advantages
  1. Precise Data Fetching: Clients request exactly what they need, no over/under-fetching
  2. Single Request: Fetch multiple resources in one roundtrip instead of multiple REST endpoints
  3. Strongly Typed: Schema defines exact types, enabling validation and tooling
  4. Introspection: Self-documenting API with queryable schema
  5. Versioning Not Required: Add new fields without breaking existing queries
  6. Real-time Updates: Built-in subscription support for live data
  7. Nested Resources: Naturally handle complex relationships without N+1 queries
  8. Client-Driven: Clients control data shape, reducing backend changes
When to Stick with REST
  • Simple CRUD operations with standard resources
  • File uploads/downloads (GraphQL requires multipart handling)
  • HTTP caching is critical (GraphQL typically uses POST)
  • Team unfamiliar with GraphQL (learning curve)
  • Existing REST infrastructure works well

Core Concepts

The GraphQL Type System

GraphQL's type system is its foundation. Every GraphQL API defines:

  1. Scalar Types: Basic data types (String, Int, Float, Boolean, ID)
  2. Object Types: Complex types with fields
  3. Query Type: Entry point for read operations
  4. Mutation Type: Entry point for write operations
  5. Subscription Type: Entry point for real-time updates
  6. Input Types: Complex inputs for mutations
  7. Enums: Fixed set of values
  8. Interfaces: Abstract types that objects implement
  9. Unions: Types that can be one of several types
  10. Non-Null Types: Types that cannot be null
  11. List Types: Arrays of types
Schema Definition

Two approaches for defining GraphQL schemas:

1. Schema Definition Language (SDL) - Declarative, readable:

graphql
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
content: String
author: User!
}
type Query {
user(id: ID!): User
posts: [Post!]!
}

2. Programmatic API - Type-safe, programmatic:

javascript
const UserType = new GraphQLObjectType({
name: 'User',
fields: {
id: { type: new GraphQLNonNull(GraphQLID) },
name: { type: new GraphQLNonNull(GraphQLString) },
email: { type: new GraphQLNonNull(GraphQLString) },
posts: { type: new GraphQLList(new GraphQLNonNull(PostType)) }
}
});
Resolvers

Resolvers are functions that return data for schema fields. Every field can have a resolver:

javascript
const resolvers = {
Query: {
user: (parent, args, context, info) => {
return context.db.findUserById(args.id);
}
},
User: {
posts: (user, args, context) => {
return context.db.findPostsByAuthorId(user.id);
}
}
};

Resolver Function Signature:

  • parent: The result from the parent resolver
  • args: Arguments passed to the field
  • context: Shared context (database, auth, etc.)
  • info: Field-specific metadata
Queries

Queries fetch data from your API:

graphql
query GetUser {
user(id: "123") {
id
name
email
posts {
title
content
}
}
}
Mutations

Mutations modify data:

graphql
mutation CreatePost {
createPost(input: {
title: "GraphQL is awesome"
content: "Here's why..."
authorId: "123"
}) {
id
title
author {
name
}
}
}
Subscriptions

Subscriptions enable real-time updates:

graphql
subscription OnPostCreated {
postCreated {
id
title
author {
name
}
}
}

Schema Design Patterns

Pattern 1: Input Types for Mutations

Always use input types for complex mutation arguments:

graphql
input CreateUserInput {
name: String!
email: String!
age: Int
bio: String
}
type Mutation {
createUser(input: CreateUserInput!): User!
}

Why: Easier to extend, better organization, reusable across mutations.

Pattern 2: Interfaces for Shared Fields

Use interfaces when multiple types share fields:

graphql
interface Node {
id: ID!
createdAt: String!
updatedAt: String!
}
type User implements Node {
id: ID!
createdAt: String!
updatedAt: String!
name: String!
email: String!
}
type Post implements Node {
id: ID!
createdAt: String!
updatedAt: String!
title: String!
content: String
}
Pattern 3: Unions for Polymorphic Returns

Use unions when a field can return different types:

graphql
union SearchResult = User | Post | Comment
type Query {
search(query: String!): [SearchResult!]!
}
Pattern 4: Pagination Patterns

Offset-based pagination:

graphql
type Query {
posts(offset: Int, limit: Int): PostConnection!
}
type PostConnection {
items: [Post!]!
total: Int!
hasMore: Boolean!
}

Cursor-based pagination (Relay-style):

graphql
type Query {
posts(first: Int, after: String): PostConnection!
}
type PostConnection {
edges: [PostEdge!]!
pageInfo: PageInfo!
}
type PostEdge {
node: Post!
cursor: String!
}
type PageInfo {
hasNextPage: Boolean!
endCursor: String
}
Pattern 5: Error Handling

Field-level errors:

graphql
type MutationPayload {
success: Boolean!
message: String
user: User
errors: [Error!]
}
type Error {
field: String!
message: String!
}

Union-based error handling:

graphql
union CreateUserResult = User | ValidationError | DatabaseError
type ValidationError {
field: String!
message: String!
}
Pattern 6: Versioning with Directives

Deprecate fields instead of versioning:

graphql
type User {
name: String! @deprecated(reason: "Use firstName and lastName")
firstName: String!
lastName: String!
}

Query Optimization and Performance

The N+1 Problem

Problem: Fetching nested data causes multiple database queries:

javascript
// BAD: N+1 queries
const UserType = new GraphQLObjectType({
name: 'User',
fields: {
posts: {
type: new GraphQLList(PostType),
resolve: (user) => {
// This runs once PER user!
return db.getPostsByUserId(user.id);
}
}
}
});
// Query for 100 users = 1 query for users + 100 queries for posts = 101 queries
DataLoader Solution

DataLoader batches and caches requests:

javascript
import DataLoader from 'dataloader';
// Create DataLoader
const postLoader = new DataLoader(async (userIds) => {
// Single query for all user IDs
const posts = await db.getPostsByUserIds(userIds);
// Group posts by userId
const postsByUserId = {};
posts.forEach(post => {
if (!postsByUserId[post.authorId]) {
postsByUserId[post.authorId] = [];
}
postsByUserId[post.authorId].push(post);
});
// Return in same order as userIds
return userIds.map(id => postsByUserId[id] || []);
});
// Use in resolver
const UserType = new GraphQLObjectType({
name: 'User',
fields: {
posts: {
type: new GraphQLList(PostType),
resolve: (user, args, context) => {
return context.loaders.postLoader.load(user.id);
}
}
}
});
// Add to context
const context = {
loaders: {
postLoader: new DataLoader(batchLoadPosts)
}
};
Query Complexity Analysis

Limit expensive queries:

javascript
import { getComplexity, simpleEstimator } from 'graphql-query-complexity';
const complexity = getComplexity({
schema,
query,
estimators: [
simpleEstimator({ defaultComplexity: 1 })
]
});
if (complexity > 1000) {
throw new Error('Query too complex');
}
Depth Limiting

Prevent deeply nested queries:

javascript
import depthLimit from 'graphql-depth-limit';
const server = new ApolloServer({
schema,
validationRules: [depthLimit(5)]
});

Mutations and Input Validation

Mutation Design Pattern
graphql
input CreatePostInput {
title: String!
content: String!
authorId: ID!
tags: [String!]
}
type CreatePostPayload {
post: Post
errors: [UserError!]
success: Boolean!
}
type UserError {
message: String!
field: String
}
type Mutation {
createPost(input: CreatePostInput!): CreatePostPayload!
}
Input Validation
javascript
const Mutation = new GraphQLObjectType({
name: 'Mutation',
fields: {
createPost: {
type: CreatePostPayload,
args: {
input: { type: new GraphQLNonNull(CreatePostInput) }
},
resolve: async (_, { input }, context) => {
// Validate input
const errors = [];
if (input.title.length < 3) {
errors.push({
field: 'title',
message: 'Title must be at least 3 characters'
});
}
if (input.content.length < 10) {
errors.push({
field: 'content',
message: 'Content must be at least 10 characters'
});
}
if (errors.length > 0) {
return { errors, success: false, post: null };
}
// Create post
const post = await context.db.createPost(input);
return { post, errors: [], success: true };
}
}
}
});

Subscriptions and Real-time Updates

Setting Up Subscriptions
javascript
import { GraphQLObjectType, GraphQLString } from 'graphql';
import { PubSub } from 'graphql-subscriptions';
const pubsub = new PubSub();
const Subscription = new GraphQLObjectType({
name: 'Subscription',
fields: {
postCreated: {
type: PostType,
subscribe: () => pubsub.asyncIterator(['POST_CREATED'])
},
messageReceived: {
type: MessageType,
args: {
channelId: { type: new GraphQLNonNull(GraphQLID) }
},
subscribe: (_, { channelId }) => {
return pubsub.asyncIterator([`MESSAGE_${channelId}`]);
}
}
}
});
Publishing Events
javascript
const Mutation = new GraphQLObjectType({
name: 'Mutation',
fields: {
createPost: {
type: PostType,
args: {
input: { type: new GraphQLNonNull(CreatePostInput) }
},
resolve: async (_, { input }, context) => {
const post = await context.db.createPost(input);
// Publish to subscribers
pubsub.publish('POST_CREATED', { postCreated: post });
return post;
}
}
}
});
WebSocket Server Setup
javascript
import { createServer } from 'http';
import { WebSocketServer } from 'ws';
import { useServer } from 'graphql-ws/lib/use/ws';
import { execute, subscribe } from 'graphql';
import express from 'express';
const app = express();
const httpServer = createServer(app);
// WebSocket server for subscriptions
const wsServer = new WebSocketServer({
server: httpServer,
path: '/graphql'
});
useServer(
{
schema,
execute,
subscribe,
context: (ctx) => {
// Access connection params, headers
return {
userId: ctx.connectionParams?.userId,
db: database
};
}
},
wsServer
);

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
48
Repository forks
11
7-day trend score
19

Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 2 Apr 2026, 7 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/manutej/luxor-claude-marketplace/graphql-api-development/badge)](https://verified-skill.com/skills/manutej/luxor-claude-marketplace/graphql-api-development)

Something wrong with this skill or its page? Tell us.