Fix apollo support
This commit is contained in:
parent
c58c8db65f
commit
940f6235af
9 changed files with 71 additions and 55 deletions
|
@ -81,8 +81,9 @@ main() async {
|
|||
);
|
||||
|
||||
// Mount GraphQL routes; we'll support HTTP and WebSockets transports.
|
||||
app.get('/graphql', graphQLHttp(GraphQL(schema)));
|
||||
app.get('/subscriptions', graphQLWS(GraphQL(schema)));
|
||||
app.all('/graphql', graphQLHttp(GraphQL(schema)));
|
||||
app.get('/subscriptions',
|
||||
graphQLWS(GraphQL(schema), keepAliveInterval: Duration(seconds: 3)));
|
||||
app.get('/graphiql',
|
||||
graphiQL(subscriptionsEndpoint: 'ws://localhost:3000/subscriptions'));
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ String renderGraphiql(
|
|||
if (subscriptionsEndpoint != null) {
|
||||
fetcherName = 'subscriptionsFetcher';
|
||||
subscriptionsScripts = '''
|
||||
<script src="//unpkg.com/subscriptions-transport-ws@0.5.4/browser/client.js"></script>
|
||||
<script src="//unpkg.com/subscriptions-transport-ws@0.8.3/browser/client.js"></script>
|
||||
<script src="//unpkg.com/graphiql-subscriptions-fetcher@0.0.2/browser/client.js"></script>
|
||||
''';
|
||||
subscriptionsFetcher = '''
|
||||
|
|
|
@ -22,12 +22,12 @@ RequestHandler graphQLWS(GraphQL graphQL, {Duration keepAliveInterval}) {
|
|||
await res.detach();
|
||||
var socket = await WebSocketTransformer.upgrade(req.rawRequest,
|
||||
protocolSelector: (protocols) {
|
||||
if (protocols.contains('graphql-subscriptions'))
|
||||
return 'graphql-subscriptions';
|
||||
if (protocols.contains('graphql-ws'))
|
||||
return 'graphql-ws';
|
||||
else
|
||||
throw AngelHttpException.badRequest(
|
||||
message:
|
||||
'Only the "graphql-subscriptions" protocol is allowed.');
|
||||
'Only the "graphql-ws" protocol is allowed.');
|
||||
});
|
||||
var channel = IOWebSocketChannel(socket);
|
||||
var client = stw.RemoteClient(channel.cast<String>());
|
||||
|
|
|
@ -18,6 +18,6 @@ dependencies:
|
|||
dev_dependencies:
|
||||
angel_serialize: ^2.0.0
|
||||
logging: ^0.11.0
|
||||
# dependency_overrides:
|
||||
# graphql_server:
|
||||
# path: ../graphql_server
|
||||
dependency_overrides:
|
||||
graphql_server:
|
||||
path: ../graphql_server
|
|
@ -1,3 +1,6 @@
|
|||
# 1.0.0-rc.0
|
||||
* Get the Apollo support working with the latest version of `subscriptions-transport-ws`.
|
||||
|
||||
# 1.0.0-beta.4
|
||||
For some reason, Pub was not including `subscriptions_transport_ws.dart`.
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import 'package:graphql_schema/graphql_schema.dart';
|
|||
|
||||
/// Performs introspection over a GraphQL [schema], and returns a new one, containing
|
||||
/// introspective information.
|
||||
///
|
||||
///
|
||||
/// [allTypes] should contain all types, not directly defined in the schema, that you
|
||||
/// would like to have introspection available for.
|
||||
GraphQLSchema reflectSchema(GraphQLSchema schema, List<GraphQLType> allTypes) {
|
||||
|
|
|
@ -8,6 +8,7 @@ abstract class Server {
|
|||
final Completer _done = Completer();
|
||||
StreamSubscription<OperationMessage> _sub;
|
||||
bool _init = false;
|
||||
Timer _timer;
|
||||
|
||||
Future get done => _done.future;
|
||||
|
||||
|
@ -29,10 +30,14 @@ abstract class Server {
|
|||
client.sink
|
||||
.add(OperationMessage(OperationMessage.gqlConnectionAck));
|
||||
|
||||
// if (keepAliveInterval != null) {
|
||||
// client.sink.add(
|
||||
// OperationMessage(OperationMessage.gqlConnectionKeepAlive));
|
||||
// }
|
||||
if (keepAliveInterval != null) {
|
||||
client.sink.add(
|
||||
OperationMessage(OperationMessage.gqlConnectionKeepAlive));
|
||||
_timer ??= Timer.periodic(keepAliveInterval, (timer) {
|
||||
client.sink.add(OperationMessage(
|
||||
OperationMessage.gqlConnectionKeepAlive));
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
if (e == false)
|
||||
_reportError('The connection was rejected.');
|
||||
|
@ -66,46 +71,46 @@ abstract class Server {
|
|||
query as String,
|
||||
(variables as Map)?.cast<String, dynamic>(),
|
||||
operationName as String);
|
||||
// var c = Completer();
|
||||
// if (keepAliveInterval != null) {
|
||||
// Timer.periodic(keepAliveInterval, (timer) {
|
||||
// if (c.isCompleted) {
|
||||
// timer.cancel();
|
||||
// } else {
|
||||
// client.sink.add(OperationMessage(
|
||||
// OperationMessage.gqlConnectionKeepAlive,
|
||||
// id: msg.id));
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
var data = result.data;
|
||||
|
||||
if (data is Stream) {
|
||||
await for (var event in data) {
|
||||
client.sink.add(OperationMessage(OperationMessage.gqlData,
|
||||
id: msg.id,
|
||||
payload: {'data': event, 'errors': result.errors}));
|
||||
}
|
||||
} else {
|
||||
if (result.errors.isNotEmpty) {
|
||||
client.sink.add(OperationMessage(OperationMessage.gqlData,
|
||||
id: msg.id,
|
||||
payload: {'data': data, 'errors': result.errors}));
|
||||
id: msg.id, payload: {'errors': result.errors.toList()}));
|
||||
} else {
|
||||
if (data is Map &&
|
||||
data.keys.length == 1 &&
|
||||
data.containsKey('data')) {
|
||||
data = data['data'];
|
||||
}
|
||||
|
||||
if (data is Stream) {
|
||||
await for (var event in data) {
|
||||
if (event is Map &&
|
||||
event.keys.length == 1 &&
|
||||
event.containsKey('data')) {
|
||||
event = event['data'];
|
||||
}
|
||||
client.sink.add(OperationMessage(OperationMessage.gqlData,
|
||||
id: msg.id, payload: {'data': event}));
|
||||
}
|
||||
} else {
|
||||
client.sink.add(OperationMessage(OperationMessage.gqlData,
|
||||
id: msg.id, payload: {'data': data}));
|
||||
}
|
||||
}
|
||||
|
||||
// c.complete();
|
||||
client.sink.add(
|
||||
OperationMessage(OperationMessage.gqlComplete, id: msg.id));
|
||||
} else if (msg.type == OperationMessage.gqlConnectionTerminate) {
|
||||
await _sub?.cancel();
|
||||
}
|
||||
// TODO: https://github.com/apollographql/subscriptions-transport-ws/issues/551
|
||||
// else if (msg.type == OperationMessage.gqlConnectionTerminate) {
|
||||
// await _sub?.cancel();
|
||||
// }
|
||||
}
|
||||
},
|
||||
onError: _done.completeError,
|
||||
onDone: () {
|
||||
_done.complete();
|
||||
_timer?.cancel();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,21 +1,28 @@
|
|||
import 'dart:async';
|
||||
import 'package:graphql_schema/graphql_schema.dart';
|
||||
import 'package:stream_channel/stream_channel.dart';
|
||||
|
||||
/// A basic message in the Apollo WebSocket protocol.
|
||||
class OperationMessage {
|
||||
static const String gqlConnectionInit = 'init',
|
||||
gqlConnectionAck = 'init_success',
|
||||
gqlConnectionKeepAlive = 'keepalive',
|
||||
gqlConnectionError = 'init_fail',
|
||||
gqlStart = 'subscription_start',
|
||||
gqlStop = 'subscription_end',
|
||||
// TODO: Does this have a replacement?
|
||||
// https://github.com/apollographql/subscriptions-transport-ws/issues/551
|
||||
// gqlConnectionTerminate = 'subscription_end',
|
||||
gqlData = 'subscription_data',
|
||||
gqlError = 'subscription_fail',
|
||||
gqlComplete = 'subscription_success';
|
||||
static const String gqlConnectionInit = 'connection_init',
|
||||
gqlConnectionAck = 'connection_ack',
|
||||
gqlConnectionKeepAlive = 'ka',
|
||||
gqlConnectionError = 'connection_error',
|
||||
gqlStart = 'start',
|
||||
gqlStop = 'stop',
|
||||
gqlConnectionTerminate = 'connection_terminate',
|
||||
gqlData = 'data',
|
||||
gqlError = 'error',
|
||||
gqlComplete = 'complete';
|
||||
static const String legacyGqlConnectionInit = 'connection_init',
|
||||
legacyGqlConnectionAck = 'connection_ack',
|
||||
legacyGqlConnectionKeepAlive = 'ka',
|
||||
legacyGqlConnectionError = 'connection_error',
|
||||
legacyGqlStart = 'start',
|
||||
legacyGqlStop = 'stop',
|
||||
legacyGqlConnectionTerminate = 'connection_terminate',
|
||||
legacyGqlData = 'data',
|
||||
legacyGqlError = 'error',
|
||||
legacyGqlComplete = 'complete';
|
||||
|
||||
// static const String gqlConnectionInit = 'GQL_CONNECTION_INIT',
|
||||
// gqlConnectionAck = 'GQL_CONNECTION_ACK',
|
||||
// gqlConnectionKeepAlive = 'GQL_CONNECTION_KEEP_ALIVE',
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name: graphql_server
|
||||
version: 1.0.0-beta.4
|
||||
version: 1.0.0-rc.0
|
||||
author: Tobe O <thosakwe@gmail.com>
|
||||
description: Base package for implementing GraphQL servers. You might prefer `package:angel_graphql`, the fastest way to implement GraphQL backends in Dart.
|
||||
homepage: https://github.com/angel-dart/graphql
|
||||
|
|
Loading…
Reference in a new issue