Skip to content

Commit

Permalink
feat:pass other apollo server options. (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
whlsxl authored and JasinYip committed Oct 31, 2019
1 parent d1cdb29 commit bf6485a
Show file tree
Hide file tree
Showing 23 changed files with 361 additions and 8 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,24 @@ exports.graphql = {
onPreGraphQL: function* (ctx) {},
// 开发工具 graphiQL 路由前的拦截器,建议用于做权限操作(如只提供开发者使用)
onPreGraphiQL: function* (ctx) {},
// apollo server的透传参数,参考[文档](https://www.apollographql.com/docs/apollo-server/api/apollo-server/#parameters)
apolloServerOptions: {
rootValue,
formatError,
formatResponse,
mocks,
schemaDirectives,
introspection,
playground,
debug,
validationRules,
tracing,
cacheControl,
subscriptions,
engine,
persistedQueries,
cors,
}
};

// 添加中间件拦截请求
Expand Down
26 changes: 18 additions & 8 deletions app/middleware/graphql.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,31 @@ module.exports = (_, app) => {
return async (ctx, next) => {
/* istanbul ignore else */
if (ctx.path === graphQLRouter) {
const {
onPreGraphiQL,
onPreGraphQL,
apolloServerOptions,
} = options;
if (ctx.request.accepts([ 'json', 'html' ]) === 'html' && graphiql) {
if (options.onPreGraphiQL) {
await options.onPreGraphiQL(ctx);
if (onPreGraphiQL) {
await onPreGraphiQL(ctx);
}
return graphiqlKoa({
endpointURL: graphQLRouter,
})(ctx);
}
if (options.onPreGraphQL) {
await options.onPreGraphQL(ctx);
if (onPreGraphQL) {
await onPreGraphQL(ctx);
}
return graphqlKoa({
schema: app.schema,
context: ctx,
})(ctx);
const serverOptions = Object.assign(
{},
apolloServerOptions,
{
schema: app.schema,
context: ctx,
}
);
return graphqlKoa(serverOptions)(ctx);
}
await next();
};
Expand Down
35 changes: 35 additions & 0 deletions test/app/graphql-options/graphql.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use strict';

const assert = require('assert');
const mm = require('egg-mock');

describe('test/app/graphql-options.test.js', () => {
let app;

before(() => {
app = mm.app({
baseDir: 'apps/graphql-options-app',
});
return app.ready();
});

after(mm.restore);

it('should return custom error, use formatError', async () => {
const resp = await app.httpRequest()
.get('/graphql?query=query+getUser($id:Int){user(id:$id){name}}&variables={"id":1}')
.expect(200);
assert.equal(resp.body.errors[0].code, 100001);
});

it('should return frameworks, user formatResponse', async () => {
const resp = await app.httpRequest()
.get('/graphql?query=query+getFramework($id:Int){framework(id:$id){name}}&variables={"id":1}')
.expect(200);
assert.deepEqual(resp.body.data, {
frameworks: {
name: 'framework1',
},
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict';

module.exports = {
changedName: 'frameworks',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict';

module.exports = {
upper(next) {
return next().then(str => {
if (typeof str === 'string') {
return str.toUpperCase();
}
return str;
});
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
directive @upper on FIELD_DEFINITION
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use strict';

const DataLoader = require('dataloader');

class FrameworkConnector {
constructor(ctx) {
this.ctx = ctx;
this.loader = new DataLoader(this.fetch.bind(this));
}

fetch(ids) {
return Promise.resolve(ids.map(id => ({
id,
name: `framework${id}`,
projects: [],
})));
}

fetchByIds(ids) {
return this.loader.loadMany(ids);
}

fetchById(id) {
return this.loader.load(id);
}

}

module.exports = FrameworkConnector;

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use strict';

module.exports = {
Query: {
framework(root, { id }, ctx) {
return ctx.connector.framework.fetchById(id);
},
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

type Framework {
id: Int!
name: String!
projects: [Project]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict';

module.exports = app => {
return {
Query: {
projects() {
console.log(app);
return [];
},
},
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

type Project {
name: String!
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
directive @lowerCase on FIELD_DEFINITION
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use strict';

const { SchemaDirectiveVisitor } = require('graphql-tools');
const { defaultFieldResolver } = require('graphql');

class LowerCaseDirective extends SchemaDirectiveVisitor {
visitFieldDefinition(field) {
const { resolve = defaultFieldResolver } = field;
field.resolve = async function(...args) {
let result = await resolve.apply(this, args);
if (typeof result === 'string') {
result = result.toLowerCase();
}
return result;
};
}
}

module.exports = {
lowerCase: LowerCaseDirective,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use strict';

const DataLoader = require('dataloader');

class UserConnector {
constructor(ctx) {
this.ctx = ctx;
this.loader = new DataLoader(this.fetch.bind(this));
}

fetch(ids) {
// this.ctx.model.user.find(ids);
return Promise.resolve(ids.map(id => ({
id,
name: `name${id}`,
upperName: `name${id}`,
lowerName: `name${id}`,
password: `password${id}`,
projects: [],
})));
}

fetchByIds(ids) {
return this.loader.loadMany(ids);
}

// eslint-disable-next-line no-unused-vars
fetchById(id) {
const err = new Error();
err.code = 100001;
throw err;
// return this.loader.load(id);
}

}

module.exports = UserConnector;

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use strict';

module.exports = {
Query: {
user(root, { id }, ctx) {
return ctx.connector.user.fetchById(id);
},
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
type Query {
user(id: Int): User
projects: [Project!]
framework(id: Int): Framework
}

type User {
id: String!
password: String!
name: String!
upperName: String @upper
lowerName: String @lowerCase
projects: [Project!]
}
14 changes: 14 additions & 0 deletions test/fixtures/apps/graphql-options-app/app/model/framework.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use strict';

module.exports = () => {
class Framework {
find(ids) {
return ids.map(id => ({
id,
name: `name${id}`,
}));
}
}

return Framework;
};
15 changes: 15 additions & 0 deletions test/fixtures/apps/graphql-options-app/app/model/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';

module.exports = () => {
class User {
find(ids) {
return ids.map(id => ({
id,
name: `name${id}`,
password: `password${id}`,
}));
}
}

return User;
};
25 changes: 25 additions & 0 deletions test/fixtures/apps/graphql-options-app/app/router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use strict';

module.exports = function(app) {
app.get('/user', async ctx => {
const req = {
query: `{
user(id: 2) {
name
}
}`,
};
ctx.body = await ctx.graphql.query(JSON.stringify(req));
});

app.get('/framework', async ctx => {
const req = {
query: `{
framework(id: 2) {
name
}
}`,
};
ctx.body = await ctx.graphql.query(JSON.stringify(req));
});
};
13 changes: 13 additions & 0 deletions test/fixtures/apps/graphql-options-app/app/service/framework.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
'use strict';

module.exports = app => {
class FrameworkService extends app.Service {
async getFrameworkList() {
return [
{ id: 1, name: 'framework1' },
{ id: 2, name: 'framework2' },
];
}
}
return FrameworkService;
};
13 changes: 13 additions & 0 deletions test/fixtures/apps/graphql-options-app/app/service/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
'use strict';

module.exports = app => {
class UserService extends app.Service {
async getUserList() {
return [
{ id: '1', name: 'user1' },
{ id: '2', name: 'user2' },
];
}
}
return UserService;
};
Loading

0 comments on commit bf6485a

Please sign in to comment.