Apollo graphQL
Apollo 提供了一套完整的 graphQL 实现方案,它以MIT协议开源了 Node.js 服务端、多种客户端 SDK(JavaScript/React、Kotlin、iOS)。Apollo 团队也销售 graphQL 云服务。
client
npm社区有 facebook 维护的开源库 graphql
作为 JavaScript 参考实现,它的作用是根据输入的Schema、用户代码,输出符合graphQL 格式的查询代码。
Apollo 团队在 graphql
的基础上开发出 graphql-tag
库简化使用,提供一个模板标签函数gql
根据用户代码输出符合graph QL 格式的查询代码,同时支持书写Schema,但不验证,以减小JS大小,毕竟在生产环境中Schema是由服务端确定校验的。
从npm下载量来看, graphql-tag
为 graphql
提供了超过一半的下载量。
客户端使用Apollo分为两步:
- 初始化
ApolloClient
实例client
,配置uri、cache - 使用
client.query()
发起 graphQL 请求
本文客户端代码以Apollo官方文档 JavaScript React 为例。
Apollo为简化React使用,提供ApolloProvider
组件在全局上下文挂载client
,提供useQuery
实现 React Hooks。
jsx
import { ApolloClient, ApolloProvider, InMemoryCache } from "@apollo/client";
const client = new ApolloClient({
uri: 'http://localhost:3000/apollo',
cache: new InMemoryCache(),
})
export function(){
return (
<ApolloProvider client={client}>
<App/>
</ApolloProvider>
)
}
jsx
// App.jsx
import { useQuery, gql } from '@apollo/client'
const gqlBooks = gql`
query {
books {
title
}
}
`
function DisplayBooks() {
const { loading, error, data } = useQuery(gqlBooks)
if (loading) return <p>Loading...</p>
if (error) return <p>Error : {error.message}</p>
return data.books.map((item: { title: string }, index: number) => (
<p key={index}>{item.title}</p>
))
}
export default function() {
return (
<DisplayBooks />
)
}
server
在 Node.js 服务端,Apollo 实现为一个独立的 ApolloServer
,并提供express服务器中间件 expressMiddleware
、基于express服务器封装的一个独立服务器 startStandaloneServer
简化使用。
三者的区别是:
startStandaloneServer
用于快速实现一个graphQL HTTP服务器expressMiddleware
用于接入 express 实现的HTTP服务器ApolloServer
用于自定义接入 Node.js 实现的HTTP服务器
采用 expressMiddleware
开发的 Demo 源码
服务端代码结构如下
js
import http from 'http';
import express from "express";
import cors from 'cors';
import bodyParser from 'body-parser';
import { ApolloServer } from '@apollo/server'
import { expressMiddleware } from '@apollo/server/express4';
const app = express();
const httpServer = http.createServer(app);
const server = new ApolloServer({
typeDefs, // graphQL类型定义,如Schema
resolvers, // graphQL类型定义的解析器
})
await server.start()
app.use(
'/apollo',
cors(),
bodyParser.json(),
// expressMiddleware accepts the same arguments:
// an Apollo Server instance and optional configuration options
expressMiddleware(server, {
context: async ({ req }) => ({ token: req.headers.token }),
}),
);
app.listen(port)