第二章:Schema 定义¶
类型系统¶
标量类型¶
# 内置标量类型
scalar Int # 整数
scalar Float # 浮点数
scalar String # 字符串
scalar Boolean # 布尔值
scalar ID # 唯一标识符
# 自定义标量
scalar Date # 日期
scalar DateTime # 日期时间
scalar JSON # JSON 对象
scalar Upload # 文件上传
对象类型¶
# 定义对象类型
type User {
id: ID!
name: String!
email: String!
age: Int
isActive: Boolean!
createdAt: DateTime!
updatedAt: DateTime!
}
# 带描述的类型
"""
用户信息
"""
type User {
"""用户 ID"""
id: ID!
"""用户名"""
name: String!
"""邮箱地址"""
email: String!
}
枚举类型¶
# 定义枚举
enum UserStatus {
ACTIVE
INACTIVE
SUSPENDED
}
enum PostStatus {
DRAFT
PUBLISHED
ARCHIVED
}
# 使用枚举
type User {
id: ID!
name: String!
status: UserStatus!
}
接口类型¶
# 定义接口
interface Node {
id: ID!
createdAt: DateTime!
}
# 实现接口
type User implements Node {
id: ID!
createdAt: DateTime!
name: String!
email: String!
}
type Post implements Node {
id: ID!
createdAt: DateTime!
title: String!
content: String!
}
联合类型¶
# 定义联合类型
union SearchResult = User | Post
# 查询联合类型
query {
search(query: "test") {
... on User {
id
name
email
}
... on Post {
id
title
content
}
}
}
输入类型¶
Input 类型¶
# 定义输入类型
input CreateUserInput {
name: String!
email: String!
age: Int
}
input UpdateUserInput {
name: String
email: String
age: Int
}
input UserFilter {
status: UserStatus
name: String
email: String
}
# 使用输入类型
type Mutation {
createUser(input: CreateUserInput!): User!
updateUser(id: ID!, input: UpdateUserInput!): User!
users(filter: UserFilter): [User!]!
}
分页输入¶
# 分页输入
input PaginationInput {
page: Int = 1
pageSize: Int = 10
}
# 排序输入
input SortInput {
field: String!
order: SortOrder = ASC
}
enum SortOrder {
ASC
DESC
}
输出类型¶
分页输出¶
# 分页信息
type PageInfo {
page: Int!
pageSize: Int!
total: Int!
totalPages: Int!
hasNextPage: Boolean!
hasPreviousPage: Boolean!
}
# 分页结果
type UserConnection {
data: [User!]!
pageInfo: PageInfo!
}
# 查询
type Query {
users(pagination: PaginationInput): UserConnection!
}
响应包装¶
# 通用响应
type Response {
success: Boolean!
message: String
code: Int
}
# 带数据的响应
type UserResponse {
success: Boolean!
message: String
data: User
}
# 错误响应
type ErrorResponse {
success: Boolean!
message: String!
code: Int!
errors: [FieldError!]
}
type FieldError {
field: String!
message: String!
}
指令¶
内置指令¶
# @skip - 条件跳过
query ($withPosts: Boolean!) {
user(id: "1") {
name
posts @skip(if: $withPosts) {
title
}
}
}
# @include - 条件包含
query ($withPosts: Boolean!) {
user(id: "1") {
name
posts @include(if: $withPosts) {
title
}
}
}
# @deprecated - 废弃字段
type User {
id: ID!
name: String!
email: String!
username: String @deprecated(reason: "Use 'name' instead")
}
自定义指令¶
# 定义指令
directive @auth(requires: Role = USER) on FIELD_DEFINITION
enum Role {
ADMIN
USER
}
# 使用指令
type Query {
user(id: ID!): User @auth(requires: USER)
adminData: String @auth(requires: ADMIN)
}
Schema 组织¶
模块化¶
# user.graphql
extend type Query {
user(id: ID!): User
users: [User!]!
}
extend type Mutation {
createUser(input: CreateUserInput!): User!
updateUser(id: ID!, input: UpdateUserInput!): User!
deleteUser(id: ID!): Boolean!
}
type User {
id: ID!
name: String!
email: String!
}
# post.graphql
extend type Query {
post(id: ID!): Post
posts: [Post!]!
}
extend type Mutation {
createPost(input: CreatePostInput!): Post!
}
type Post {
id: ID!
title: String!
content: String!
author: User!
}
合并 Schema¶
// JavaScript 合并
const { mergeTypeDefs } = require('@graphql-tools/merge');
const userSchema = fs.readFileSync('user.graphql', 'utf-8');
const postSchema = fs.readFileSync('post.graphql', 'utf-8');
const typeDefs = mergeTypeDefs([userSchema, postSchema]);
小结¶
Schema 定义要点:
- 类型系统:标量、对象、枚举、接口、联合
- 输入类型:Input、分页、排序
- 输出类型:分页、响应包装
- 指令:内置指令、自定义指令
- Schema 组织:模块化、合并
下一章我们将学习 Query 查询。