Skip to content

Commit

Permalink
refactor: refactor ctx.graphql query and mutate
Browse files Browse the repository at this point in the history
  • Loading branch information
supperchong committed Aug 23, 2019
1 parent 7a3679d commit 78101c6
Show file tree
Hide file tree
Showing 10 changed files with 186 additions and 47 deletions.
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/test
6 changes: 5 additions & 1 deletion app/middleware/graphql.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

const { ApolloServer } = require('apollo-server-koa');
const compose = require('koa-compose');
const GraphqlServer = Symbol.for('Egg#graphqlServer');
/**
* @param {Object} options The `options` of apollo-server.
* @return {Promise} The compose of middleware in apollo-server-koa.
Expand Down Expand Up @@ -41,7 +42,10 @@ module.exports = (_, app) => {
server.installSubscriptionHandlers(httpServer);
});
}

/**
* 将server实例挂载在app上,这样可以在service里访问了
*/
app[GraphqlServer] = server;
const middlewares = [];
const proxyApp = {
use: m => {
Expand Down
78 changes: 32 additions & 46 deletions app/service/graphql.js
Original file line number Diff line number Diff line change
@@ -1,55 +1,41 @@
'use strict';

/**
* copy from https://github.com/eggjs/egg-graphql/blob/master/app/service/graphql.js
* 主要为了兼容egg-graphql
*/
const { execute, formatError } = require('graphql');
const gql = require('graphql-tag');
const { createTestClient } = require('apollo-server-testing');
const GraphqlServer = Symbol.for('Egg#graphqlServer');
async function operate({ request, method }) {
let result = {};
const graphqlServer = this.app[GraphqlServer];
const operation = createTestClient(graphqlServer)[method];
try {
if (typeof request === 'string') {
request = JSON.parse(request);
}
result = await operation(request);
} catch (e) {
this.logger.error(e);

result = {
data: {},
errors: [ e ],
};
}

return result;
}
module.exports = app => {
class GraphqlService extends app.Service {

async query(requestString) {
let result = {};
const ctx = this.ctx;

try {
const params = JSON.parse(requestString);
const { query, variables, operationName } = params;
// GraphQL source.
// https://github.com/apollostack/graphql-tag#caching-parse-results
const documentAST = gql`${query}`;
const context = ctx;
const schema = this.app.schema;

// http://graphql.org/graphql-js/execution/#execute
result = await execute(
schema,
documentAST,
null,
context,
variables,
operationName
);

// Format any encountered errors.
/* istanbul ignore if */
if (result && result.errors) {
result.errors = result.errors.map(formatError);
}
} catch (e) {
this.logger.error(e);

result = {
data: {},
errors: [ e ],
};
}

return result;
async query(request) {
return operate.call(this, {
request,
method: 'query',
});
}
async mutate(request) {
return operate.call(this, {
request,
method: 'mutate',
});
}
}

return GraphqlService;
};
6 changes: 6 additions & 0 deletions examples/simple/app/graphql/user/resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,11 @@ module.exports = {
users.push(newUser);
return newUser;
},
updateUser: (root, params) => {
const { input } = params;
const user = users.find(id => id === input.id);
Object.assign(user, input);
return true;
},
},
};
6 changes: 6 additions & 0 deletions examples/simple/app/graphql/user/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,14 @@ extend type Query {
}
extend type Mutation {
addUser(input: AddUser): User
updateUser(input: UpdateUser): Boolean
}
input AddUser {
name: String
age: Int
}
input UpdateUser {
id: ID!
name: String
age: Int
}
File renamed without changes
18 changes: 18 additions & 0 deletions test/fixtures/apps/app-test/app/graphql/user/resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,22 @@ module.exports = {
return users.find(user => user.id == id);
},
},
Mutation: {
addUser: (root, params) => {
const id = users.length + 1;
const newUser = {
id,
...params.input,
};
users.push(newUser);
return newUser;
},
updateUser: (root, params) => {
const { input } = params;
// eslint-disable-next-line eqeqeq
const user = users.find(({ id }) => id == input.id);
Object.assign(user, input);
return true;
},
},
};
13 changes: 13 additions & 0 deletions test/fixtures/apps/app-test/app/graphql/user/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,16 @@ extend type Query {
users: [User]
user(id: ID!): User
}
extend type Mutation {
addUser(input: AddUser): User
updateUser(input: UpdateUser): Boolean
}
input AddUser {
name: String
age: Int
}
input UpdateUser {
id: ID!
name: String
age: Int
}
104 changes: 104 additions & 0 deletions test/app.test.js → test/test/app.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -357,3 +357,107 @@ describe('test subscription', () => {
});

});

describe('test graphql query without http', () => {
let app;
before(() => {
app = mock.app({
baseDir: 'apps/app-test',
});
return app.ready();
});

after(() => app.close());
afterEach(mock.restore);

it('request get should return users', async () => {
const ctx = await app.createAnonymousContext();
const { data } = await ctx
.graphql
.query({
query: gql`
query getUsers{
users{
id
name
age
}
}
`,
});
assert.deepEqual(data, {
users,
});
});

it('should return user where id=1', async () => {
const ctx = await app.createAnonymousContext();
const { data } = await ctx
.graphql
.query({
query: gql`
query getUsers($id:ID!){
user(id:$id){
id
name
}
}
`,
variables: {
id: 1,
},
});
const user = {
id: 1,
name: '小王',
};
assert.deepEqual(data, {
user,
});
});

it('should update user where id=1', async () => {
const ctx = await app.createAnonymousContext();
const { data } = await ctx
.graphql
.mutate({
mutation: gql`
mutation updateUser($input:UpdateUser){
updateUser(input:$input)
}
`,
variables: {
input: {
id: 1,
name: 'xiaowang',
},
},
});
const { data: { user } } = await ctx
.graphql
.query({
query: gql`
query getUsers($id:ID!){
user(id:$id){
id
name
}
}
`,
variables: {
id: 1,
},
});
const _user = {
id: 1,
name: 'xiaowang',
};
assert.deepEqual(data, {
updateUser: true,
});
assert.deepEqual(_user,
user
);
});

});
1 change: 1 addition & 0 deletions test/test/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 78101c6

Please sign in to comment.