Last updated:
0 purchases
normalize
Normalizes and denormalizes data for GraphQL operations.
The normalize function writes normalized documents to a normalized Map 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 TypePolicy is provided for the given type, it's TypePolicy.keyFields are used.
If a dataIdFromObject funciton is provided, the result is used.
The id or _id field (respectively) are used.
The library includes the following methods:
normalize: writes normalized documents to a normalized Map
denormalize: reads and reconstructs objects from a normalized Map
normalizeFragment: writes normalized fragments to a normalized Map
denormalizeFragment: reads and reconstructs fragments from a normalized Map
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
}
}
}
}
""")
copied to clipboard
... and executing that query produces the following response data:
final Map<String, dynamic> 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",
}
}
],
}
]
};
copied to clipboard
We can then run our normalize function:
final normalizedMap = {};
normalizeOperation(
merge: (dataId, value) =>
(normalizedMap[dataId] ??= {}).addAll(value),
document: query,
data: data,
);
print(normalizedMap);
copied to clipboard
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",
}
}
copied to clipboard
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.
denormalizeOperation(
document: query,
read: (dataId) => normalizedMap[dataId],
)
copied to clipboard
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.
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.