@data-client/rest 0.9.4 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +85 -54
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Data Client for REST
1
+ # TypeScript HTTP definitions
2
2
 
3
3
  [![CircleCI](https://circleci.com/gh/reactive/data-client/tree/master.svg?style=shield)](https://circleci.com/gh/reactive/data-client)
4
4
  [![Coverage Status](https://img.shields.io/codecov/c/gh/reactive/data-client/master.svg?style=flat-square)](https://app.codecov.io/gh/reactive/data-client?branch=master)
@@ -8,93 +8,126 @@
8
8
  [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
9
9
  [![Chat](https://img.shields.io/discord/768254430381735967.svg?style=flat-square&colorB=758ED3)](https://discord.gg/35nb8Mz)
10
10
 
11
- Extensible CRUD patterns for REST APIs.
12
-
13
11
  <div align="center">
14
12
 
15
- **[📖Read The Docs](https://dataclient.io/rest)** &nbsp;|&nbsp; [🎮Github Demo](https://stackblitz.com/github/reactive/data-client/tree/master/examples/github-app?file=src%2Fresources%2FIssue.tsx)
13
+ **[📖Read The Docs](https://dataclient.io/rest)** &nbsp;|&nbsp; [🎮Todo Demo](https://stackblitz.com/github/reactive/data-client/tree/master/examples/todo-app?file=src%2Fresources%2FTodoResource.ts) &nbsp;|&nbsp; [🎮Github Demo](https://stackblitz.com/github/reactive/data-client/tree/master/examples/github-app?file=src%2Fresources%2FIssue.tsx)
16
14
 
17
15
  </div>
18
16
 
19
- ### Simple TypeScript definition
17
+ ## RestEndpoint
18
+
19
+ Simplify TypeScript fetch functions with [RestEndpoint](https://dataclient.io/rest/api/RestEndpoint)
20
20
 
21
21
  ```typescript
22
- import { Entity, createResource } from '@data-client/rest';
22
+ const getTodo = new RestEndpoint({
23
+ urlPrefix: 'https://jsonplaceholder.typicode.com',
24
+ path: '/todos/:id',
25
+ });
26
+ ```
23
27
 
24
- class Article extends Entity {
25
- id: number | undefined = undefined;
26
- title = '';
27
- body = '';
28
+ [RestEndpoint](https://dataclient.io/rest/api/RestEndpoint) infers [path-to-regex](https://github.com/pillarjs/path-to-regexp#compile-reverse-path-to-regexp)
29
+ argument types, enabling enforcement of function calls
30
+
31
+ ```typescript
32
+ // signature requires id!
33
+ const todo = await getTodo({ id: 5 });
34
+ ```
35
+
36
+ It automatically handles REST concepts like JSON serialization, consolidated error handling and more.
37
+
38
+ ## Resources
39
+
40
+ Simplify related CRUD endpoints with [Resources](https://dataclient.io/rest/api/createResource)
28
41
 
42
+ [Resources](https://dataclient.io/rest/api/createResource) are a collection of `methods` for a given `data model`.
43
+
44
+ [Entities](https://dataclient.io/rest/api/Entity) and [Schemas](https://dataclient.io/concepts/normalization) declaratively define the _data model_.
45
+ [RestEndpoints](https://dataclient.io/rest/api/RestEndpoint) are the [_methods_](<https://en.wikipedia.org/wiki/Method_(computer_programming)>) on
46
+ that data.
47
+
48
+ ```typescript
49
+ class Todo extends Entity {
50
+ id = 0;
51
+ userId = 0;
52
+ title = '';
53
+ completed = false;
29
54
  pk() {
30
- return this.id;
55
+ return `${this.id}`;
31
56
  }
32
57
  }
33
- const ArticleResource = createResource({
34
- path: '/articles/:id',
35
- schema: Article,
58
+ const TodoResource = createResource({
59
+ urlPrefix: 'https://jsonplaceholder.typicode.com',
60
+ path: '/todos/:id',
61
+ searchParams: {} as { userId?: string | number },
62
+ schema: Todo,
63
+ paginationField: 'page',
36
64
  });
37
65
  ```
38
66
 
39
- [Entity](https://dataclient.io/rest/api/Entity) defines a data model.
40
- [createResource](https://dataclient.io/rest/api/createResource) creates a [collection](https://dataclient.io/rest/api/createResource#members)
41
- of six [RestEndpoints](https://dataclient.io/rest/api/RestEndpoint)
67
+ One Resource defines [seven endpoints](https://dataclient.io/rest/api/createResource#members):
42
68
 
43
- [RestEndpoints](https://dataclient.io/rest/api/RestEndpoint) are functions (and more) that return a Promise.
44
- Both call parameters and return value are [automatically inferred](https://dataclient.io/rest/api/RestEndpoint#typing) from
45
- the options used to construct them.
69
+ ```typescript
70
+ // GET https://jsonplaceholder.typicode.com/todos/5
71
+ let todo5 = await TodoResource.get({ id: 5 });
46
72
 
47
- `path` is a templating language using [path-to-regex compile](https://github.com/pillarjs/path-to-regexp#compile-reverse-path-to-regexp).
73
+ // GET https://jsonplaceholder.typicode.com/todos
74
+ const todoList = await TodoResource.getList();
48
75
 
49
- ### [Standard CRUD Endpoints](https://dataclient.io/rest/api/createResource#members)
76
+ // GET https://jsonplaceholder.typicode.com/todos?userId=1
77
+ const userOneTodos = await TodoResource.getList({ userId: 1 });
50
78
 
51
- #### Reads
79
+ // POST https://jsonplaceholder.typicode.com/todos
80
+ const newTodo = await TodoResource.getList.push({ title: 'my todo' });
52
81
 
53
- ```typescript
54
- const article = useSuspense(ArticleResource.get, { id: 5 });
55
- const articles = useSuspense(ArticleResource.getList);
56
- ```
82
+ // POST https://jsonplaceholder.typicode.com/todos?userId=1
83
+ const newUserOneTodo = await TodoResource.getList.push({ userId: 1 }, { title: 'my todo' });
57
84
 
58
- ```typescript
59
- const [article, setArticle] = useState();
60
- useEffect(() => {
61
- setArticle(await ArticleResource.get({ id: 5 }));
62
- }, []);
85
+ // GET https://jsonplaceholder.typicode.com/todos?userId=1&page=2
86
+ const nextPageOfTodos = await TodoResource.getList.getPage({ userId: 1, page: 2 });
87
+
88
+ // PUT https://jsonplaceholder.typicode.com/todos/5
89
+ todo5 = await TodoResource.update({ id: 5 }, { title: 'my todo' });
90
+
91
+ // PATCH https://jsonplaceholder.typicode.com/todos/5
92
+ todo5 = await TodoResource.partialUpdate({ id: 5 }, { title: 'my todo' });
93
+
94
+ // DELETE https://jsonplaceholder.typicode.com/todos/5
95
+ await TodoResource.delete({ id: 5 });
63
96
  ```
64
97
 
65
- #### Mutates
98
+ ## Free React Integration
99
+
100
+ No need for any custom hooks. All endpoints are 100% compatible with [Reactive Data Client](https://dataclient.io)
101
+
102
+ ### [Rendering](https://dataclient.io/docs/getting-started/data-dependency)
66
103
 
67
104
  ```typescript
68
- const ctrl = useController();
69
- const updateArticle = data => ctrl.fetch(ArticleResource.update, { id }, data);
70
- const partialUpdateArticle = data =>
71
- ctrl.fetch(ArticleResource.partialUpdate, { id }, data);
72
- const createArticle = data => ctrl.fetch(ArticleResource.getList.push, data);
73
- const deleteArticle = data => ctrl.fetch(ArticleResource.delete, { id });
105
+ const todo = useSuspense(TodoResource.get, { id: 5 });
106
+ const todoList = useSuspense(TodoResource.getList);
74
107
  ```
75
108
 
76
- ### Use with Node
109
+ ### [Mutations](https://dataclient.io/docs/getting-started/mutations)
77
110
 
78
111
  ```typescript
79
- const article = await ArticleResource.get({ id: 5 });
80
- const articles = await ArticleResource.getList();
112
+ const ctrl = useController();
113
+ const updateTodo = data => ctrl.fetch(TodoResource.update, { id }, data);
114
+ const partialUpdateTodo= data =>
115
+ ctrl.fetch(TodoResource.partialUpdate, { id }, data);
116
+ const addTodoToEnd = data => ctrl.fetch(TodoResource.getList.push, data);
117
+ const addTodoToBeginning = data => ctrl.fetch(TodoResource.getList.unshift, data);
118
+ const deleteTodo = data => ctrl.fetch(TodoResource.delete, { id });
81
119
  ```
82
120
 
83
121
  ### [Programmatic queries](https://dataclient.io/rest/api/Query)
84
122
 
85
123
  ```tsx
86
- const sortedArticles = new Query(
87
- new schema.All(Article),
88
- (entries, { asc } = { asc: false }) => {
89
- const sorted = [...entries].sort((a, b) => a.title.localeCompare(b.title));
90
- if (asc) return sorted;
91
- return sorted.reverse();
92
- },
124
+ const queryRemainingTodos = new Query(
125
+ TodoResource.getList,
126
+ (entries) => entries.filter((todo) => !todo.completed).length,
93
127
  );
94
128
 
95
- const articlesUnsorted = useCache(sortedArticles);
96
- const articlesAscending = useCache(sortedArticles, { asc: true });
97
- const articlesDescending = useCache(sortedArticles, { asc: false });
129
+ const allRemainingTodos = useCache(queryRemainingTodos);
130
+ const firstUserRemainingTodos = useCache(queryRemainingTodos, { userId: 1 });
98
131
  ```
99
132
 
100
133
  ### TypeScript requirements
@@ -102,8 +135,6 @@ const articlesDescending = useCache(sortedArticles, { asc: false });
102
135
  TypeScript is optional, but will only work with 4.0 or above. 4.1 is needed for stronger types as it
103
136
  supports inferring argument types from the path templates.
104
137
 
105
- Version 5.x can be used for older TypeScript versions.
106
-
107
138
  ### Prior Art
108
139
 
109
140
  - [Backbone Model](https://backbonejs.org/#Model)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@data-client/rest",
3
- "version": "0.9.4",
3
+ "version": "0.9.5",
4
4
  "description": "Endpoints for REST APIs",
5
5
  "homepage": "https://dataclient.io/rest",
6
6
  "repository": {