GraphQL.js配合Apollo的例子,ApolloServer如何使用?
发布于 作者:苏南大叔 来源:程序如此灵动~
在前面的文章中,Graphql.js配合express和koa的例子,都做了实验。但是,express-graphql和koa-graphql都有一个比较大的问题,就是和最新的graphql@16是不兼容的。这里,提出了一个新的解决思路,就是apollo server。这款apollo代码可以单独使用,也可以配置express或者koa使用。

大家好,这里是苏南大叔的“程序如此灵动”博客,这里讲述苏南大叔和计算机代码的故事。本文讲述graphql和apollo server结合的例子。测试环境:win10,node@16.14.0,graphql@16.3.0,apollo server@3.6.4。本文中的apollo server@3.6.4和graphql@16并没有冲突的状况发生。
apollo server
在graphql的官方界面上,有对apollo server的推荐:
官方的文档页面是:
ApolloServer()的函数说明如下:

本文中单独使用apollo server,并不和express和koa结合。而且schema定义,数据逻辑处理方式深度结合上一篇文章中的内容,分为文本和代码两种模式定义。可以参考:

代码例子一
new ApolloServer()需要两个变量:
- 一个是
typeDefs,和以前的schema文本定义是一致的。 - 另外一个是
resolvers,这个和文本定义时的root类似,不同点是:resolvers的参数数量是两个。
完整代码如下:
const { ApolloServer, gql } = require('apollo-server');
const typeDefs = gql`
type Query {
"A simple type for getting started!"
hello: String
hola (name:String): String
bonjour (name:String,id:Int): human
}
type human {
id: Int
name: String
title: String
plus: String
}
`;
const resolvers = {
Query: {
hello: () => 'Hello world!',
hola: (para,args) => '?Hola ' + args.name + '!',
bonjour: (para,args) => {
return { 'id':args.id,'name':args.name,'title':'manager','plus':'wonderful'}
}
},
};
const server = new ApolloServer({
typeDefs,
resolvers,
});
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
});
这个略有奇怪的apollo-server的导出对象gql模版支持功能的说明文档,见下面:
{ typeDefs,resolvers } 实际上是 { typeDefs:typeDefs,resolvers:resolvers },所以,并不是不可以改名,这个是语法问题。
这两个参数的官方表述都是:Required unless you provide schema.。所以,除非给出schema,否则两个必填。
代码例子二
这个例子里面,apollo server延续代码定义schema的模式,并不存在单独的root参数,resolve是合并写在schema里面的。这个时候,new ApolloServer()仅仅需要一个变量schema。
完整代码如下:
const {
GraphQLSchema,
GraphQLObjectType,
GraphQLString,
GraphQLInt,
versionInfo
} = require('graphql');
const RootQueryType = new GraphQLObjectType({
name: 'Query',
description: 'Root Query',
fields: () => ({
hello: {
type: GraphQLString,
resolve() {
return 'hello world';
},
},
hola: {
type: GraphQLString,
description: 'hola query',
args: {
name: { type: GraphQLString }
},
resolve: (parent, args) => {
return 'hi,' + args.name
}
},
bonjour: {
type: human,
description: 'human bonjour',
args: {
id: { type: GraphQLInt },
name: { type: GraphQLString }
},
resolve: (parent, args) => {
return { id: args.id, name: args.name, title: "manager", plus:"plus" };
}
}
})
});
const human = new GraphQLObjectType({
name: 'human',
description: 'human',
fields: () => ({
id: { type: GraphQLInt },
name: { type: GraphQLString },
title: { type: GraphQLString },
plus: { type: GraphQLString },
})
})
const schema = new GraphQLSchema({
query: RootQueryType
})
const server = new ApolloServer({
schema
});
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
});
查询界面
apollo server官方自带的界面,是从本地跳到了官方页面,然后官方页面的代码再探索本地的接口。不得不说,思路清奇。但是,官方界面的服务器实在不给力,速度奇慢。而且所谓的增强的代码,也并没有强大到替换graphiql的地步。个人对这个apollo的替代界面,表示些许的质疑。
跳转到官方的服务器上面的沙盒查询界面地址是:

关于查询内容,apollo server的界面上给出的默认语句,比graphiql多两个单词,在{之前多两个单词,而且目前测试的情况下,这两个占位的文字可以随便乱写,都是可以顺利执行的。所以,可能是没有啥用的。否则graphiql中的默认查询语句里面,为啥没有这两个无用的占位呢?

参考文献
本文中的apollo server@3.6.4虽然和express或者koa之类的可以无缝结合。但是,
- 鉴于官方文档对于
nodejs新人很不友好,官方的例子里面,给出的代码例子对于nodejs新人来说,运行起来都比较困难。(需要配置babel/ts等进行代码转化) - 使用
apollo server的时候,使用自带的查询界面代替了官方的graphiql。这款新的查询界面虽然确实比官方的查询界面强大,但是最大的缺点是太慢,无法接受的慢。这也是苏南大叔不推荐apollo server的原因之一。 - https://www.apollographql.com/docs/apollo-server/getting-started/
- https://newsn.net/say/graphql.html
- https://newsn.net/say/graphql-node.html
- https://newsn.net/say/graphql-import-schema.html
总结
对于apollo server来说,虽然很好很强大,但是对于新人也是很难很复杂的。所以,高手可以使用apollo server,新人就老实的使用express-graphql就好。
更多graphql文章,请点击苏南大叔的博客: