Skip to content

Commit

Permalink
docs: Update normalizr readme
Browse files Browse the repository at this point in the history
  • Loading branch information
ntucker committed Dec 18, 2023
1 parent 23af5b5 commit 67f4e0b
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 24 deletions.
5 changes: 5 additions & 0 deletions .changeset/odd-cars-cheer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@data-client/normalizr": patch
---

Update README
3 changes: 0 additions & 3 deletions docs/rest/api/schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,12 @@ class Article extends Entity {
import { schema, Entity } from '@data-client/endpoint';
import { Temporal } from '@js-temporal/polyfill';

// Define a users schema
class User extends Entity {
pk() {
return this.id;
}
}

// Define your comments schema
class Comment extends Entity {
pk() {
return this.id;
Expand All @@ -111,7 +109,6 @@ class Comment extends Entity {
};
}

// Define your article
class Article extends Entity {
pk() {
return this.id;
Expand Down
132 changes: 113 additions & 19 deletions packages/normalizr/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# normalizr
# Normalizr Client

[![CircleCI](https://circleci.com/gh/reactive/data-client/tree/master.svg?style=shield)](https://circleci.com/gh/data-clientdata-clients)
[![Coverage Status](https://img.shields.io/codecov/c/gh/reactive/data-client/master.svg?style=flat-square)](https://app.codecov.io/gh/data-clientdata-clients?branch=master)
Expand Down Expand Up @@ -35,9 +35,17 @@ Normalizr is a small, but powerful utility for taking JSON with a schema definit

## Examples

- [Normalizing GitHub Issues](/examples/normalizr-github)
- [Relational Data](/examples/normalizr-relationships)
- [Interactive Redux](/examples/normalizr-redux)
- [Normalizing GitHub Issues](../../examples/normalizr-github)
- [Relational Data](../../examples/normalizr-relationships)
- [Interactive Redux](../../examples/normalizr-redux)
- [Benchmarks](../../examples/benchmark)
- [Charts](https://reactive.github.io/data-client/dev/bench/)

## React Demos

- [Todo Demo](https://stackblitz.com/github/reactive/data-client/tree/master/examples/todo-app?file=src%2Fpages%2FHome%2FTodoList.tsx)
- [Github Demo](https://stackblitz.com/github/reactive/data-client/tree/master/examples/github-app?file=src%2Fpages%2FIssueList.tsx)
- [NextJS SSR Demo](https://stackblitz.com/github/reactive/data-client/tree/master/examples/nextjs?file=pages%2FAssetPrice.tsx)

## Quick Start

Expand All @@ -54,19 +62,29 @@ Consider a typical blog post. The API response for a single post might look some
"comments": [
{
"id": "324",
"createdAt": "2013-05-29T00:00:00-04:00",
"commenter": {
"id": "2",
"name": "Nicole"
}
},
{
"id": "544",
"createdAt": "2013-05-30T00:00:00-04:00",
"commenter": {
"id": "1",
"name": "Paul"
}
}
]
}
```

We have two nested entity types within our `article`: `users` and `comments`. Using various `schema`, we can normalize all three entity types down:
We have two [nested](https://dataclient.io/rest/guides/relational-data) [entity](https://dataclient.io/rest/api/Entity) types within our `article`: `users` and `comments`. Using various [schema](https://dataclient.io/rest/api/Entity#schema), we can normalize all three entity types down:

```js
import { normalize, schema, Entity } from '@data-client/normalizr';
import { schema, Entity } from '@data-client/endpoint';
import { Temporal } from '@js-temporal/polyfill';

// Define a users schema
class User extends Entity {
Expand All @@ -83,6 +101,7 @@ class Comment extends Entity {

static schema = {
commenter: User,
createdAt: Temporal.Instant.from,
};
}

Expand All @@ -97,41 +116,116 @@ class Article extends Entity {
comments: [Comment],
};
}
```

### Normalize

const normalizedData = normalize(originalData, Article);
```js
import { normalize } from '@data-client/normalizr';

const args = [{ id: '123' }];
const normalizedData = normalize(originalData, Article, args);
```

Now, `normalizedData` will be:
Now, `normalizedData` will create a single serializable source of truth for all entities:

```js
{
result: "123",
entities: {
"Article": {
articles: {
"123": {
id: "123",
author: "1",
title: "My awesome blog post",
comments: [ "324" ]
comments: [ "324", "544" ]
}
},
"User": {
users: {
"1": { "id": "1", "name": "Paul" },
"2": { "id": "2", "name": "Nicole" }
},
"Comment": {
"324": { id: "324", "commenter": "2" }
comments: {
"324": {
id: "324",
createdAt: "2013-05-29T00:00:00-04:00",
commenter: "2"
},
"544": {
id: "544",
createdAt: "2013-05-30T00:00:00-04:00",
commenter: "1"
}
}
}
},
}
```

`normalizedData` can be placed in any flux store as the single source of truth for this data.

### Denormalize

Accessing the store can then be done using flux `selectors` by `denormalizing`:

```js
import { denormalize } from '@data-client/normalizr';

const denormalizedData = denormalize(
normalizedData.result,
Article,
normalizedData.entities,
args,
);
```

Now, `denormalizedData` will instantiate the classes, ensuring all instances of the same member (like `Paul`) are referentially equal:

```js
Article {
id: '123',
title: 'My awesome blog post',
author: User { id: '1', name: 'Paul' },
comments: [
Comment {
id: '324',
createdAt: Instant [Temporal.Instant] {},
commenter: [User { id: '2', name: 'Nicole' }]
},
Comment {
id: '544',
createdAt: Instant [Temporal.Instant] {},
commenter: [User { id: '1', name: 'Paul' }]
}
]
}
```

## Dependencies
### Memoizing results

`denormalizeCached` can also be used to maintain referential equality between calls as well
as potentially improved performance by 2000%.

None.
```js
import { WeakEntityMap, denormalizeCached } from '@data-client/normalizr';

// maintain these cache variables unless you want to reset the cache
const entityCache = {};
const resultCache = new WeakEntityMap();

const { data: denormalizedData, paths } = denormalizeCached(
normalizedData.result,
Article,
normalizedData.entities,
entityCache,
resultCache,
args,
);
```

`paths` is an Array of paths of all entities included in the result.

## Credits

Normalizr was originally created by [Dan Abramov](http://github.com/gaearon) and inspired by a conversation with [Jing Chen](https://twitter.com/jingc). Since v3, it was completely rewritten and maintained by [Paul Armstrong](https://twitter.com/paularmstrong).
Since v4, it was largely rewritten and maintained by [Nathaniel Tucker](https://twitter.com/npinp).
It has also received much help, enthusiasm, and contributions from [community members](https://github.com/ntucker/normalizr/graphs/contributors).
Normalizr Client is based on [Normalizr](https://github.com/paularmstrong/normalizr) - originally created by [Dan Abramov](http://github.com/gaearon) and inspired by a conversation with [Jing Chen](https://twitter.com/jingc). Since v3, it was completely rewritten and maintained by [Paul Armstrong](https://twitter.com/paularmstrong).

Normalizr Client was rewritten and maintained by Normalizr contributor [Nathaniel Tucker](https://twitter.com/npinp). It has also received much help, enthusiasm, and contributions from [community members](https://github.com/ntucker/normalizr/graphs/contributors).
12 changes: 10 additions & 2 deletions packages/normalizr/docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ Normalizes input data per the schema definition provided.
### Usage

```js
import { normalize, schema } from '@data-client/normalizr';
import { schema } from '@data-client/endpoint';
import { normalize } from '@data-client/normalizr';

const myData = { users: [{ id: 1 }, { id: 2 }] };
const user = new schema.Entity('users');
Expand Down Expand Up @@ -56,7 +57,8 @@ If your schema and data have recursive references, only the first instance of an
### Usage

```js
import { denormalize, schema } from '@data-client/normalizr';
import { schema } from '@data-client/endpoint';
import { denormalize } from '@data-client/normalizr';

const user = new schema.Entity('users');
const mySchema = { users: [user] };
Expand Down Expand Up @@ -95,6 +97,8 @@ _Note: The same behavior can be defined with shorthand syntax: `[ mySchema ]`_
To describe a simple array of a singular entity type:

```js
import { schema } from '@data-client/endpoint';

const data = [{ id: '123', name: 'Jim' }, { id: '456', name: 'Jane' }];
const userSchema = new schema.Entity('users');

Expand Down Expand Up @@ -126,6 +130,8 @@ _Note: If your data returns an object that you did not provide a mapping for, th
For example:

```js
import { schema } from '@data-client/endpoint';

const data = [{ id: 1, type: 'admin' }, { id: 2, type: 'user' }];

const userSchema = new schema.Entity('users');
Expand Down Expand Up @@ -379,6 +385,8 @@ _Note: If your data returns an object that you did not provide a mapping for, th
For example:

```js
import { schema } from '@data-client/endpoint';

const data = {
'1': { id: 1, type: 'admin' },
'2': { id: 2, type: 'user' }
Expand Down

0 comments on commit 67f4e0b

Please sign in to comment.