normalize 0.0.1
normalize: ^0.0.1 copied to clipboard
Normalization and denormalization of GraphQL responses in Dart
Normalize #
About #
This project allows for the normalization and denormalization of GraphQL Documents.
The normalize function creates a flat map of normalized documents and can be used to cache results of GraphQL queries. It traverses the GraphQL AST and only includes the fields specified in the GraphQL Document in the normalized results.
The normalize function only normalizes entities that include a __typename field and a valid ID.
IDs are determined by the following:
- If a
TypePolicyis provided for the given type, it'sTypePolicy.keyFieldsare used. - If a
dataIdFromObjectfunciton is provided, the result is used. - The
idor_idfield (respectively) are used.
Features #
| Feature | Progress |
|---|---|
| Fragments | ✅ |
| Variables | ✅ |
| Interface & Union types | ✅ |
| Aliases | ✅ |
TypePolicys (see Apollo) |
✅ |
Usage #
Assuming we have the following query...
import 'package:gql/language.dart';
import 'package:gql/ast.dart';
import 'package:normalize/normalize.dart';
final DocumentNode query = parseString("""
query TestQuery {
posts {
id
__typename
author {
id
__typename
name
}
title
comments {
id
__typename
commenter {
id
__typename
name
}
}
}
}
""")
... and executing that query produces the following response data:
final Map<String, Object> data = {
"posts": [
{
"id": "123",
"__typename": "Post",
"author": {"id": "1", "__typename": "Author", "name": "Paul"},
"title": "My awesome blog post",
"comments": [
{
"id": "324",
"__typename": "Comment",
"commenter": {"id": "2", "__typename": "Author", "name": "Nicole"}
}
]
}
]
};
We can then run our normalize function:
final Map<String, Object> normalizedMap = normalize(query: query, data: data);
print(normalized);
Which will produce the following normalized result:
{
"Query": {
"posts": [
{"$ref": "Post:123"}
]
},
"Post:123": {
"id": "123",
"__typename": "Post",
"author": {"$ref": "Author:1"},
"title": "My awesome blog post",
"comments": [
{"$ref": "Comment:324"}
]
},
"Author:1": {"id": "1", "__typename": "Author", "name": "Paul"},
"Comment:324": {
"id": "324",
"__typename": "Comment",
"commenter": {"$ref": "Author:2"}
},
"Author:2": {"id": "2", "__typename": "Author", "name": "Nicole"}
}
If we later want to denormalize this data (for example, when reading from a cache), we can call denormalize on the normalizedMap from above. This will give us back the original data response object.
denormalize(query: query, normalizedMap: normalizedMap)
Limitations #
TypePolicy.keyFields and FieldPolicy.keyArgs currently only accept a flat list of Strings. Functions and nested lists of strings and are not yet supported. FieldPolicy.merge and FieldPolicy.read are also not yet supported.
Dependencies #
This library depends on the gql library.