graphql

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

GraphQL

GraphQL

Schema design, queries, mutations, and tooling.
模式设计、查询、变更及工具相关内容。

Schema Definition

模式定义

graphql
undefined
graphql
undefined

Type definitions

Type definitions

type User { id: ID! email: String! name: String posts: [Post!]! createdAt: DateTime! }
type Post { id: ID! title: String! content: String published: Boolean! author: User! tags: [Tag!]! }
type Tag { id: ID! name: String! posts: [Post!]! }
type User { id: ID! email: String! name: String posts: [Post!]! createdAt: DateTime! }
type Post { id: ID! title: String! content: String published: Boolean! author: User! tags: [Tag!]! }
type Tag { id: ID! name: String! posts: [Post!]! }

Input types

Input types

input CreateUserInput { email: String! name: String }
input UpdateUserInput { email: String name: String }
input PostFilter { published: Boolean authorId: ID search: String }
input CreateUserInput { email: String! name: String }
input UpdateUserInput { email: String name: String }
input PostFilter { published: Boolean authorId: ID search: String }

Enums

Enums

enum Role { ADMIN USER MODERATOR }
enum SortOrder { ASC DESC }
enum Role { ADMIN USER MODERATOR }
enum SortOrder { ASC DESC }

Custom scalars

Custom scalars

scalar DateTime scalar JSON
scalar DateTime scalar JSON

Interfaces

Interfaces

interface Node { id: ID! }
type User implements Node { id: ID! email: String! }
interface Node { id: ID! }
type User implements Node { id: ID! email: String! }

Unions

Unions

union SearchResult = User | Post | Tag
undefined
union SearchResult = User | Post | Tag
undefined

Queries

查询

graphql
type Query {
  # Single item
  user(id: ID!): User
  post(id: ID!): Post

  # Lists with filtering and pagination
  users(
    filter: UserFilter
    limit: Int = 20
    offset: Int = 0
    orderBy: SortOrder = DESC
  ): UserConnection!

  posts(
    filter: PostFilter
    first: Int
    after: String
  ): PostConnection!

  # Search
  search(query: String!): [SearchResult!]!

  # Current user
  me: User
}
graphql
type Query {
  # 单个条目
  user(id: ID!): User
  post(id: ID!): Post

  # 带筛选和分页的列表
  users(
    filter: UserFilter
    limit: Int = 20
    offset: Int = 0
    orderBy: SortOrder = DESC
  ): UserConnection!

  posts(
    filter: PostFilter
    first: Int
    after: String
  ): PostConnection!

  # 搜索
  search(query: String!): [SearchResult!]!

  # 当前用户
  me: User
}

Cursor-based pagination

基于游标分页

type UserConnection { edges: [UserEdge!]! pageInfo: PageInfo! totalCount: Int! }
type UserEdge { node: User! cursor: String! }
type PageInfo { hasNextPage: Boolean! hasPreviousPage: Boolean! startCursor: String endCursor: String }
undefined
type UserConnection { edges: [UserEdge!]! pageInfo: PageInfo! totalCount: Int! }
type UserEdge { node: User! cursor: String! }
type PageInfo { hasNextPage: Boolean! hasPreviousPage: Boolean! startCursor: String endCursor: String }
undefined

Query Examples

查询示例

graphql
undefined
graphql
undefined

Basic query

基础查询

query { user(id: "1") { name email } }
query { user(id: "1") { name email } }

With variables

带变量的查询

query GetUser($id: ID!) { user(id: $id) { name email posts { title published } } }
query GetUser($id: ID!) { user(id: $id) { name email posts { title published } } }

Fragment

片段

fragment UserFields on User { id name email }
query { user(id: "1") { ...UserFields posts { title } } }
fragment UserFields on User { id name email }
query { user(id: "1") { ...UserFields posts { title } } }

Pagination

分页查询

query GetPosts($first: Int!, $after: String) { posts(first: $first, after: $after) { edges { node { id title } cursor } pageInfo { hasNextPage endCursor } } }
undefined
query GetPosts($first: Int!, $after: String) { posts(first: $first, after: $after) { edges { node { id title } cursor } pageInfo { hasNextPage endCursor } } }
undefined

