Example star wars done
This commit is contained in:
parent
8f98e801ab
commit
91701b56ad
4 changed files with 45 additions and 10 deletions
|
@ -8,6 +8,11 @@ Map<String, dynamic> _fetchRequestInfo(Map<String, dynamic> arguments) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _getQuery(Map<String, dynamic> arguments) {
|
||||||
|
var f = Map<String, dynamic>.from(arguments)..remove('id')..remove('data');
|
||||||
|
return f.isEmpty ? null : {};
|
||||||
|
}
|
||||||
|
|
||||||
/// A GraphQL resolver that `index`es an Angel service.
|
/// A GraphQL resolver that `index`es an Angel service.
|
||||||
///
|
///
|
||||||
/// The arguments passed to the resolver will be forwarded to the service, and the
|
/// The arguments passed to the resolver will be forwarded to the service, and the
|
||||||
|
@ -16,7 +21,7 @@ GraphQLFieldResolver<List<Value>, Serialized>
|
||||||
resolveViaServiceIndex<Value, Serialized>(Service<dynamic, Value> service) {
|
resolveViaServiceIndex<Value, Serialized>(Service<dynamic, Value> service) {
|
||||||
return (_, arguments) async {
|
return (_, arguments) async {
|
||||||
var _requestInfo = _fetchRequestInfo(arguments);
|
var _requestInfo = _fetchRequestInfo(arguments);
|
||||||
var params = {'query': arguments, 'provider': Providers.graphQL}
|
var params = {'query': _getQuery(arguments), 'provider': Providers.graphQL}
|
||||||
..addAll(_requestInfo);
|
..addAll(_requestInfo);
|
||||||
|
|
||||||
return await service.index(params);
|
return await service.index(params);
|
||||||
|
@ -32,7 +37,7 @@ GraphQLFieldResolver<Value, Serialized>
|
||||||
Service<dynamic, Value> service) {
|
Service<dynamic, Value> service) {
|
||||||
return (_, arguments) async {
|
return (_, arguments) async {
|
||||||
var _requestInfo = _fetchRequestInfo(arguments);
|
var _requestInfo = _fetchRequestInfo(arguments);
|
||||||
var params = {'query': arguments, 'provider': Providers.graphQL}
|
var params = {'query': _getQuery(arguments), 'provider': Providers.graphQL}
|
||||||
..addAll(_requestInfo);
|
..addAll(_requestInfo);
|
||||||
return await service.findOne(params);
|
return await service.findOne(params);
|
||||||
};
|
};
|
||||||
|
@ -50,7 +55,7 @@ GraphQLFieldResolver<Value, Serialized>
|
||||||
{String idField: 'id'}) {
|
{String idField: 'id'}) {
|
||||||
return (_, arguments) async {
|
return (_, arguments) async {
|
||||||
var _requestInfo = _fetchRequestInfo(arguments);
|
var _requestInfo = _fetchRequestInfo(arguments);
|
||||||
var params = {'query': arguments, 'provider': Providers.graphQL}
|
var params = {'query': _getQuery(arguments), 'provider': Providers.graphQL}
|
||||||
..addAll(_requestInfo);
|
..addAll(_requestInfo);
|
||||||
var id = arguments.remove(idField);
|
var id = arguments.remove(idField);
|
||||||
return await service.read(id, params);
|
return await service.read(id, params);
|
||||||
|
@ -70,8 +75,9 @@ GraphQLFieldResolver<Value, Serialized>
|
||||||
{String idField: 'id'}) {
|
{String idField: 'id'}) {
|
||||||
return (_, arguments) async {
|
return (_, arguments) async {
|
||||||
var _requestInfo = _fetchRequestInfo(arguments);
|
var _requestInfo = _fetchRequestInfo(arguments);
|
||||||
var params = {'query': arguments, 'provider': Providers.graphQL}
|
var params = {'query': _getQuery(arguments), 'provider': Providers.graphQL}
|
||||||
..addAll(_requestInfo);
|
..addAll(_requestInfo);
|
||||||
|
print(params);
|
||||||
var id = arguments.remove(idField);
|
var id = arguments.remove(idField);
|
||||||
return await service.modify(id, arguments['data'] as Value, params);
|
return await service.modify(id, arguments['data'] as Value, params);
|
||||||
};
|
};
|
||||||
|
@ -93,7 +99,7 @@ GraphQLFieldResolver<Value, Serialized>
|
||||||
{String idField: 'id'}) {
|
{String idField: 'id'}) {
|
||||||
return (_, arguments) async {
|
return (_, arguments) async {
|
||||||
var _requestInfo = _fetchRequestInfo(arguments);
|
var _requestInfo = _fetchRequestInfo(arguments);
|
||||||
var params = {'query': arguments, 'provider': Providers.graphQL}
|
var params = {'query': _getQuery(arguments), 'provider': Providers.graphQL}
|
||||||
..addAll(_requestInfo);
|
..addAll(_requestInfo);
|
||||||
var id = arguments.remove(idField);
|
var id = arguments.remove(idField);
|
||||||
return await service.update(id, arguments['data'] as Value, params);
|
return await service.update(id, arguments['data'] as Value, params);
|
||||||
|
@ -112,7 +118,7 @@ GraphQLFieldResolver<Value, Serialized>
|
||||||
{String idField: 'id'}) {
|
{String idField: 'id'}) {
|
||||||
return (_, arguments) async {
|
return (_, arguments) async {
|
||||||
var _requestInfo = _fetchRequestInfo(arguments);
|
var _requestInfo = _fetchRequestInfo(arguments);
|
||||||
var params = {'query': arguments, 'provider': Providers.graphQL}
|
var params = {'query': _getQuery(arguments), 'provider': Providers.graphQL}
|
||||||
..addAll(_requestInfo);
|
..addAll(_requestInfo);
|
||||||
var id = arguments.remove(idField);
|
var id = arguments.remove(idField);
|
||||||
return await service.remove(id, params);
|
return await service.remove(id, params);
|
||||||
|
|
|
@ -4,6 +4,7 @@ import 'package:angel_framework/angel_framework.dart';
|
||||||
import 'package:angel_graphql/angel_graphql.dart';
|
import 'package:angel_graphql/angel_graphql.dart';
|
||||||
import 'package:graphql_schema/graphql_schema.dart';
|
import 'package:graphql_schema/graphql_schema.dart';
|
||||||
import 'package:graphql_server/graphql_server.dart';
|
import 'package:graphql_server/graphql_server.dart';
|
||||||
|
import 'package:graphql_server/mirrors.dart';
|
||||||
import 'src/models/models.dart';
|
import 'src/models/models.dart';
|
||||||
|
|
||||||
Future configureServer(Angel app) async {
|
Future configureServer(Angel app) async {
|
||||||
|
@ -90,7 +91,11 @@ Future configureServer(Angel app) async {
|
||||||
|
|
||||||
// Next, create a GraphQL object, which will be passed to `graphQLHttp`, and
|
// Next, create a GraphQL object, which will be passed to `graphQLHttp`, and
|
||||||
// used to mount a spec-compliant GraphQL endpoint on the server.
|
// used to mount a spec-compliant GraphQL endpoint on the server.
|
||||||
var graphQL = GraphQL(schema);
|
//
|
||||||
|
// The `mirrorsFieldResolver` is unnecessary in this case, because we are using
|
||||||
|
// `Map`s only, but if our services returned concrete Dart objects, we'd need
|
||||||
|
// this to allow GraphQL to read field values.
|
||||||
|
var graphQL = GraphQL(schema, defaultFieldResolver: mirrorsFieldResolver);
|
||||||
|
|
||||||
// Mount the GraphQL endpoint.
|
// Mount the GraphQL endpoint.
|
||||||
app.all('/graphql', graphQLHttp(graphQL));
|
app.all('/graphql', graphQLHttp(graphQL));
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:graphql_parser/graphql_parser.dart';
|
import 'package:graphql_parser/graphql_parser.dart';
|
||||||
import 'package:graphql_schema/graphql_schema.dart';
|
import 'package:graphql_schema/graphql_schema.dart';
|
||||||
|
|
||||||
import 'introspection.dart';
|
import 'introspection.dart';
|
||||||
|
|
||||||
|
/// Transforms any [Map] into `Map<String, dynamic>`.
|
||||||
Map<String, dynamic> foldToStringDynamic(Map map) {
|
Map<String, dynamic> foldToStringDynamic(Map map) {
|
||||||
return map == null
|
return map == null
|
||||||
? null
|
? null
|
||||||
|
@ -12,12 +11,21 @@ Map<String, dynamic> foldToStringDynamic(Map map) {
|
||||||
<String, dynamic>{}, (out, k) => out..[k.toString()] = map[k]);
|
<String, dynamic>{}, (out, k) => out..[k.toString()] = map[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A Dart implementation of a GraphQL server.
|
||||||
class GraphQL {
|
class GraphQL {
|
||||||
|
/// Any custom types to include in introspection information.
|
||||||
final List<GraphQLType> customTypes = [];
|
final List<GraphQLType> customTypes = [];
|
||||||
|
|
||||||
|
/// An optional callback that can be used to resolve fields from objects that are not [Map]s,
|
||||||
|
/// when the related field has no resolver.
|
||||||
|
final FutureOr<T> Function<T>(T, String, Map<String, dynamic>)
|
||||||
|
defaultFieldResolver;
|
||||||
|
|
||||||
GraphQLSchema _schema;
|
GraphQLSchema _schema;
|
||||||
|
|
||||||
GraphQL(GraphQLSchema schema,
|
GraphQL(GraphQLSchema schema,
|
||||||
{bool introspect: true,
|
{bool introspect: true,
|
||||||
|
this.defaultFieldResolver,
|
||||||
List<GraphQLType> customTypes = const <GraphQLType>[]})
|
List<GraphQLType> customTypes = const <GraphQLType>[]})
|
||||||
: _schema = schema {
|
: _schema = schema {
|
||||||
if (customTypes?.isNotEmpty == true) {
|
if (customTypes?.isNotEmpty == true) {
|
||||||
|
@ -473,6 +481,14 @@ class GraphQL {
|
||||||
var field = objectType.fields.firstWhere((f) => f.name == fieldName);
|
var field = objectType.fields.firstWhere((f) => f.name == fieldName);
|
||||||
|
|
||||||
if (field.resolve == null) {
|
if (field.resolve == null) {
|
||||||
|
if (defaultFieldResolver != null)
|
||||||
|
return await defaultFieldResolver(
|
||||||
|
objectValue, fieldName, argumentValues);
|
||||||
|
|
||||||
|
if (objectValue is Map) {
|
||||||
|
return objectValue[fieldName] as T;
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return await field.resolve(objectValue, argumentValues) as T;
|
return await field.resolve(objectValue, argumentValues) as T;
|
||||||
|
@ -571,7 +587,6 @@ class GraphQL {
|
||||||
|
|
||||||
var errors = <GraphQLExceptionError>[];
|
var errors = <GraphQLExceptionError>[];
|
||||||
|
|
||||||
print(possibleTypes);
|
|
||||||
for (var t in possibleTypes) {
|
for (var t in possibleTypes) {
|
||||||
try {
|
try {
|
||||||
var validation =
|
var validation =
|
||||||
|
|
|
@ -9,6 +9,15 @@ import 'package:angel_serialize/angel_serialize.dart';
|
||||||
import 'package:graphql_schema/graphql_schema.dart';
|
import 'package:graphql_schema/graphql_schema.dart';
|
||||||
import 'package:recase/recase.dart';
|
import 'package:recase/recase.dart';
|
||||||
|
|
||||||
|
/// Uses `dart:mirrors` to read field names from items. If they are Maps, performs a regular lookup.
|
||||||
|
T mirrorsFieldResolver<T>(objectValue, String fieldName,
|
||||||
|
[Map<String, dynamic> objectValues]) {
|
||||||
|
if (objectValue is Map)
|
||||||
|
return objectValue[fieldName] as T;
|
||||||
|
else
|
||||||
|
return reflect(objectValue).getField(Symbol(fieldName)).reflectee as T;
|
||||||
|
}
|
||||||
|
|
||||||
/// Reflects upon a given [type] and dynamically generates a [GraphQLType] that corresponds to it.
|
/// Reflects upon a given [type] and dynamically generates a [GraphQLType] that corresponds to it.
|
||||||
///
|
///
|
||||||
/// This function is aware of the annotations from `package:angel_serialize`, and works seamlessly
|
/// This function is aware of the annotations from `package:angel_serialize`, and works seamlessly
|
||||||
|
|
Loading…
Reference in a new issue