grapher_annotation 0.5.0
grapher_annotation: ^0.5.0 copied to clipboard
Annotation package for 'grapher_builder' package. For generating GraphQL based on dart code models.
Grapher #
Grapher is a helper for generating client-side GraphQL from models written in Dart!
Support all base features:
- Type, Input, Enum
- Query, Mutation, Subscription
- Union
- Subquery (query on field)
Not implemented, but plan:
- Fragments generation (for reduce query complexity)
- Multiple queries in one
Usage #
See example project
Types #
Define class with unnamed or _ constructor, all fields in this constructor used in code generation
Below are examples of the Dart model for the GraphQL entity example.
Object #
Objects validation only occurs if a name is specified or object used in actions If name is not specified, it search in parent objects
@GrapherObject(name: 'Item')
class Item {
final ID id;
final DateTime createdAt;
final String name;
final String? description;
final int count;
final ItemStatus? status; // Enumeration values are optional to ensure greater compatibility.
const Item(
this.id,
this.createdAt,
this.name,
this.description,
this.count,
this.status,
);
}
type Item {
id: ID!
createdAt: Timestamp!
name: String!
description: String
count: Int!
price: Double!
status: ItemStatus!
}
Input #
@GrapherInput(name: "SelectItemInput")
class SelectItemInput {
final ID? id;
const SelectItemInput({this.id});
}
input SelectItemInput {
id: ID
}
For greater compatibility, you can replace enum values with a string.
Fields #
All fields maybe annotated for change behavior
@GrapherObject(name: 'Item')
class Item {
@GrapherField(name: 'code')
final ID id;
const Item(
this.id,
);
}
Enum #
@GrapherEnum(name: "Status")
enum Status {
@GrapherEnumValue(name: "new")
open,
closed,
}
enum Status {
new,
closed
}
Actions #
The library uses wrappers that you must use result for further use
Use in
- static function in object or input
@GrapherObject()
class Item {
// ...
@GrapherQuery(name: 'items')
static Query<List<Item>> query(SelectItemInput input) => _itemQuery(input);
}
extend type Query {
items(input: SelectItemInput!): [Item!]!
}
- top level function
@GrapherQuery(name: 'items')
Query<List<Item>> query(SelectItemInput input) => _query(input);
- getter in input
@GrapherObject()
class UpdateItemInput {
// ...
@GrapherMutation(name: 'updateItem')
Mutation<Item> get mutation => _updateItemInputMutation(this);
}
Query #
Mutation #
Subscription #
Options #
Resolvers #
For custom types use resolvers and create custom annotation
Custom resolver maybe const class!
@GrapherResolver(name: 'Timestamp')
class TimestampResolver with GrapherResolverMixin<DateTime> {
const TimestampResolver();
@override
DateTime fromMap(dynamic json) => DateTime.parse(json as String);
@override
dynamic toMap(DateTime value) {
return value.toUtc().toIso8601String();
}
}
// To avoid import issues, define the resolver class or instance in the same file as the new annotations.
const timestampResolver = TimestampResolver();
// Example for GrapherObject
class ProjectObject extends GrapherObject {
const ProjectObject({super.name})
: super(resolvers: const [timestampResolver]);
}
// And use @ProjectObject(name:)