Skip to main content Skills Marketplace Descubra e explore skills de IA criadas pela comunidade.
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Copiar promptMostrar detalhes do prompt Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
npx skills add https://github.com/pluginagentmarketplace/custom-plugin-api-design --skill graphqlO comando permanece em uma só linha. Role horizontalmente para revisá-lo antes de copiar.
Prefere uma cópia local? Baixe os arquivos disponíveis atualmente no SkillsMP.
Baixar Zip Baixando... Ocupações relacionadas SOC
Baseado na classificação ocupacional SOC
Explorador de arquivos
6 arquivos name graphql version 2.0.0 description GraphQL API design and schema development sasmp_version 1.3.0 bonded_agent 01-api-architect bond_type PRIMARY_BOND atomic_design {"single_responsibility":"GraphQL schema design and resolver patterns","boundaries":{"includes":["schema_design","resolvers","subscriptions","n_plus_one","caching"],"excludes":["rest_design","database_queries","frontend_code"]}} parameter_validation {"schema":{"type":"object","properties":{"operation_type":{"type":"string","enum":["query","mutation","subscription"]},"complexity_limit":{"type":"number","minimum":0,"maximum":1000}}}} retry_config {"enabled":true,"max_attempts":3,"backoff":{"type":"exponential","initial_delay_ms":1000,"max_delay_ms":30000}} logging {"level":"INFO","fields":["operation_name","complexity","duration_ms"]} dependencies {"skills":["api-architecture"],"agents":["01-api-architect"]}
GraphQL API Design Skill
Purpose
Design efficient GraphQL APIs with proper schema patterns.
Schema Design
Types
scalar DateTime
scalar UUID
scalar Email
type User {
id : ID!
email : Email!
name : String!
status : UserStatus!
profile : Profile
teams : [ Team! ] !
createdAt : DateTime!
updatedAt : DateTime
}
enum UserStatus {
ACTIVE
INACTIVE
BANNED
}
interface Node {
id : ID!
}
union SearchResult = User | Team | Post
Queries
type
user ID User
users
Int
String
Int
String
UserFilter
UserConnection
search String , SearchType SearchResult
UserFilter
UserStatus
String
DateTime
Query
{
(
id
:
!
)
:
(
first
:
after
:
last
:
before
:
filter
:
)
:
!
(
query
:
!
types
:
[
!
]
)
:
[
!
]
!
}
input
{
status
:
role
:
createdAfter
:
}
Mutations type Mutation {
createUser( input : CreateUserInput! ) : CreateUserPayload!
updateUser( id : ID! , input : UpdateUserInput! ) : UpdateUserPayload!
deleteUser( id : ID! ) : DeleteUserPayload!
verifyUser( id : ID! ) : VerifyUserPayload!
}
input CreateUserInput {
email : Email!
name : String!
password : String!
}
input UpdateUserInput {
name : String
status : UserStatus
}
type CreateUserPayload {
user : User
errors : [ UserError! ] !
}
type UserError {
field : String
message : String!
code : ErrorCode!
}
Subscriptions type Subscription {
userCreated : User!
userUpdated( id : ID) : User!
orderStatusChanged( orderId : ID! ) : Order!
}
Connection Pattern (Relay) type UserConnection {
edges : [ UserEdge! ] !
pageInfo : PageInfo!
totalCount : Int!
}
type UserEdge {
node : User!
cursor : String!
}
type PageInfo {
hasNextPage : Boolean!
hasPreviousPage : Boolean!
startCursor : String
endCursor : String
}
Resolver Patterns
Basic Resolver const resolvers = {
Query : {
user : async (_, { id }, context) => {
return context.dataSources .users .findById (id);
},
users : async (_, { first, after, filter }, context) => {
return context.dataSources .users .findMany ({
first,
after,
filter,
});
},
},
User : {
teams : async (user, _, context) => {
return context.dataSources .teams .findByUserId (user.id );
},
},
};
DataLoader (N+1 Solution) import DataLoader from 'dataloader' ;
const userLoader = new DataLoader (async (ids : string []) => {
const users = await db.query (
'SELECT * FROM users WHERE id = ANY($1)' ,
[ids]
);
const userMap = new Map (users.map (u => [u.id , u]));
return ids.map (id => userMap.get (id) || null );
});
const resolvers = {
Post : {
author : (post, _, context ) => {
return context.loaders .user .load (post.authorId );
},
},
};
Context Setup const server = new ApolloServer ({
typeDefs,
resolvers,
context : ({ req } ) => ({
user : req.user ,
loaders : {
user : new DataLoader (batchUsers),
team : new DataLoader (batchTeams),
},
dataSources : {
users : new UserDataSource (db),
teams : new TeamDataSource (db),
},
}),
});
Error Handling import { GraphQLError } from 'graphql' ;
throw new GraphQLError ('User not found' , {
extensions : {
code : 'NOT_FOUND' ,
field : 'userId' ,
},
});
const server = new ApolloServer ({
formatError : (error ) => {
if (error.extensions ?.code === 'INTERNAL_SERVER_ERROR' ) {
logger.error (error);
return { message : 'Internal server error' };
}
return error;
},
});
Security
Query Complexity import { createComplexityRule } from 'graphql-query-complexity' ;
const complexityRule = createComplexityRule ({
maximumComplexity : 1000 ,
estimators : [
fieldExtensionsEstimator (),
simpleEstimator ({ defaultComplexity : 1 }),
],
onComplete : (complexity ) => {
console .log ('Query complexity:' , complexity);
},
});
const server = new ApolloServer ({
validationRules : [complexityRule],
});
Depth Limiting import depthLimit from 'graphql-depth-limit' ;
const server = new ApolloServer ({
validationRules : [depthLimit (10 )],
});
Unit Test Template import { describe, it, expect } from 'vitest' ;
import { ApolloServer } from '@apollo/server' ;
import { typeDefs, resolvers } from './schema' ;
describe ('GraphQL API' , () => {
const server = new ApolloServer ({ typeDefs, resolvers });
describe ('Query.user' , () => {
it ('should return user by id' , async () => {
const result = await server.executeOperation ({
query : `
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}
` ,
variables : { id : 'user-123' },
});
expect (result.body .singleResult .data ?.user ).toEqual ({
id : 'user-123' ,
name : 'John Doe' ,
email : 'john@example.com' ,
});
});
it ('should return null for non-existent user' , async () => {
const result = await server.executeOperation ({
query : `query { user(id: "invalid") { id } }` ,
});
expect (result.body .singleResult .data ?.user ).toBeNull ();
});
});
describe ('Mutation.createUser' , () => {
it ('should create user and return payload' , async () => {
const result = await server.executeOperation ({
query : `
mutation CreateUser($input: CreateUserInput!) {
createUser(input: $input) {
user { id name }
errors { field message }
}
}
` ,
variables : {
input : { email : 'new@example.com' , name : 'New User' , password : 'Secret123!' },
},
});
expect (result.body .singleResult .data ?.createUser .user ).toBeDefined ();
expect (result.body .singleResult .data ?.createUser .errors ).toEqual ([]);
});
});
});
Troubleshooting Issue Cause Solution N+1 queries Field-level resolvers Use DataLoader Slow queries High complexity Add complexity limits Memory issues Large result sets Implement pagination Introspection leak Enabled in production Disable in prod
Quality Checklist