Mutations

变更

graphql
type Mutation {
  createUser(input: CreateUserInput!): User!
  updateUser(id: ID!, input: UpdateUserInput!): User!
  deleteUser(id: ID!): Boolean!

  createPost(input: CreatePostInput!): Post!
  publishPost(id: ID!): Post!

  login(email: String!, password: String!): AuthPayload!
}

type AuthPayload {
  token: String!
  user: User!
}
graphql
type Mutation {
  createUser(input: CreateUserInput!): User!
  updateUser(id: ID!, input: UpdateUserInput!): User!
  deleteUser(id: ID!): Boolean!

  createPost(input: CreatePostInput!): Post!
  publishPost(id: ID!): Post!

  login(email: String!, password: String!): AuthPayload!
}

type AuthPayload {
  token: String!
  user: User!
}

Mutation Examples

变更示例

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

Variables:

变量:

{ "input": { "email": "alice@test.com", "name": "Alice" } }

{ "input": { "email": "alice@test.com", "name": "Alice" } }

mutation Login($email: String!, $password: String!) { login(email: $email, password: $password) { token user { id name } } }
undefined
mutation Login($email: String!, $password: String!) { login(email: $email, password: $password) { token user { id name } } }
undefined

Subscriptions

订阅

graphql
type Subscription {
  postCreated: Post!
  messageReceived(channelId: ID!): Message!
}
graphql
type Subscription {
  postCreated: Post!
  messageReceived(channelId: ID!): Message!
}

Client usage

客户端使用示例

subscription OnPostCreated { postCreated { id title author { name } } }
undefined
subscription OnPostCreated { postCreated { id title author { name } } }
undefined

Resolvers (Node.js)

解析器(Node.js)

typescript
const resolvers = {
  Query: {
    user: (_, { id }, context) => context.db.user.findUnique({ where: { id } }),
    users: (_, { filter, limit, offset }, context) =>
      context.db.user.findMany({ where: filter, take: limit, skip: offset }),
    me: (_, __, context) => context.currentUser,
  },

  Mutation: {
    createUser: (_, { input }, context) =>
      context.db.user.create({ data: input }),
    updateUser: (_, { id, input }, context) =>
      context.db.user.update({ where: { id }, data: input }),
  },

  User: {
    posts: (user, _, context) =>
      context.db.post.findMany({ where: { authorId: user.id } }),
  },
};
typescript
const resolvers = {
  Query: {
    user: (_, { id }, context) => context.db.user.findUnique({ where: { id } }),
    users: (_, { filter, limit, offset }, context) =>
      context.db.user.findMany({ where: filter, take: limit, skip: offset }),
    me: (_, __, context) => context.currentUser,
  },

  Mutation: {
    createUser: (_, { input }, context) =>
      context.db.user.create({ data: input }),
    updateUser: (_, { id, input }, context) =>
      context.db.user.update({ where: { id }, data: input }),
  },

  User: {
    posts: (user, _, context) =>
      context.db.post.findMany({ where: { authorId: user.id } }),
  },
};

Error Handling

错误处理

graphql
undefined
graphql
undefined

Union-based errors

基于联合类型的错误

type CreateUserResult = CreateUserSuccess | ValidationError | EmailTakenError
type CreateUserSuccess { user: User! }
type ValidationError { message: String! field: String! }
type EmailTakenError { message: String! suggestedEmail: String }
type Mutation { createUser(input: CreateUserInput!): CreateUserResult! }
undefined
type CreateUserResult = CreateUserSuccess | ValidationError | EmailTakenError
type CreateUserSuccess { user: User! }
type ValidationError { message: String! field: String! }
type EmailTakenError { message: String! suggestedEmail: String }
type Mutation { createUser(input: CreateUserInput!): CreateUserResult! }
undefined

Reference

参考资料

For Apollo, Relay, and testing patterns:
references/tooling.md
关于Apollo、Relay及测试模式的内容,请查看:
references/tooling.md