GraphQL 基础语法 #

基本结构 #

GraphQL 请求的基本结构非常简单,由操作类型和选择集组成:

text
┌─────────────────────────────────────────────────────────────┐
│                    GraphQL 请求结构                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  操作类型        选择集                                      │
│     │              │                                        │
│     ▼              ▼                                        │
│  query {                                                    │
│    user {          ← 字段                                   │
│      name          ← 子字段                                 │
│      email                                                  │
│    }                                                        │
│  }                                                          │
│                                                             │
│  操作类型:                                                  │
│  - query:查询数据(读取)                                   │
│  - mutation:变更数据(写入)                                │
│  - subscription:订阅数据(实时)                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

字段(Fields) #

字段是 GraphQL 查询的基本单位,用于指定要获取的数据。

简单字段 #

graphql
query {
  user {
    name
    email
  }
}

响应:

json
{
  "data": {
    "user": {
      "name": "Alice",
      "email": "alice@example.com"
    }
  }
}

嵌套字段 #

GraphQL 允许嵌套查询关联数据:

graphql
query {
  user {
    name
    posts {
      title
      comments {
        content
        author {
          name
        }
      }
    }
  }
}

响应:

json
{
  "data": {
    "user": {
      "name": "Alice",
      "posts": [
        {
          "title": "GraphQL 入门",
          "comments": [
            {
              "content": "很棒的教程!",
              "author": {
                "name": "Bob"
              }
            }
          ]
        }
      ]
    }
  }
}

列表字段 #

当字段返回列表时,仍然使用相同的语法:

graphql
query {
  users {
    id
    name
    email
  }
}

响应:

json
{
  "data": {
    "users": [
      {
        "id": "1",
        "name": "Alice",
        "email": "alice@example.com"
      },
      {
        "id": "2",
        "name": "Bob",
        "email": "bob@example.com"
      }
    ]
  }
}

参数(Arguments) #

GraphQL 字段可以接受参数,用于过滤、分页等操作。

基本参数 #

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

多个参数 #

graphql
query {
  posts(status: "published", limit: 10) {
    title
    content
  }
}

参数类型 #

graphql
query {
  user(
    id: "1"
    name: "Alice"
    age: 25
    isActive: true
    tags: ["developer", "designer"]
  ) {
    id
  }
}

参数类型说明:

类型 示例 说明
String "hello" 字符串,用双引号包裹
Int 42 整数
Float 3.14 浮点数
Boolean true / false 布尔值
ID "1" ID 类型,通常为字符串
Enum ACTIVE 枚举值,不加引号
List [1, 2, 3] 列表
Object { name: "Alice" } 输入对象

输入对象参数 #

复杂参数可以使用输入对象:

graphql
query {
  search(input: { keyword: "GraphQL", category: "TECH", limit: 10 }) {
    id
    title
    score
  }
}

别名(Aliases) #

当需要查询同名字段或同一字段多次时,使用别名区分。

同名字段别名 #

graphql
query {
  hero: character(id: "1") {
    name
  }
  villain: character(id: "2") {
    name
  }
}

响应:

json
{
  "data": {
    "hero": {
      "name": "Luke Skywalker"
    },
    "villain": {
      "name": "Darth Vader"
    }
  }
}

字段别名 #

graphql
query {
  user {
    fullName: name
    contactEmail: email
  }
}

响应:

json
{
  "data": {
    "user": {
      "fullName": "Alice",
      "contactEmail": "alice@example.com"
    }
  }
}

实际应用场景 #

graphql
query {
  primaryUser: user(role: "primary") {
    id
    name
  }
  secondaryUsers: users(role: "secondary", limit: 5) {
    id
    name
  }
  adminUser: user(role: "admin") {
    id
    name
  }
}

片段(Fragments) #

片段是可复用的选择集,用于避免重复代码。

定义片段 #

graphql
fragment userFields on User {
  id
  name
  email
  createdAt
}

使用片段 #

graphql
query {
  user(id: "1") {
    ...userFields
  }
  users {
    ...userFields
  }
}

fragment userFields on User {
  id
  name
  email
  createdAt
}

