Last updated:
0 purchases
gql
A package for working with GraphQL documents.
This package exports several libraries:
package:gql/language.dart provides ability to parse GraphQL string into AST and print AST as a string;
package:gql/ast.dart defines the AST and provides visitors and transformers;
⚠ Call for contributions ⚠ #
package:gql/document.dart implements some of the validation rules defined in GraphQL spec.
PRs are welcome to finish the validation support. Rules which are concerned with Schema validation should take preference over rules concerned with Document validation.
package:gql/language.dart #
Parsing GraphQL documents #
import "package:gql/language.dart" as lang;
import "package:gql/ast.dart" as ast;
void main() {
final ast.DocumentNode doc = lang.parseString(
r"""
query UserInfo($id: ID!) {
user(id: $id) {
id
name
}
}
""",
);
print(
(doc.definitions.first as ast.OperationDefinitionNode).name.value,
); // prints "UserInfo"
}
copied to clipboard
Printing GraphQL AST to string #
import "package:gql/ast.dart" as ast;
import "package:gql/language.dart" as lang;
void main() {
print(
lang.printNode(
const ast.SchemaDefinitionNode(
operationTypes: [
ast.OperationTypeDefinitionNode(
operation: ast.OperationType.query,
type: ast.NamedTypeNode(
name: ast.NameNode(value: "MyQuery"),
isNonNull: false,
),
)
],
),
),
);
// prints
// "schema {
// query: MyQuery
// }"
}
copied to clipboard
package:gql/ast.dart #
Visiting GraphQL AST nodes #
import "package:gql/ast.dart" as ast;
import "package:gql/language.dart" as lang;
class TypeVisitor extends ast.RecursiveVisitor {
Iterable<ast.ObjectTypeDefinitionNode> types = [];
@override
visitObjectTypeDefinitionNode(
ast.ObjectTypeDefinitionNode node,
) {
types = types.followedBy([node]);
super.visitObjectTypeDefinitionNode(node);
}
}
void main() {
final ast.DocumentNode doc = lang.parseString(
"""
type A { id: ID! }
type B { id: ID! }
type C { id: ID! }
type D { id: ID! }
type E { id: ID! }
""",
);
final TypeVisitor v = TypeVisitor();
doc.accept(v);
print(
v.types
.map(
(t) => t.name.value,
)
.join("\n"),
);
// prints
// "A
// B
// C
// D
// E"
}
copied to clipboard
Transforming GraphQL documents #
import "package:gql/ast.dart" as ast;
import "package:gql/language.dart" as lang;
class AddTypenames extends ast.TransformingVisitor {
@override
ast.FieldNode visitFieldNode(ast.FieldNode node) {
if (node.selectionSet == null) {
return node;
}
return ast.FieldNode(
name: node.name,
alias: node.alias,
arguments: node.arguments,
directives: node.directives,
selectionSet: ast.SelectionSetNode(
selections: <ast.SelectionNode>[
ast.FieldNode(
name: ast.NameNode(value: "__typename"),
),
...node.selectionSet.selections
],
),
);
}
}
void main() {
final ast.DocumentNode doc = lang.parseString(
r"""
query UserInfo($id: ID!, $articleId: ID!) {
user(id: $id) {
id
name
}
post(id: $articleId) {
id
title
description
}
}
""",
);
final ast.DocumentNode withTypenames = ast.transform(
doc,
[
AddTypenames(),
],
);
print(
lang.printNode(withTypenames),
);
// prints
// "query UserInfo($id: ID!, $articleId: ID!) {
// user(id: $id) {
// __typename
// id
// name
// }
// post(id: $articleId) {
// __typename
// id
// title
// description
// }
// }"
}
copied to clipboard
gql/schema.dart and gql/operation.dart (experimental) #
gql/schema.dart and gql/operation.dart provide higher-level
type definitions derived from gql/ast.dart asts for
GraphQL Schemas and Operations respectively.
NOTE: does not currently have runtime features, such as field resolution.
It was initially developed as a more friendly way to work with schema ASTs.
import "package:gql/language.dart" as lang;
import "package:gql/schema.dart" as gql_schema;
import "package:gql/operation.dart" as gql_operation;
final schemaDefinition = lang.parseString(r"""
schema {
query: StarWarsQuery
}
interface Character {
id: String
name: String
}
type Droid implements Character {
id: String
name: String
primaryFunction: String
}
type StarWarsQuery {
droids: [Droid!]
}
""");
void inspectSchema() {
final schema = gql_schema.GraphQLSchema.fromNode(schemaDefinition);
final character =
schema.getType("Character") as gql_schema.InterfaceTypeDefinition;
final droid = schema.getType("Droid") as gql_schema.ObjectTypeDefinition;
print(character.isImplementedBy(droid));
// prints "true"
print(schema.query.getField("droids").type.toString());
// prints "[Droid!]"
}
final fragmentDefinitions = [
lang.parseString(r"""
fragment droidName on Droid {
name
}
"""),
];
final queryDefinition = lang.parseString(r"""
query AllDroids {
droids {
...droidName
primaryFunction
}
}
""");
void inspectQuery() {
final schema = gql_schema.GraphQLSchema.fromNode(schemaDefinition);
final document = gql_operation.ExecutableDocument(
queryDefinition,
schema.getType,
// necessary for dereferencing schema definitions
fragmentDefinitions,
);
final importedFragment = document.getFragment("droidName");
print(importedFragment);
// prints the fagment above
final query = document.operations.first;
final droids = query.selectionSet.fields.first;
final spreadDroidName = droids.selectionSet.fragmentSpreads.first;
print(
// dereference fragment spread into fragment definition
spreadDroidName.fragment == importedFragment,
);
}
void main() {
inspectSchema();
inspectQuery();
}
copied to clipboard
Features and bugs #
Please file feature requests and bugs at the GitHub.
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.