Skip to content

Commit f8ba6d1

Browse files
committed
internal: Update copilot rest instructions
1 parent 8616156 commit f8ba6d1

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

.github/instructions/rest.instructions.md

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ to represent the data expected.
1717

1818
- `Entity` - represents a single unique object (denormalized)
1919
- `schema.Union(Entity)` - polymorphic objects (A | B)
20-
- `{[key:string]: Schema}` - immutable objects (lacking primary key)
20+
- `{[key:string]: Schema}` - immutable objects
2121
- `schema.Invalidate(Entity)` - to delete an Entity
2222

2323
### List
@@ -42,7 +42,6 @@ to represent the data expected.
4242
- Every `Entity` subclass **defines defaults** for _all_ non-optional serialised fields.
4343
- Override `pk()` only when the primary key ≠ `id`.
4444
- `pk()` return type is `number | string | undefined`
45-
- if `pk()` cannot be determined, use `{[key:string]: Schema}` schema instead
4645
- Always define nested Entities to be used in `static schema`
4746
- When designing APIs, prefer nesting entities
4847
- use `static schema` to deserialize
@@ -75,7 +74,6 @@ export class Todo extends Entity {
7574
completed = false;
7675

7776
static key = 'Todo';
78-
// optional
7977
static schema = {
8078
user: User,
8179
}
@@ -102,6 +100,11 @@ const todo = useSuspense(TodoResource.get, { id: 5 });
102100
const todoList = useSuspense(TodoResource.getList);
103101
// GET https://jsonplaceholder.typicode.com/todos?userId=1
104102
const todoListByUser = useSuspense(TodoResource.getList, { userId: 1 });
103+
// subscriptions
104+
const todo = useLive(TodoResource.get, { id: 5 });
105+
// without fetch
106+
const todo = useCache(TodoResource.get, { id: 5 });
107+
const todo = useQuery(Todo, { id: 5 });
105108
```
106109

107110
#### Mutations
@@ -124,24 +127,30 @@ const deleteTodo = id => ctrl.fetch(TodoResource.delete, { id });
124127
const getNextPage = (page) => ctrl.fetch(TodoResource.getList.getPage, { userId: 1, page })
125128
```
126129

130+
#### Type-safe imperative actions
131+
132+
`Controller` is returned from `useController()`. It has: ctrl.fetch(), ctrl.fetchIfStale(), ctrl.expireAll(), ctrl.invalidate(), ctrl.invalidateAll(), ctrl.setResponse(), ctrl.set().
133+
127134
#### Programmatic queries
128135

129136
```ts
130137
const queryRemainingTodos = new schema.Query(
131138
TodoResource.getList.schema,
132139
entries => entries.filter(todo => !todo.completed).length,
133140
);
141+
142+
const allRemainingTodos = useQuery(queryRemainingTodos);
143+
const firstUserRemainingTodos = useQuery(queryRemainingTodos, { userId: 1 });
134144
```
135145

136146
```ts
137147
const groupTodoByUser = new schema.Query(
138148
TodoResource.getList.schema,
139149
todos => Object.groupBy(todos, todo => todo.userId),
140150
);
151+
const todosByUser = useQuery(groupTodoByUser);
141152
```
142153

143-
For more detailed usage, refer to the [@data-client/react guide](.github/instructions/react.instructions.md).
144-
145154
---
146155

147156
## 4. Custom RestEndpoint patterns
@@ -160,6 +169,7 @@ export const getTicker = new RestEndpoint({
160169
- `path` params ▶️ 1st arg shape.
161170
- `method` ≠ `GET` ⇒ 2nd arg = body (unless `body: undefined`).
162171
- Provide `searchParams` / `body` _values_ purely for **type inference**.
172+
- Use `RestGenerics` when inheriting from `RestEndpoint`.
163173

164174
### getOptimisticResponse()
165175

@@ -224,9 +234,13 @@ export const IssueResource = resource({
224234

225235
## 8. Best Practices & Notes
226236

237+
- When asked to browse or navigate to a web address, actual visit the address
227238
- Always set up `schema` on every resource/entity/collection for normalization.
228239
- Prefer `RestEndpoint` over `resource` for defining single endpoints or when full CRUD endpoints don't exist
229240
- Normalize deeply nested or relational data by defining proper schemas.
241+
- `useDebounce(query, timeout);` when rendering async data based on user field inputs
242+
- `[handleSubmit, loading, error] = useLoading()` when tracking mutation loads like submitting an async form
243+
- Prefer smaller React components that do one thing.
230244

231245
## 9. Common Mistakes to Avoid
232246

0 commit comments

Comments
 (0)