egg-apollo-server
apollo-server-koa plugin in egg.
TheGetting Started
install
With yarn:
yarn add egg-apollo-server
or using npm
npm install --save egg-apollo-server
Usage
- 开启插件
// config/plugin.jsexportsgraphql = enable: true package: 'egg-apollo-server';
- 在 config/config.${env}.js 配置 graphql options。支持 apollo-server 中的所有 options.
configgraphql = router: '/graphql' app: true //是否加载到 app 上,默认为 true agent: false //是否加载到 agent 上,默认为 false graphiql: true //是否加载开发者工具 playground,默认为 true uploads: true //是否开启文件上传功能,默认开启 //是否添加默认的type Query,Mutation,默认为true //如果为true须使用extend type Query|extend type Mutation,因为graphql规定同一个type只能定义一个 //带来的好处时egg/graphql下不用再新建query,mutation目录 defaultEmptySchema: true //subscriptions的值为<Object>|<String>|false 见https://www.apollographql.com/docs/apollo-server/api/apollo-server/ //如果为String 表示订阅的路径 //如果为false 关闭订阅 //如果为object 可以添加path,keepAlive,onConnect,onDisconnect subscriptions: { console; if connectionParamsauthToken // return validateToken(connectionParams.authToken) // .then(findUser(connectionParams.authToken)) // .then(user => { // return { // currentUser: user, // } // }) // throw new Error('Missing auth token!') } //可选字段,接受项目中发生的错误,然后自定义错误返回给前端 { // console.log(error); applogger; return error; } debug: false // 发生错误时,是否包含错误堆栈信息,生产环境要设置为false; // 添加中间件拦截请求exportsmiddleware = 'graphql';
- 项目目录
在 app 目录下新建 graphql 目录, graphql 相关文件写在此目录,插件会读取 app/graphql 下所有目录里面的 graphql 相关文件
├── app
│ ├── controller
│ │ └── home.js
│ ├── graphql
│ │ ├── tag
│ │ │ ├── resolver.js
│ │ │ └── schema.graphql
│ │ └── user
│ │ ├── resolver.js
│ │ └── schema.graphql
│ ├── router.js
│ └── service
├── config
│ ├── config.default.js
│ └── plugin.js
├── package.json
└── package-lock.json
graphql 相关文件包含:
- schema.graphql
a GraphQL type language string
#插件设置了默认的Query,Mutation 所以不用定义Query,直接使用extend继承extend type Query { users: [User] user(id: ID!): User}type User { id: ID! name: String age: Int} extend type Mutation { addUser(input: AddUser): User updateUser(input: UpdateUser): User deleteUser(id: ID!): Boolean}input AddUser { name: String age: Int}input UpdateUser { id: ID! name: String age: Int}
- resolver.js
a nested object that maps type and field names to resolver functions
moduleexports = Query: { return users; } { const id = params; return users; } ;
- schemaDirective.js
a nested object that maps type and field names to resolver functions
const defaultFieldResolver = ;const SchemaDirectiveVisitor = ; { const resolve = defaultFieldResolver } = field; fieldresolve = async { const defaultText = await resolve; if typeof defaultText === 'string' return defaultText; return defaultText; }; }moduleexports = upper: UpperDirective;
demo
options
- router - 处理 graphql 请求的路由,默认为 "/graphql"
- app - 是否加载到 app 上,默认为 true
- agent - 是否加载到 agent 上,默认为 false
- graphiql - 是否加载开发者工具 playground,默认为 true
- uploads - 是否开启文件上传功能,默认为 true
其它 options 参 见apollo-server
egg-apollo-server 和 egg-graphql 的区别
- 不支持 onPreGraphQL,onPreGraphiQL
- 不支持 directiveResolvers,用 schemaDirective 替代
- 支持文件上传.
- 更漂亮的调试界面.
- 支持自定义错误类型
- 支持 dataSources
- 支持缓存(redis 等)
- 支持 Subscriptions
- 支持 mock
- 支持默认的 Query
设置默认 Query 的好处?
未设置默认 Query 之前,假如有 user,tag 两个表,需要建四个文件夹,这样导致 mutation,query 包含了所有的一级查询,增加,更新,删除 而 user 相关定义又在 user/graphql 下
app
└── graphql
├── mutation
│ └── schema.graphql
├── query
│ └── schema.graphql
├── tag
│ ├── resolver.js
│ └── schema.graphql
└── user
├── resolver.js
└── schema.graphql
有了默认 Query 后,只需要建两个文件夹
app
└── graphql
├── tag
│ ├── resolver.js
│ └── schema.graphql
└── user
├── resolver.js
└── schema.graphql
只需要在各自 schema.graphql 定义 例如 egg 中使用 graphql
#app/graphql/user/schema.graphqlextend type Query { user(id: ID!): User}extend type Mutation { addUser(input: AddUser): User}input AddUser { name: String age: Int}type User { id: ID! name: String age: Int}
TODO
- 支持自定义 schema,可自定义 graphql 相关文件结构
- 支持 typeDefs 里引用 model 数据