GraphQL 入门:API 开发的新范式
什么是 GraphQL?
GraphQL 是一种用于 API 的查询语言,由 Facebook 在 2012 年开发并于 2015 年开源。它提供了一种更高效、更灵活的数据获取方式。
GraphQL vs REST
| 特性 | REST | GraphQL |
|---|---|---|
| 数据获取 | 多个请求 | 单个请求 |
| 响应数据 | 固定结构 | 按需获取 |
| API 版本 | 需要版本控制 | 无需版本控制 |
| 错误处理 | HTTP 状态码 | 统一错误格式 |
GraphQL 核心概念
1. Schema(模式)
定义数据结构和可用操作:
graphql
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
content: String!
author: User!
}
type Query {
user(id: ID!): User
posts: [Post!]!
}
type Mutation {
createUser(name: String!, email: String!): User
}
2. Query(查询)
获取数据:
graphql
query GetUserWithPosts {
user(id: "1") {
id
name
email
posts {
title
content
}
}
}
3. Mutation(变更)
修改数据:
graphql
mutation CreateUser {
createUser(name: "John", email: "john@example.com") {
id
name
email
}
}
搭建 GraphQL 服务器
使用 Apollo Server
javascript
const { ApolloServer, gql } = require('apollo-server');
const typeDefs = gql`
type Query {
hello: String
}
`;
const resolvers = {
Query: {
hello: () => 'Hello world!'
}
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
});
Resolvers(解析器)
javascript
const resolvers = {
Query: {
user: (parent, args, context, info) => {
return users.find(user => user.id === args.id);
},
posts: () => posts
},
User: {
posts: (parent) => {
return posts.filter(post => post.authorId === parent.id);
}
}
};
GraphQL 查询深度解析
查询变量
graphql
query GetUser($userId: ID!) {
user(id: $userId) {
name
email
}
}
javascript
{
"userId": "1"
}
片段(Fragments)
graphql
fragment UserFields on User {
id
name
email
}
query GetUsers {
users {
...UserFields
}
}
指令(Directives)
graphql
query GetUser($withPosts: Boolean!) {
user(id: "1") {
name
posts @include(if: $withPosts) {
title
}
}
}
实际应用场景
场景一:前端数据获取
javascript
import { ApolloClient, InMemoryCache, gql } from '@apollo/client';
const client = new ApolloClient({
uri: 'http://localhost:4000/graphql',
cache: new InMemoryCache()
});
client.query({
query: gql`
query GetUser {
user(id: "1") {
name
email
}
}
`
}).then(result => console.log(result));
场景二:分页查询
graphql
query GetPosts($offset: Int!, $limit: Int!) {
posts(offset: $offset, limit: $limit) {
edges {
node {
title
content
}
}
pageInfo {
hasNextPage
hasPreviousPage
}
}
}
场景三:实时数据(Subscriptions)
graphql
subscription NewPost {
newPost {
id
title
content
}
}
安全与性能
查询深度限制
javascript
const server = new ApolloServer({
typeDefs,
resolvers,
validationRules: [
depthLimit(5)
]
});
查询复杂度分析
javascript
const server = new ApolloServer({
typeDefs,
resolvers,
validationRules: [
complexityLimit(1000)
]
});
缓存策略
javascript
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
posts: {
merge(existing, incoming) {
return [...existing, ...incoming];
}
}
}
}
}
});
总结
GraphQL 为 API 开发带来了革命性的变化:
- 高效的数据获取:按需获取所需数据
- 灵活的查询方式:支持复杂查询和嵌套关系
- 强类型系统:提供更好的开发体验和错误检测
- 实时数据支持:通过 Subscriptions 实现实时更新
无论是前端开发还是后端架构,掌握 GraphQL 都将成为一项重要技能。它不仅能提高开发效率,还能改善用户体验。