Skip to main content

data-client-rest

Define how the app talks to its API with @data-client/rest, including the shape of the data each call returns. Use it when adding or changing any API call or its data, changing how requests are sent or responses are read, or deciding how fetched data is stored, updated and kept fresh. Covers resource, RestEndpoint and pagination.

ソース情報

リポジトリ
reactive/data-client
ソースの最終更新活動
2026年10月29日 04:46
検出された SKILL.md の言語
英語
スター
2,039
フォーク
98

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

ファイルエクスプローラー
42 ファイル

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
data-client-rest
description
Define how the app talks to its API with @data-client/rest, including the shape of the data each call returns. Use it when adding or changing any API call or its data, changing how requests are sent or responses are read, or deciding how fetched data is stored, updated and kept fresh. Covers resource, RestEndpoint and pagination.
license
Apache 2.0
# Guide: Using `@data-client/rest` for Resource Modeling This project uses [@data-client/rest](https://dataclient.io/rest) to define, fetch, normalize, and update RESTful resources and entities in React/TypeScript apps with type safety and automatic cache management. **Always follow these patterns when generating code that interacts with remote APIs.** --- ## 1. Defining Schemas Every `resource()` and `RestEndpoint` takes a `schema` that normalizes its response into the shared cache. Apply the skill "data-client-schema" before defining or changing one: Entity, Collection, Union and Query patterns and references live there, not here. ## 2. Resources (`resource()`) - [resource()](references/resource.md) creates a collection of [RestEndpoints](references/RestEndpoint.md) for CRUD operations on a common object - Required fields: - `path`: path‑to‑regexp template (typed!) - `schema`: Declarative data shape for a **single** item (typically Entity or Union) - Optional: - `urlPrefix`: Host root, if not `/` - `searchParams`: Type for query parameters (TS generic) in MyResource.getList - `paginationField`: Add MyResource.getList.getPage for pagination - `optimistic`: Boolean, when true all mutations will update optimistically, improving performance - `body`: Type for body parameter to MyResource.getList.push, MyResource.getList.unshift, MyResource.update, MyResource.partialUpdate ```ts import { Entity, resource } from '@data-client/rest'; import { User } from './User'; export class Todo extends Entity { id = 0; user = User.fromJS(); title = ''; completed = false; createdAt = new Date(); static key = 'Todo'; static schema = { user: User, createdAt: (iso: string) => new Date(iso), } } export const TodoResource = resource({ urlPrefix: 'https://jsonplaceholder.typicode.com', path: '/todos/:id', schema: Todo, searchParams: {} as { userId?: string | number } | undefined, paginationField: 'page', nonFilterArgumentKeys: ['orderBy'], optimistic: true, }); ``` ### Usage #### [Rendering](references/data-dependency.md) ```ts // GET https://jsonplaceholder.typicode.com/todos/5 const todo = useSuspense(TodoResource.get, { id: 5 }); // GET https://jsonplaceholder.typicode.com/todos const todoList = useSuspense(TodoResource.getList); // GET https://jsonplaceholder.typicode.com/todos?userId=1 const todoListByUser = useSuspense(TodoResource.getList, { userId: 1 }); ``` #### [Mutations](references/mutations.md) ```ts const ctrl = useController(); // PUT https://jsonplaceholder.typicode.com/todos/5 const updateTodo = todo => ctrl.fetch(TodoResource.update, { id }, todo); // PATCH https://jsonplaceholder.typicode.com/todos/5 const partialUpdateTodo = todo => ctrl.fetch(TodoResource.partialUpdate, { id }, todo); // POST https://jsonplaceholder.typicode.com/todos const addTodoToStart = todo => ctrl.fetch(TodoResource.getList.unshift, todo); // POST https://jsonplaceholder.typicode.com/todos?userId=1 const addTodoToEnd = todo => ctrl.fetch(TodoResource.getList.push, { userId: 1 }, todo); // PATCH https://jsonplaceholder.typicode.com/todos/5 const toggleStatus = (completed: boolean) => ctrl.fetch(TodoResource.getList.move, { id }, { completed }); // DELETE https://jsonplaceholder.typicode.com/todos/5 const deleteTodo = id => ctrl.fetch(TodoResource.delete, { id }); // GET https://jsonplaceholder.typicode.com/todos?userId=1&page=2 const getNextPage = (page) => ctrl.fetch(TodoResource.getList.getPage, { userId: 1, page }) ``` For more detailed usage, apply the skill "data-client-react" or "data-client-vue". --- ## 3. Custom [RestEndpoint](references/RestEndpoint.md) patterns ```ts /** Stand‑alone endpoint with custom typing */ export const getTicker = new RestEndpoint({ urlPrefix: 'https://api.exchange.coinbase.com', path: '/products/:product_id/ticker', schema: Ticker, pollFrequency: 2000, }); ``` `pollFrequency` polls only while subscribed (`useLive`/`useSubscription`). Subscribers to the same endpoint and args share one poll at the fastest frequency, so a faster `.extend({ pollFrequency })` on one view speeds up the others too. **Typing tips** - `path` path‑to‑regexp template for 1st arg - `method` ≠ `GET` ⇒ 2nd arg = body (unless `body: undefined`) - Provide `searchParams` / `body` _values_ purely for **type inference** - Use `RestGenerics` when inheriting from `RestEndpoint` ### `getOptimisticResponse()` ```ts getOptimisticResponse(snap, { id }) { const article = snap.get(Article, { id }); if (!article) throw snap.abort; return { id, votes: article.votes + 1, }; } ``` --- ### RestEndpoint lifecycle overrides `fetch()` runs `fetchResponse(url(), getRequestInit())` → `parseResponse()` → `process()`. Override the step that owns the change, never `fetch` itself (that replaces the whole lifecycle): | To change | Override | |---|---| | Headers (auth) | `getHeaders(headers)` | | Other request options or body encoding | `getRequestInit(body)` | | Query string format | `searchToString(searchParams)` | | The network call (retries, another client) | `fetchResponse(input, init)` | | Non-JSON responses | `content` option (`'blob'`, `'text'`, …), else `parseResponse(response)` | | Shape of the parsed data | `process(value, ...args)` | --- ## 4. **Extending Resources** Use `.extend()` to add or override endpoints. ```typescript export const IssueResource = resource({ // ...base config... }).extend((Base) => ({ search: Base.getList.extend({ path: '/search/issues', // ...custom schema or params... }), })); ``` --- ## 5. Best Practices & Notes - When asked to browse or navigate to a web address, actual visit the address - Prefer `RestEndpoint` over `resource()` for defining single endpoints or when mutation endpoints don't exist - For blob/file downloads and other non-JSON responses, see [network-transform: file download](references/network-transform.md#file-download). ## 6. Common Mistakes to Avoid - Don't use `resource()` when mutation endpoints are not used or needed # References Vue projects: read `<name>.vue.md` instead of `<name>.md` when it exists. For detailed API documentation, see the [references](references/) directory: - [resource](references/resource.md) - Create CRUD endpoints - [RestEndpoint](references/RestEndpoint.md);[_EndpointLifecycle.md](references/_EndpointLifecycle.md);[RestEndpoint.js](references/RestEndpoint.js) - Single REST endpoint - Entity, Collection and other schemas: skill "data-client-schema" - [Fixtures](references/Fixtures.md) - Mock data for testing - [data-dependency](references/data-dependency.md);[_useLive.md](references/_useLive.md);[_AsyncBoundary.md](references/_AsyncBoundary.md) - Rendering guide - [mutations](references/mutations.md);[_useLoading.md](references/_useLoading.md);[_VoteDemo.md](references/_VoteDemo.md) - Mutations guide **Guides** (refer when user asks about these topics): - [auth](references/auth.md) - Authentication headers, tokens, login/logout flows - [pagination](references/pagination.md);[_pagination.md](references/_pagination.md) - Cursor/offset pagination, infinite scroll - [optimistic-updates](references/optimistic-updates.md);[_optimisticTransform.md](references/_optimisticTransform.md) - Instant UI feedback before server response - [network-transform](references/network-transform.md) - Transform responses, handle non-standard APIs **Concepts** (refer when user asks about these topics): - [expiry-policy](references/expiry-policy.md) - Cache invalidation, stale data, dataExpiryLength, errorExpiryLength - [error-policy](references/error-policy.md) - Error handling, retry behavior, soft vs hard errors **ALWAYS follow these patterns and refer to the official docs for edge cases. Prioritize code generation that is idiomatic, type-safe, and leverages automatic normalization/caching via schema definitions.**
GitHubで見る