graphql_fragment_builder 1.1.0
graphql_fragment_builder: ^1.1.0 copied to clipboard
A small Dart builder for GraphQL selection sets, variables, and operation documents.
GraphQL Fragment Builder #
GraphQL Fragment Builder is a small Dart package for building GraphQL selection sets, variables, fragments, and operation documents without assembling strings by hand. It keeps the query shape close to Dart code, while still producing plain GraphQL strings and variable maps for any client.
Quick Start #
Runtime: Dart >= 3.5.1.
Add the package:
dependencies:
graphql_fragment_builder: ^1.1.0
Build a document:
import 'package:graphql_fragment_builder/graphql_fragment_builder.dart';
const bookFields = GraphQLFragmentDefinition(
name: 'BookFields',
typeCondition: 'Book',
fields: ['id', 'title', 'publicationYear'],
);
final query = GraphQLQueryBuilder(
name: 'booksByAuthor',
operationName: 'BooksByAuthor',
parameters: const [
QueryParameter('authorName', 'Jane Austen', type: 'String', isRequired: true),
QueryParameter('bookLimit', 5, argumentName: 'limit', type: 'Int'),
],
fragments: const [
FragmentSpread('BookFields'),
QuerySelection(
name: 'reviews',
parameters: [
QueryParameter('reviewLimit', 3, argumentName: 'limit', type: 'Int'),
],
fields: ['rating', 'body'],
),
],
fragmentDefinitions: const [bookFields],
);
print(query.buildDocument());
print(query.variables);
Output:
query BooksByAuthor($authorName: String!, $bookLimit: Int, $reviewLimit: Int) {
booksByAuthor(authorName: $authorName, limit: $bookLimit) {
...BookFields
reviews(limit: $reviewLimit) {
rating
body
}
}
}
fragment BookFields on Book {
id
title
publicationYear
}
{authorName: Jane Austen, bookLimit: 5, reviewLimit: 3}
What It Builds #
| Method | Output | Use it when |
|---|---|---|
buildQuery() |
A root field selection | Your GraphQL client wraps the operation for you |
buildDocument() |
A full query, mutation, or subscription document |
You send the document string yourself |
variables |
A merged variable map from the whole selection tree | Your client sends variables separately |
Variables And Arguments #
QueryParameter.name is the GraphQL variable name. By default it is also the schema argument name.
Use argumentName when the schema argument and local variable should differ:
QueryParameter('reviewLimit', 3, argumentName: 'limit', type: 'Int')
That emits:
limit: $reviewLimit
Variables are collected from the root field, nested selections, inline fragments, and named fragment definitions. Duplicate variable names are allowed only when they resolve to the same value and compatible metadata; conflicting duplicates throw ArgumentError.
Selection Sets #
Use SimpleQueryFragment when you only need a named object and scalar fields:
class BookDetailsFragment extends QueryFragment with SimpleQueryFragment {
@override
String get objectName => 'book';
@override
List<String> get fields => ['id', 'title', 'publishedAt'];
}
Use QuerySelection when a field needs arguments, an alias, or nested selections:
const QuerySelection(
name: 'author',
alias: 'primaryAuthor',
fields: ['name'],
);
Use InlineFragment for interfaces and unions:
const InlineFragment(
typeCondition: 'Book',
fields: ['title'],
);
Use GraphQLFragmentDefinition and FragmentSpread for reusable named fragments:
const bookFields = GraphQLFragmentDefinition(
name: 'BookFields',
typeCondition: 'Book',
fields: ['id', 'title'],
);
const spread = FragmentSpread('BookFields');
Operations #
Default behavior: GraphQLQueryBuilder creates a query.
Set operationType for mutations or subscriptions:
final mutation = GraphQLQueryBuilder(
name: 'updateBookTitle',
operationType: GraphQLOperationType.mutation,
operationName: 'UpdateBookTitle',
parameters: const [
QueryParameter('id', 'book-1', type: 'ID', isRequired: true),
QueryParameter('title', 'Persuasion', type: 'String'),
],
fragments: const [
QuerySelection(name: 'book', fields: ['id', 'title']),
],
);
QueryParameter.type is required for buildDocument(), because GraphQL operation documents need variable definitions. buildQuery() can still use parameters without types for clients that only need the root field selection.
Validation #
The builder validates GraphQL-facing names and variable types before emitting output:
- Operation names
- Root field names
- Argument and variable names
- Selection names and aliases
- Scalar field names
- GraphQL variable types such as
String,ID!, and[String!]! - Named fragment definitions and spreads
Invalid names and conflicting variables throw ArgumentError. Missing parameter types in buildDocument() throw StateError.
Development #
Install dependencies:
dart pub get
Run the full local check:
dart format --output=none --set-exit-if-changed lib test example
dart analyze
dart test
dart pub publish --dry-run
Project #
Website · gabrimatic.info
Source · github.com/gabrimatic/graphql_fragment_builder
Issues · github.com/gabrimatic/graphql_fragment_builder/issues