Skip to main content Skills Marketplace Découvrez et explorez les compétences IA créées par la communauté.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Copier le promptAfficher les détails du prompt Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
npx skills add https://github.com/pluginagentmarketplace/custom-plugin-api-design --skill graphqlLa commande reste sur une seule ligne. Faites défiler horizontalement pour la vérifier avant de la copier.
Vous préférez une copie locale ? Téléchargez les fichiers actuellement disponibles dans SkillsMP.
Télécharger Zip Téléchargement... Métiers associés SOC
Basé sur la classification professionnelle SOC
Explorateur de fichiers
6 fichiers 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