Skip to content

Commit

Permalink
feat: introduce stronger types to fail fast (#5)
Browse files Browse the repository at this point in the history
feat: introduce stronger types to fail fast
feat: don't export types that might still be renamed and are not essential for usage
feat: add isRelationshipDataPresent -helper method
task: remove unnecessary parameter from deserializeRelationship -methods
feat: getItem* can return null and we can deal with it

BREAKING-CHANGE: the ItemDeserializer methods have changed
  • Loading branch information
Strobotti authored May 22, 2023
1 parent bbe1f71 commit 710704e
Show file tree
Hide file tree
Showing 3 changed files with 239 additions and 157 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ const yourJsonData = fetch('https://api.example.com/api/folders');
const rootItems: any[] = deserializer.consume(yourJsonData).getRootItems();
```

Please note that the deserializer only supports successful responses, and you will get an error if the response is not compatible with the JSON:API specification.
I practise the response should be checked for errors before deserializing it and the error handling should be done separately.

### Examples

* [The JSON from the jsonapi.org example](docs/examples/jsonapiorg)
Expand Down
35 changes: 22 additions & 13 deletions src/__tests__/Deserializer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ const jsonapiOrgExampleData2 = {
self: 'https://example.com/articles/1/relationships/comments',
related: 'https://example.com/articles/1/comments',
},
data: null,
data: [],
},
},
links: {
Expand All @@ -135,7 +135,7 @@ const jsonapiOrgExampleData2 = {
type Article = {
id: number;
title: string;
author?: Person;
author?: Person|null;
comments: Comment[];
};

Expand All @@ -156,13 +156,18 @@ const articleDeserializer: ItemDeserializer<Article> = {
type: 'articles',
deserialize: (item: Item, relationshipDeserializer: RelationshipDeserializer): Article => {
const article: Article = {
author: null,
id: parseInt(item.id),
title: item.attributes.title,
comments: [],
};

article.author = relationshipDeserializer.deserializeRelationship(relationshipDeserializer, item, 'author');
article.comments = relationshipDeserializer.deserializeRelationships(relationshipDeserializer, item, 'comments');
if (relationshipDeserializer.isRelationshipDataPresent(item, 'author')) {
article.author = relationshipDeserializer.deserializeRelationship(item, 'author');
}
if (relationshipDeserializer.isRelationshipDataPresent(item, 'comments')) {
article.comments = relationshipDeserializer.deserializeRelationships(item, 'comments');
}

return article;
},
Expand All @@ -188,8 +193,9 @@ const commentDeserializer: ItemDeserializer<Comment> = {
body: item.attributes.body,
};

comment.author = relationshipDeserializer.deserializeRelationship(relationshipDeserializer, item, 'author');

if (relationshipDeserializer.isRelationshipDataPresent(item, 'author')) {
comment.author = relationshipDeserializer.deserializeRelationship(item, 'author');
}
return comment;
},
};
Expand Down Expand Up @@ -347,7 +353,7 @@ const fileSystemExampleData3 = {
related: 'https://example.com/folders/1/children',
self: 'https://example.com/folders/1/relationships/children',
},
data: null,
data: [],
},
},
},
Expand All @@ -373,8 +379,9 @@ const folderDeserializer: ItemDeserializer<Folder> = {
children: [],
};

folder.children = relationshipDeserializer.deserializeRelationships(relationshipDeserializer, item, 'children');

if (relationshipDeserializer.isRelationshipDataPresent(item, 'children')) {
folder.children = relationshipDeserializer.deserializeRelationships(item, 'children');
}
return folder;
},
};
Expand All @@ -391,17 +398,19 @@ const fileDeserializer: ItemDeserializer<File> = {

describe('Deserializer', () => {
it('deserializes the jsonapi.org example into an object graph', () => {
const deserializer: Deserializer = getDeserializer([articleDeserializer, personDeserializer, commentDeserializer]);
const deserializer: Deserializer = getDeserializer([articleDeserializer, personDeserializer, commentDeserializer])
.consume(jsonapiOrgExampleData);

const rootItems: any[] = deserializer.consume(jsonapiOrgExampleData).getRootItems();
const rootItems: any[] = deserializer.getRootItems();

expect(rootItems).toMatchSnapshot();
});

it('deserializes the second jsonapi.org example (without relationships but with relationships.*.links and data:null) into an object graph', () => {
const deserializer: Deserializer = getDeserializer([articleDeserializer, personDeserializer, commentDeserializer]);
const deserializer: Deserializer = getDeserializer([articleDeserializer, personDeserializer, commentDeserializer])
.consume(jsonapiOrgExampleData2);

const rootItems: any[] = deserializer.consume(jsonapiOrgExampleData2).getRootItems();
const rootItems: any[] = deserializer.getRootItems();

expect(rootItems).toMatchSnapshot();
});
Expand Down
Loading

0 comments on commit 710704e

Please sign in to comment.