graphql-implementation

安装量: 51
排名: #14363

安装

npx skills add https://github.com/aj-geddes/useful-ai-prompts --skill graphql-implementation

GraphQL Implementation Overview

Implement GraphQL APIs with proper schema design, resolver patterns, error handling, and performance optimization for flexible client-server communication.

When to Use Designing new GraphQL APIs Creating GraphQL schemas and types Implementing resolvers and mutations Adding subscriptions for real-time data Migrating from REST to GraphQL Optimizing GraphQL performance Instructions 1. GraphQL Schema Design type User { id: ID! email: String! firstName: String! lastName: String! role: UserRole! posts: [Post!]! createdAt: DateTime! updatedAt: DateTime! }

enum UserRole { ADMIN USER MODERATOR }

type Post { id: ID! title: String! content: String! author: User! comments: [Comment!]! publishedAt: DateTime createdAt: DateTime! }

type Comment { id: ID! text: String! author: User! post: Post! createdAt: DateTime! }

type Query { user(id: ID!): User users(limit: Int, offset: Int): [User!]! post(id: ID!): Post posts(authorId: ID, limit: Int, offset: Int): [Post!]! search(query: String!): [SearchResult!]! }

union SearchResult = User | Post | Comment

type Mutation { createUser(input: CreateUserInput!): User! updateUser(id: ID!, input: UpdateUserInput!): User! deleteUser(id: ID!): Boolean! createPost(input: CreatePostInput!): Post! updatePost(id: ID!, input: UpdatePostInput!): Post! deletePost(id: ID!): Boolean! createComment(postId: ID!, text: String!): Comment! }

input CreateUserInput { email: String! firstName: String! lastName: String! role: UserRole! }

input UpdateUserInput { email: String firstName: String lastName: String role: UserRole }

input CreatePostInput { title: String! content: String! }

input UpdatePostInput { title: String content: String publishedAt: DateTime }

type Subscription { userCreated: User! postPublished: Post! commentAdded(postId: ID!): Comment! }

scalar DateTime

  1. Node.js Apollo Server Implementation const { ApolloServer, gql } = require('apollo-server-express'); const express = require('express');

const typeDefs = gql` type Query { user(id: ID!): User users: [User!]! }

type User { id: ID! email: String! firstName: String! lastName: String! posts: [Post!]! }

type Post { id: ID! title: String! content: String! author: User! }

type Mutation { createUser(email: String!, firstName: String!, lastName: String!): User! createPost(title: String!, content: String!): Post! } `;

const resolvers = { Query: { user: async (, { id }, { db }) => { return db.users.findById(id); }, users: async (, __, { db }) => { return db.users.findAll(); } },

User: { posts: async (user, _, { db }) => { return db.posts.findByAuthorId(user.id); } },

Post: { author: async (post, _, { db }) => { return db.users.findById(post.authorId); } },

Mutation: { createUser: async (, { email, firstName, lastName }, { db }) => { const user = { id: Date.now().toString(), email, firstName, lastName }; db.users.save(user); return user; }, createPost: async (, { title, content }, { user, db }) => { if (!user) throw new Error('Unauthorized'); const post = { id: Date.now().toString(), title, content, authorId: user.id }; db.posts.save(post); return post; } } };

const server = new ApolloServer({ typeDefs, resolvers, context: ({ req }) => ({ user: req.user, db: require('./database') }) });

const app = express(); server.start().then(() => { server.applyMiddleware({ app }); app.listen(4000, () => console.log('GraphQL server running on port 4000')); });

  1. Python GraphQL Implementation (Graphene) import graphene from datetime import datetime from typing import List

class UserType(graphene.ObjectType): id = graphene.ID(required=True) email = graphene.String(required=True) first_name = graphene.String(required=True) last_name = graphene.String(required=True) posts = graphene.List(lambda: PostType)

class PostType(graphene.ObjectType): id = graphene.ID(required=True) title = graphene.String(required=True) content = graphene.String(required=True) author = graphene.Field(UserType) created_at = graphene.DateTime(required=True)

class Query(graphene.ObjectType): user = graphene.Field(UserType, id=graphene.ID(required=True)) users = graphene.List(UserType) posts = graphene.List(PostType, author_id=graphene.ID())

def resolve_user(self, info, id):
    return User.objects.get(pk=id)

def resolve_users(self, info):
    return User.objects.all()

def resolve_posts(self, info, author_id=None):
    if author_id:
        return Post.objects.filter(author_id=author_id)
    return Post.objects.all()

class CreateUserMutation(graphene.Mutation): class Arguments: email = graphene.String(required=True) first_name = graphene.String(required=True) last_name = graphene.String(required=True)

user = graphene.Field(UserType)
success = graphene.Boolean()

def mutate(self, info, email, first_name, last_name):
    user = User.objects.create(
        email=email,
        first_name=first_name,
        last_name=last_name
    )
    return CreateUserMutation(user=user, success=True)

class Mutation(graphene.ObjectType): create_user = CreateUserMutation.Field()

schema = graphene.Schema(query=Query, mutation=Mutation)

  1. Query Examples

Get user with posts

query GetUserWithPosts { user(id: "123") { id email firstName posts { id title createdAt } } }

Paginated users query

query GetUsers($limit: Int, $offset: Int) { users(limit: $limit, offset: $offset) { id email firstName } }

Search across types

query Search($query: String!) { search(query: $query) { ... on User { id email } ... on Post { id title } } }

Create user mutation

mutation CreateUser($input: CreateUserInput!) { createUser(input: $input) { id email firstName } }

Subscribe to new comments

subscription OnCommentAdded($postId: ID!) { commentAdded(postId: $postId) { id text author { firstName } } }

  1. Error Handling const resolvers = { Query: { user: async (_, { id }) => { try { const user = await User.findById(id); if (!user) { throw new GraphQLError('User not found', { extensions: { code: 'NOT_FOUND', userId: id } }); } return user; } catch (error) { throw new GraphQLError('Database error', { originalError: error, extensions: { code: 'INTERNAL_ERROR' } }); } } } };

server.formatError = (formattedError) => ({ message: formattedError.message, code: formattedError.extensions?.code || 'INTERNAL_ERROR', timestamp: new Date().toISOString() });

Best Practices ✅ DO Use clear, descriptive field names Design schemas around client needs Implement proper error handling Use input types for mutations Add subscriptions for real-time data Cache resolvers efficiently Validate input data Use federation for scalability ❌ DON'T Over-nest queries deeply Expose internal database IDs Return sensitive data without authorization Create overly complex schemas Forget to handle null values Ignore N+1 query problems Skip error messages Performance Tips Use DataLoader to batch database queries Implement query complexity analysis Cache at resolver level Use connection patterns for pagination Monitor query execution time

返回排行榜