graphql-implementation

安装量: 51
排名: #23551

安装

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

← 返回排行榜