Add ability to provide default field resolvers (#482)

This commit is contained in:
Mikhail Novikov 2017-08-02 13:20:10 +03:00 committed by Martijn Walraven
parent 7b8409a3fa
commit c51fc65da8
15 changed files with 72 additions and 14 deletions

View file

@ -2,6 +2,9 @@
### VNEXT
### v1.1.0
* Added ability to provide custom default field resolvers [#482](https://github.com/apollographql/apollo-server/pull/482)
* Add support for GraphiQL editor themes in [#484](https://github.com/apollographql/apollo-server/pull/484) as requested in [#444](https://github.com/apollographql/apollo-server/issues/444)
* Add support for full websocket using GraphiQL [#491](https://github.com/apollographql/graphql-server/pull/491)

View file

@ -25,7 +25,6 @@
"homepage": "https://github.com/apollographql/apollo-server#readme",
"devDependencies": {
"@types/fibers": "0.0.29",
"@types/graphql": "^0.9.0",
"fibers": "1.0.15",
"meteor-promise": "^0.8.2"
},
@ -33,7 +32,7 @@
"graphql": "^0.9.0 || ^0.10.1"
},
"optionalDependencies": {
"@types/graphql": "^0.9.0"
"@types/graphql": "^0.10.1"
},
"typings": "dist/index.d.ts",
"typescript": {

View file

@ -1,4 +1,4 @@
import { GraphQLSchema, ValidationContext } from 'graphql';
import { GraphQLSchema, ValidationContext, GraphQLFieldResolver } from 'graphql';
import { LogFunction } from './runQuery';
/*
@ -12,6 +12,7 @@ import { LogFunction } from './runQuery';
* - (optional) formatParams: a function applied to the parameters of every invocation of runQuery
* - (optional) validationRules: extra validation rules applied to requests
* - (optional) formatResponse: a function applied to each graphQL execution result
* - (optional) fieldResolver: a custom default field resolver
* - (optional) debug: a boolean that will print additional debug logging if execution errors occur
*
*/
@ -24,6 +25,7 @@ export interface GraphQLServerOptions {
formatParams?: Function;
validationRules?: Array<(context: ValidationContext) => any>;
formatResponse?: Function;
fieldResolver?: GraphQLFieldResolver<any, any>;
debug?: boolean;
}

View file

@ -116,6 +116,7 @@ export async function runHttpQuery(handlerArguments: Array<any>, request: HttpQu
validationRules: optionsObject.validationRules,
formatError: formatErrorFn,
formatResponse: optionsObject.formatResponse,
fieldResolver: optionsObject.fieldResolver,
debug: optionsObject.debug,
};

View file

@ -33,6 +33,21 @@ const queryType = new GraphQLObjectType({
return 'it works';
},
},
testObject: {
type: new GraphQLObjectType({
name: 'TestObject',
fields: {
testString: {
type: GraphQLString,
},
},
}),
resolve() {
return {
testString: 'a very test string',
};
},
},
testRootValue: {
type: GraphQLString,
resolve(root) {
@ -265,4 +280,39 @@ describe('runQuery', () => {
expect(logs[10]).to.deep.equals({action: LogAction.request, step: LogStep.end});
});
});
it('uses custom field resolver', async () => {
const query = `
query Q1 {
testObject {
testString
}
}
`;
const result1 = await runQuery({
schema,
query: query,
operationName: 'Q1',
});
expect(result1.data).to.deep.equal({
testObject: {
testString: 'a very test string',
},
});
const result2 = await runQuery({
schema,
query: query,
operationName: 'Q1',
fieldResolver: () => 'a very testful field resolver string',
});
expect(result2.data).to.deep.equal({
testObject: {
testString: 'a very testful field resolver string',
},
});
});
});

View file

@ -1,5 +1,6 @@
import {
GraphQLSchema,
GraphQLFieldResolver,
ExecutionResult,
DocumentNode,
parse,
@ -44,6 +45,7 @@ export interface QueryOptions {
operationName?: string;
logFunction?: LogFunction;
validationRules?: Array<(context: ValidationContext) => any>;
fieldResolver?: GraphQLFieldResolver<any, any>;
// WARNING: these extra validation rules are only applied to queries
// submitted as string, not those submitted as Document!
@ -128,6 +130,7 @@ function doRunQuery(options: QueryOptions): Promise<ExecutionResult> {
options.context,
options.variables,
options.operationName,
options.fieldResolver,
).then(gqlResponse => {
logFunction({action: LogAction.execute, step: LogStep.end});
logFunction({action: LogAction.request, step: LogStep.end});

View file

@ -46,7 +46,7 @@
},
"optionalDependencies": {
"@types/express": "^4.0.35",
"@types/graphql": "^0.9.1"
"@types/graphql": "^0.10.1"
},
"typings": "dist/index.d.ts",
"typescript": {

View file

@ -31,7 +31,7 @@
},
"devDependencies": {
"@types/boom": "4.3.2",
"@types/graphql": "^0.9.1",
"@types/graphql": "^0.10.1",
"@types/hapi": "^16.1.4",
"apollo-server-integration-testsuite": "^1.0.5",
"hapi": "^16.4.3"
@ -40,7 +40,7 @@
"graphql": "^0.9.0 || ^0.10.1"
},
"optionalDependencies": {
"@types/graphql": "^0.9.1",
"@types/graphql": "^0.10.1",
"@types/hapi": "^16.1.2"
},
"typings": "dist/index.d.ts",

View file

@ -27,13 +27,13 @@
"supertest-as-promised": "^4.0.0"
},
"devDependencies": {
"@types/graphql": "^0.9.0"
"@types/graphql": "^0.10.1"
},
"peerDependencies": {
"graphql": "^0.9.0 || ^0.10.1"
},
"optionalDependencies": {
"@types/graphql": "^0.9.0"
"@types/graphql": "^0.10.1"
},
"typings": "dist/index.d.ts",
"typescript": {

View file

@ -41,7 +41,7 @@
"graphql": "^0.9.0 || ^0.10.1"
},
"optionalDependencies": {
"@types/graphql": "^0.9.1",
"@types/graphql": "^0.10.1",
"@types/koa": "^2.0.39"
},
"typings": "dist/index.d.ts",

View file

@ -30,7 +30,7 @@
},
"devDependencies": {
"@types/aws-lambda": "0.0.10",
"@types/graphql": "^0.9.1",
"@types/graphql": "^0.10.1",
"apollo-server-integration-testsuite": "^1.0.5"
},
"peerDependencies": {

View file

@ -38,7 +38,7 @@
"micro": "^7.3.3"
},
"optionalDependencies": {
"@types/graphql": "^0.9.1",
"@types/graphql": "^0.10.1",
"@types/micro": "^7.3.0"
},
"typings": "dist/index.d.ts",

View file

@ -27,7 +27,7 @@
"graphql": "^0.9.0 || ^0.10.1"
},
"optionalDependencies": {
"@types/graphql": "^0.9.1"
"@types/graphql": "^0.10.1"
},
"typings": "dist/index.d.ts",
"typescript": {

View file

@ -37,7 +37,7 @@
"graphql": "^0.9.0 || ^0.10.1"
},
"optionalDependencies": {
"@types/graphql": "^0.9.1",
"@types/graphql": "^0.10.1",
"@types/restify": "^4.3.2"
},
"typings": "dist/index.d.ts",

View file

@ -9,7 +9,7 @@
"allowSyntheticDefaultImports": false,
"pretty": true,
"removeComments": true,
"lib": ["es6"],
"lib": ["es6", "esnext.asynciterable"],
"types": [
"@types/node"
]