使用GraphQL构建现代API
- GraphQL简介
- 安装GraphQL
- 使用npm安装GraphQL
- 使用Yarn安装GraphQL
- 创建GraphQL服务器
- 定义Schema
- 编写Resolver
- 查询数据
- 变更数据
- 使用Apollo Client
- GraphQL订阅
- 数据验证
- 错误处理
- 分页查询
- 拆分和组合Schema
- 总结
随着API的发展,传统的RESTful API逐渐显露出其局限性,特别是在需要灵活的数据查询和减少网络往返次数的应用场景中。GraphQL作为一种新兴的数据查询和操作语言,正好弥补了这一缺陷。本文将详细介绍如何使用GraphQL来构建现代API。
GraphQL简介
安装GraphQL
使用npm安装GraphQL
npm install graphql graphql-yoga
使用Yarn安装GraphQL
yarn add graphql graphql-yoga
创建GraphQL服务器
const { GraphQLServer } = require('graphql-yoga');
const resolvers = {
Query: {
hello: () => 'Hello World!',
},
};
const server = new GraphQLServer({ typeDefs, resolvers });
server.start(() => console.log('Server running on http://localhost:4000'));
定义Schema
type Query {
hello: String
}
编写Resolver
const resolvers = {
Query: {
hello: () => 'Hello World!',
},
};
查询数据
query {
hello
}
变更数据
schema {
query: Query
mutation: Mutation
}
... existing schema ...
type Mutation {
incrementCount: Int!
}
const resolvers = {
... existing resolvers ...
Mutation: {
incrementCount: (parent, args, context, info) => {
context.count++;
return context.count;
}
}
};
mutation {
incrementCount
}
使用Apollo Client
npm install @apollo/client
import { ApolloClient, InMemoryCache, gql } from '@apollo/client';
const client = new ApolloClient({
uri: 'http://localhost:4000/',
cache: new InMemoryCache(),
});
client.query({
query: gql`{
hello
}`,
}).then(console.log);
GraphQL订阅
subscription {
countUpdated @subscription
}
const resolvers = {
Subscription: {
countUpdated: {
subscribe: (parent, args, { pubsub }) => {
return pubsub.asyncIterator('COUNT_UPDATED');
}
}
}
};
const pubsub = new PubSub();
// Inside resolver that modifies the count
pubsub.publish('COUNT_UPDATED', { countUpdated: context.count });
数据验证
type User {
id: ID!
name: String!
email: String!
}
const resolvers = {
Query: {
user: () => ({ id: '1', name: 'Alice', email: 'alice@example.com' }),
},
};
错误处理
const resolvers = {
Query: {
user: () => {
throw new Error('User not found');
},
},
};
query {
user {
id
name
email
}
}
分页查询
type Query {
users(first: Int, after: String): UsersConnection
}
union UsersConnection = UsersPage
type UsersPage {
edges: [UserEdge]!
pageInfo: PageInfo!
}
type UserEdge {
node: User!
cursor: String!
}
type PageInfo {
hasNextPage: Boolean!
endCursor: String
}
const resolvers = {
Query: {
users: (parent, { first, after }) => {
const users = [{ id: '1', name: 'Alice', email: 'alice@example.com' }, { id: '2', name: 'Bob', email: 'bob@example.com' }];
const pageOfUsers = users.slice(0, first);
const pageInfo = {
hasNextPage: pageOfUsers.length < users.length,
endCursor: pageOfUsers[pageOfUsers.length - 1].id,
};
return {
edges: pageOfUsers.map(user => ({ node: user, cursor: user.id })),
pageInfo,
};
},
},
};
拆分和组合Schema
import { makeExecutableSchema } from '@graphql-tools/schema';
import { loadFilesSync } from '@graphql-tools/load-files';
import path from 'path';
const typeDefsArray = loadFilesSync(path.join(__dirname, './schema/**/*.graphql'));
const resolversArray = loadFilesSync(path.join(__dirname, './resolvers/**/*.js'));
const schema = makeExecutableSchema({
typeDefs: typeDefsArray,
resolvers: resolversArray,
});
总结
使用GraphQL可以让你构建出更加高效和灵活的API。