片段组合 #

graphql
query {
  user(id: "1") {
    ...basicInfo
    ...contactInfo
  }
}

fragment basicInfo on User {
  id
  name
}

fragment contactInfo on User {
  email
  phone
}

嵌套片段 #

graphql
query {
  posts {
    title
    author {
      ...authorFields
    }
  }
}

fragment authorFields on User {
  id
  name
  avatar
}

变量(Variables) #

变量使查询更加动态和可复用。

定义变量 #

graphql
query GetUser($id: ID!) {
  user(id: $id) {
    name
    email
  }
}

变量值:

json
{
  "id": "1"
}

变量类型 #

graphql
query SearchPosts(
  $keyword: String
  $category: PostCategory
  $limit: Int = 10
  $offset: Int = 0
) {
  search(keyword: $keyword, category: $category, limit: $limit, offset: $offset) {
    title
    content
  }
}

必填与可选变量 #

graphql
query (
  $id: ID!       $name: String
) {
  user(id: $id, name: $name) {
    id
    name
  }
}

变量默认值 #

graphql
query GetPosts($limit: Int = 10, $status: String = "published") {
  posts(limit: $limit, status: $status) {
    title
  }
}

输入对象变量 #

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

变量值:

json
{
  "input": {
    "name": "Alice",
    "email": "alice@example.com",
    "age": 25
  }
}

操作名称(Operation Name) #

为操作命名可以提高可读性和调试效率。

命名查询 #

graphql
query GetUserProfile {
  user(id: "1") {
    name
    email
    posts {
      title
    }
  }
}

命名变更 #

graphql
mutation CreateNewUser {
  createUser(input: { name: "Bob", email: "bob@example.com" }) {
    id
    name
  }
}

命名订阅 #

graphql
subscription WatchMessages {
  onMessageCreated {
    id
    content
    createdAt
  }
}

带变量的命名操作 #

graphql
query GetUserById($id: ID!) {
  user(id: $id) {
    name
    email
  }
}

指令(Directives) #

指令用于动态控制查询行为。

@include 指令 #

条件包含字段:

graphql
query GetUser($id: ID!, $withPosts: Boolean!) {
  user(id: $id) {
    name
    posts @include(if: $withPosts) {
      title
    }
  }
}

变量值:

json
{
  "id": "1",
  "withPosts": true
}

@skip 指令 #

条件跳过字段:

graphql
query GetUser($id: ID!, $skipDetails: Boolean!) {
  user(id: $id) {
    name
    email
    details @skip(if: $skipDetails) {
      bio
      location
    }
  }
}

指令组合 #

graphql
query GetPosts(
  $includeContent: Boolean!
  $skipComments: Boolean!
) {
  posts {
    title
    content @include(if: $includeContent)
    comments @skip(if: $skipComments) {
      text
    }
  }
}

自定义指令 #

服务端可以定义自定义指令:

graphql
query {
  posts {
    title
    content @deprecated(reason: "Use `body` field instead")
  }
}

内联片段(Inline Fragments) #

内联片段用于处理接口和联合类型。

接口类型 #

graphql
query {
  search(text: "an") {
    ... on Human {
      name
      height
    }
    ... on Droid {
      name
      primaryFunction
    }
    ... on Starship {
      name
      length
    }
  }
}

联合类型 #

graphql
query {
  media(id: "1") {
    ... on Video {
      title
      duration
      thumbnail
    }
    ... on Audio {
      title
      duration
      bitrate
    }
    ... on Image {
      title
      width
      height
    }
  }
}

类型条件 #

graphql
query {
  character(id: "1") {
    name
    ... on Human {
      homePlanet
    }
    ... on Droid {
      manufacturer
    }
  }
}

多操作文档 #

一个 GraphQL 文档可以包含多个操作。

多个查询 #

graphql
query GetUser {
  user(id: "1") {
    name
  }
}

query GetPosts {
  posts {
    title
  }
}

混合操作 #

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

mutation UpdateUser {
  updateUser(id: "1", input: { name: "New Name" }) {
    name
  }
}

