.. | ||
example | ||
lib | ||
test | ||
.gitignore | ||
analysis_options.yaml | ||
CHANGELOG.md | ||
graphql_server.iml | ||
LICENSE | ||
mono_pkg.yaml | ||
pubspec.yaml | ||
README.md |
graphql_server
Base package for implementing GraphQL servers.
You might prefer package:angel_graphql
,
the fastest way to implement GraphQL backends in Dart.
package:graphql_server
does not require any specific
framework, and thus can be used in any Dart project.
Ad-hoc Usage
The actual querying functionality is handled by the
GraphQL
class, which takes a schema (from package:graphql_schema
).
In most cases, you'll want to call parseAndExecute
on some string of GraphQL text. It returns either a Stream
or Map<String, dynamic>
, and can potentially throw
a GraphQLException
(which is JSON-serializable):
try {
var data = await graphQL.parseExecute(responseText);
if (data is Stream) {
// Handle a subscription somehow...
} else {
response.send({'data': data});
}
} on GraphQLException catch(e) {
response.send(e.toJson());
}
Consult the API reference for more: https://pub.dartlang.org/documentation/graphql_server/latest/graphql_server/GraphQL/parseAndExecute.html
If you're looking for functionality like graphQLHttp
in graphql-js
, that is not included in this package, because
it is typically specific to the framework/platform you are using.
The graphQLHttp
implementation in package:angel_graphql
is
a good example:
https://github.com/angel-dart/graphql/blob/master/angel_graphql/lib/src/graphql_http.dart
Subscriptions
GraphQL queries involving subscription
operations can return
a Stream
. Ultimately, the transport for relaying subscription
events to clients is not specified in the GraphQL spec, so it's
up to you.
Note that in a schema like this:
type TodoSubscription {
onTodo: TodoAdded!
}
type TodoAdded {
id: ID!
text: String!
isComplete: Bool
}
Your Dart schema's resolver for onTodo
should be
a Map
containing an onTodo
key:
field(
'onTodo',
todoAddedType,
resolve: (_, __) {
return someStreamOfTodos()
.map((todo) => {'onTodo': todo});
},
);
For the purposes of reusing existing tooling (i.e. JS clients, etc.),
package:graphql_server
rolls with an implementation of Apollo's
subscriptions-transport-ws
spec.
NOTE: At this point, Apollo's spec is extremely out-of-sync with the protocol their client actually expects. See the following issue to track this: https://github.com/apollographql/subscriptions-transport-ws/issues/551
The implementation is built on package:stream_channel
, and
therefore can be used on any two-way transport, whether it is
WebSockets, TCP sockets, Isolates, or otherwise.
Users of this package are expected to extend the Server
abstract class. Server
will handle the transport and communication,
but again, ultimately, emitting subscription events is up to your
implementation.
Here's a snippet from graphQLWS
in package:angel_graphql
.
It runs within the context of one single request:
var channel = IOWebSocketChannel(socket);
var client = stw.RemoteClient(channel.cast<String>());
var server =
_GraphQLWSServer(client, graphQL, req, res, keepAliveInterval);
await server.done;
See graphQLWS
in package:angel_graphql
for a good example:
https://github.com/angel-dart/graphql/blob/master/angel_graphql/lib/src/graphql_ws.dart
Introspection
Introspection of a GraphQL schema allows clients to query the schema itself,
and get information about the response the server expects. The GraphQL
class handles this automatically, so you don't have to write any code for it.
However, you can call the reflectSchema
method to manually reflect a schema:
https://pub.dartlang.org/documentation/graphql_server/latest/introspection/reflectSchema.html
Mirrors Usage
By default, dart:mirrors
is not required, but it can be optionally used.
The mirrorsFieldResolver
can resolve fields from concrete objects, instead of you
first having to serialize them:
https://pub.dartlang.org/documentation/graphql_server/latest/graphql_server.mirrors/mirrorsFieldResolver.html
You can also use convertDartType
to convert a concrete Dart type into a GraphQLType
. However,
the ideal choice is package:graphql_generator
.