graphql-implementation

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

GraphQL Implementation

GraphQL 实现

Build GraphQL APIs with proper schema design, resolvers, and performance optimization.
使用规范的Schema设计、解析器和性能优化方案构建GraphQL API。

Schema Definition

Schema 定义

graphql
type User {
  id: ID!
  name: String!
  email: String!
  posts(limit: Int = 10): [Post!]!
}

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

type Query {
  user(id: ID!): User
  users(limit: Int, offset: Int): [User!]!
  post(id: ID!): Post
}

type Mutation {
  createUser(input: CreateUserInput!): User!
  createPost(input: CreatePostInput!): Post!
}

input CreateUserInput {
  name: String!
  email: String!
}
graphql
type User {
  id: ID!
  name: String!
  email: String!
  posts(limit: Int = 10): [Post!]!
}

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

type Query {
  user(id: ID!): User
  users(limit: Int, offset: Int): [User!]!
  post(id: ID!): Post
}

type Mutation {
  createUser(input: CreateUserInput!): User!
  createPost(input: CreatePostInput!): Post!
}

input CreateUserInput {
  name: String!
  email: String!
}

Apollo Server Setup

Apollo Server 搭建

javascript
const { ApolloServer } = require('@apollo/server');
const { startStandaloneServer } = require('@apollo/server/standalone');

const resolvers = {
  Query: {
    user: (_, { id }, { dataSources }) =>
      dataSources.userAPI.getUser(id),
    users: (_, { limit, offset }, { dataSources }) =>
      dataSources.userAPI.getUsers({ limit, offset })
  },
  User: {
    posts: (user, { limit }, { dataSources }) =>
      dataSources.postAPI.getPostsByUser(user.id, limit)
  },
  Mutation: {
    createUser: (_, { input }, { dataSources }) =>
      dataSources.userAPI.createUser(input)
  }
};

const server = new ApolloServer({ typeDefs, resolvers });
javascript
const { ApolloServer } = require('@apollo/server');
const { startStandaloneServer } = require('@apollo/server/standalone');

const resolvers = {
  Query: {
    user: (_, { id }, { dataSources }) =>
      dataSources.userAPI.getUser(id),
    users: (_, { limit, offset }, { dataSources }) =>
      dataSources.userAPI.getUsers({ limit, offset })
  },
  User: {
    posts: (user, { limit }, { dataSources }) =>
      dataSources.postAPI.getPostsByUser(user.id, limit)
  },
  Mutation: {
    createUser: (_, { input }, { dataSources }) =>
      dataSources.userAPI.createUser(input)
  }
};

const server = new ApolloServer({ typeDefs, resolvers });

DataLoader for N+1 Prevention

使用DataLoader 避免N+1查询问题

javascript
const DataLoader = require('dataloader');

const userLoader = new DataLoader(async (ids) => {
  const users = await User.find({ _id: { $in: ids } });
  return ids.map(id => users.find(u => u.id === id));
});
javascript
const DataLoader = require('dataloader');

const userLoader = new DataLoader(async (ids) => {
  const users = await User.find({ _id: { $in: ids } });
  return ids.map(id => users.find(u => u.id === id));
});

Error Handling

错误处理

javascript
const { GraphQLError } = require('graphql');

throw new GraphQLError('User not found', {
  extensions: { code: 'NOT_FOUND', argumentName: 'id' }
});
javascript
const { GraphQLError } = require('graphql');

throw new GraphQLError('User not found', {
  extensions: { code: 'NOT_FOUND', argumentName: 'id' }
});

Best Practices

最佳实践

  • Use DataLoader to batch queries
  • Implement query complexity limits
  • Design schema around client needs
  • Validate all inputs
  • Use descriptive naming conventions
  • 使用DataLoader批量处理查询
  • 实现查询复杂度限制
  • 围绕客户端需求设计Schema
  • 验证所有输入参数
  • 使用描述性命名规范

Python Graphene

Python Graphene实现

See references/python-graphene.md for complete Flask implementation with:
  • ObjectType definitions
  • Query and Mutation classes
  • Input types
  • Flask integration
查看 references/python-graphene.md 获取完整的Flask实现,包括:
  • ObjectType定义
  • Query和Mutation类
  • 输入类型
  • Flask集成

Best Practices

最佳实践

Do:
  • Use DataLoader to batch queries
  • Implement query complexity limits
  • Design schema around client needs
  • Validate all inputs
  • Use descriptive naming conventions
  • Add subscriptions for real-time data
Don't:
  • Allow deeply nested queries without limits
  • Expose database internals
  • Ignore N+1 query problems
  • Return unauthorized data
  • Skip input validation
建议:
  • 使用DataLoader批量处理查询
  • 实现查询复杂度限制
  • 围绕客户端需求设计Schema
  • 验证所有输入参数
  • 使用描述性命名规范
  • 添加订阅以支持实时数据
避免:
  • 允许无限制的深度嵌套查询
  • 暴露数据库内部细节
  • 忽略N+1查询问题
  • 返回未授权数据
  • 跳过输入验证