subscription OnUserUpdate {
  onUserUpdated {
    id
    name
  }
}

执行特定操作 #

graphql
query GetUserProfile {
  user(id: "1") {
    name
  }
}

query GetUserPosts {
  user(id: "1") {
    posts {
      title
    }
  }
}

执行时指定操作名:GetUserProfileGetUserPosts

注释 #

GraphQL 支持注释,注释不会出现在响应中。

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

格式化最佳实践 #

缩进 #

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

一行简写 #

对于简单查询可以使用一行:

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

参数换行 #

参数较多时换行:

graphql
query Search(
  $keyword: String!
  $category: String
  $limit: Int = 10
  $offset: Int = 0
  $sortBy: String = "createdAt"
  $sortOrder: SortOrder = DESC
) {
  search(
    keyword: $keyword
    category: $category
    limit: $limit
    offset: $offset
    sortBy: $sortBy
    sortOrder: $sortOrder
  ) {
    id
    title
  }
}

请求格式 #

GraphQL 请求通常通过 HTTP POST 发送。

请求体格式 #

json
{
  "query": "query GetUser($id: ID!) { user(id: $id) { name email } }",
  "variables": {
    "id": "1"
  },
  "operationName": "GetUser"
}

字段说明 #

字段 必填 说明
query GraphQL 查询字符串
variables 变量对象
operationName 操作名称(多操作时必填)

HTTP 请求示例 #

http
POST /graphql HTTP/1.1
Content-Type: application/json

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

带变量的请求 #

http
POST /graphql HTTP/1.1
Content-Type: application/json

{
  "query": "query GetUser($id: ID!) { user(id: $id) { name email } }",
  "variables": { "id": "1" },
  "operationName": "GetUser"
}

响应格式 #

GraphQL 响应始终返回 JSON 格式。

成功响应 #

json
{
  "data": {
    "user": {
      "name": "Alice",
      "email": "alice@example.com"
    }
  }
}

错误响应 #

json
{
  "errors": [
    {
      "message": "User not found",
      "locations": [{ "line": 2, "column": 3 }],
      "path": ["user"]
    }
  ],
  "data": {
    "user": null
  }
}

部分成功响应 #

json
{
  "data": {
    "user": {
      "name": "Alice",
      "posts": null
    }
  },
  "errors": [
    {
      "message": "Failed to fetch posts",
      "path": ["user", "posts"]
    }
  ]
}

实战示例 #

示例一:用户信息查询 #

graphql
query GetUserProfile($id: ID!) {
  user(id: $id) {
    id
    name
    email
    avatar
    createdAt
    posts(limit: 5) {
      id
      title
      views
    }
  }
}

示例二:文章搜索 #

graphql
query SearchPosts($input: SearchInput!) {
  search(input: $input) {
    total
    items {
      id
      title
      excerpt
      author {
        name
        avatar
      }
      tags
      createdAt
    }
  }
}

变量:

json
{
  "input": {
    "keyword": "GraphQL",
    "category": "TECH",
    "limit": 10,
    "offset": 0,
    "sortBy": "createdAt",
    "sortOrder": "DESC"
  }
}

示例三:仪表板数据 #

graphql
query Dashboard {
  me {
    id
    name
    avatar
  }
  
  notifications(limit: 5, unread: true) {
    id
    message
    createdAt
  }
  
  recentProjects: projects(limit: 3) {
    id
    name
    progress
  }
  
  statistics {
    totalPosts
    totalViews
    totalFollowers
  }
}

常见错误 #

语法错误 #

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

错误:缺少右大括号

字段不存在 #

graphql
query {
  user(id: "1") {
    name
    nonExistentField
  }
}

错误:Cannot query field "nonExistentField" on type "User"

参数类型错误 #

graphql
query {
  user(id: 123) {
    name
  }
}

错误:Expected type ID, found 123

必填参数缺失 #

graphql
query {
  user {
    name
  }
}

错误:Field "user" argument "id" of type "ID!" is required

下一步 #

现在你已经掌握了 GraphQL 的基础语法,接下来学习 查询操作详解,深入了解各种查询技巧!

最后更新:2026-03-29