normalize 0.9.1 copy "normalize: ^0.9.1" to clipboard
normalize: ^0.9.1 copied to clipboard

Normalization and denormalization of GraphQL responses in Dart

MIT License PRs Welcome Watch on GitHub Star on GitHub Watch on GitHub Discord

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:

  1. If a TypePolicy is provided for the given type, it's TypePolicy.keyFields are used.
  2. If a dataIdFromObject funciton is provided, the result is used.
  3. The id or _id field (respectively) are used.

The library includes the following methods:

  1. normalize: writes normalized documents to a normalized Map
  2. denormalize: reads and reconstructs objects from a normalized Map
  3. normalizeFragment: writes normalized fragments to a normalized Map
  4. 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
        }
      }
    }
  }
""")

... 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",
          }
        }
      ],
    }
  ]
};

We can then run our normalize function:

final normalizedMap = {};
normalizeOperation(
  merge: (dataId, value) =>
      (normalizedMap[dataId] ??= {}).addAll(value),
  document: query,
  data: data,
);
print(normalizedMap);

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.

denormalizeOperation(
  document: query,
  read: (dataId) => normalizedMap[dataId],
)

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.

15
likes
150
pub points
87%
popularity

Publisher

verified publishergql-dart.dev

Normalization and denormalization of GraphQL responses in Dart

Homepage
Repository (GitHub)
View/report issues
Contributing

Topics

#graphql #gql

Documentation

API reference

License

MIT (license)

Dependencies

collection, gql

More

Packages that depend on normalize