diff --git a/angel_graphql/example/main.dart b/angel_graphql/example/main.dart index d9ed9dec..06310af2 100644 --- a/angel_graphql/example/main.dart +++ b/angel_graphql/example/main.dart @@ -24,11 +24,16 @@ main() async { description: 'A simple API that manages your to-do list.', fields: [ field( - 'todo', + 'todos', type: listType(convertDartType(Todo).nonNullable()), - resolve: resolveFromService(todoService), + resolve: resolveViaServiceIndex(todoService), + ), + field( + 'todo', + type: convertDartType(Todo), + resolve: resolveViaServiceRead(todoService), arguments: [ - new GraphQLFieldArgument('id', graphQLId), + new GraphQLFieldArgument('id', graphQLId.nonNullable()), ], ), ], @@ -39,10 +44,14 @@ main() async { app.all('/graphql', graphQLHttp(new GraphQL(schema))); app.get('/graphiql', graphiql()); - await todoService.create({'text': 'Clean your room!', 'completed': true}); - await todoService.create({'text': 'Take out the trash', 'completed': false}); + await todoService + .create({'text': 'Clean your room!', 'completion_status': 'COMPLETE'}); await todoService.create( - {'text': 'Become a billionaire at the age of 5', 'completed': false}); + {'text': 'Take out the trash', 'completion_status': 'INCOMPLETE'}); + await todoService.create({ + 'text': 'Become a billionaire at the age of 5', + 'completion_status': 'INCOMPLETE' + }); var server = await http.startServer('127.0.0.1', 3000); var uri = @@ -67,5 +76,4 @@ class Todo extends Model { } @GraphQLDocumentation(description: 'The completion status of a to-do item.') -enum CompletionStatus { - COMPLETE, INCOMPLETE } +enum CompletionStatus { COMPLETE, INCOMPLETE } diff --git a/angel_graphql/lib/src/graphql_http.dart b/angel_graphql/lib/src/graphql_http.dart index 2da0c944..c936be75 100644 --- a/angel_graphql/lib/src/graphql_http.dart +++ b/angel_graphql/lib/src/graphql_http.dart @@ -55,7 +55,7 @@ RequestHandler graphQLHttp(GraphQL graphQl) { errors .addAll(e.errors.map((ee) => new GraphQLExceptionError(ee)).toList()); - throw new GraphQLException(errors); + return new GraphQLException(errors).toJson(); } on SyntaxError catch (e) { return new GraphQLException.fromSourceSpan(e.message, e.span); } on GraphQLException catch (e) { diff --git a/angel_graphql/lib/src/resolvers.dart b/angel_graphql/lib/src/resolvers.dart index 94f55c4a..df19a948 100644 --- a/angel_graphql/lib/src/resolvers.dart +++ b/angel_graphql/lib/src/resolvers.dart @@ -1,25 +1,30 @@ import 'package:angel_framework/angel_framework.dart'; import 'package:graphql_schema/graphql_schema.dart'; -/// A GraphQL resolver that indexes an Angel service. -/// -/// If [enableRead] is `true`, and the [idField] is present in the input, -/// a `read` will be performed, rather than an `index`. +/// A GraphQL resolver that `index`es an Angel service. /// /// The arguments passed to the resolver will be forwarded to service, and the /// service will receive [Providers.graphql]. -GraphQLFieldResolver resolveFromService( - Service service, - {String idField: 'id', - bool enableRead: true}) { +GraphQLFieldResolver + resolveViaServiceIndex(Service service, + {String idField: 'id'}) { return (_, arguments) async { var params = {'query': arguments, 'provider': Providers.graphql}; - if (enableRead && arguments.containsKey(idField)) { - var id = arguments.remove(idField); - return await service.read(id, params) as Value; - } - return await service.index(params) as Value; }; } + +/// A GraphQL resolver that `read`s a single value from an Angel service. +/// +/// The arguments passed to the resolver will be forwarded to service, and the +/// service will receive [Providers.graphql]. +GraphQLFieldResolver + resolveViaServiceRead(Service service, + {String idField: 'id'}) { + return (_, arguments) async { + var params = {'query': arguments, 'provider': Providers.graphql}; + var id = arguments.remove(idField); + return await service.read(id, params) as Value; + }; +} diff --git a/graphql_server/lib/graphql_server.dart b/graphql_server/lib/graphql_server.dart index 820c532a..01cab90a 100644 --- a/graphql_server/lib/graphql_server.dart +++ b/graphql_server/lib/graphql_server.dart @@ -238,9 +238,8 @@ class GraphQL { if (defaultValue != null || argumentDefinition.defaultsToNull) { coercedValues[argumentName] = defaultValue; } else if (argumentType is GraphQLNonNullableType) { - throw new GraphQLException.fromSourceSpan( - 'Missing value for argument "$argumentName".', - value.valueOrVariable.span); + throw new GraphQLException.fromMessage( + 'Missing value for argument "$argumentName".'); } else { continue; } diff --git a/graphql_server/lib/introspection.dart b/graphql_server/lib/introspection.dart index 1fe80751..a4a6ede3 100644 --- a/graphql_server/lib/introspection.dart +++ b/graphql_server/lib/introspection.dart @@ -418,6 +418,10 @@ List _fetchAllTypesFromObject(GraphQLObjectType objectType) { } else { types.addAll(_fetchAllTypesFromType(field.type)); } + + for (var argument in field.arguments ?? []) { + types.addAll(_fetchAllTypesFromType(argument.type)); + } } return types;