Skip to main content
data-client-rest Define REST APIs with @data-client/rest - resource(), RestEndpoint, CRUD (GET/POST/PUT/PATCH/DELETE), HTTP fetch, normalize, cache, urlPrefix, path-to-regexp parameters, searchParams, pagination, extend(), auth/headers, optimistic updates, polling, file download, blob, parseResponse. Use when defining or modifying network endpoints, REST resources, or the HTTP layer.
跳到安装 Skills Marketplace 发现并探索由社区构建的 Agent Skills
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/reactive/data-client --skill data-client-rest命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
下载 Zip 下载中... 同仓库更多 Skills Cost-and-speed-optimized development workflow for a cheap fast implementing model consulting expensive advisor subagents (design-advisor, principal-advisor, quality-reviewer). Use for design-bearing or high-risk implementation - new/changed public contracts, schemas, state/lifecycle, concurrency, security, persistence, compatibility - or after repeated failed attempts. Do not invoke for trivial edits or solely because a change touches multiple files.
Use @data-client/react hooks for data fetching, mutations, and rendering - useSuspense, useFetch, useQuery, useCache, useLive, useDLE, useSubscription, useController, DataProvider, AsyncBoundary, useLoading, useDebounce. Use when reading/rendering remote data, triggering mutations, doing optimistic updates, real-time subscriptions, or wiring Suspense/error boundaries in React.
Model data with @data-client schemas (Entity, EntityMixin, Collection, Union, Query, Values, All, Invalidate, Lazy, Scalar) for atomic, consistent, referentially-equal async data via normalization, identity-based caching, and a single source of truth. Use when defining or editing pk, static schema, resource()/RestEndpoint schema, mutable lists/maps (push/unshift/assign/remove/move), polymorphic/discriminated types, memoized selectors / derived data, partial/supplementary entities, relational/nested/joined data, optimistic updates, or cache invalidation across @data-client/rest, /endpoint, /graphql, or /normalizr. Apply proactively when discussing data models, remote data shape, caching, normalization, identity, joins, polymorphism, mutable collections, or store consistency.
name data-client-rest description Define REST APIs with @data-client/rest - resource(), RestEndpoint, CRUD (GET/POST/PUT/PATCH/DELETE), HTTP fetch, normalize, cache, urlPrefix, path-to-regexp parameters, searchParams, pagination, extend(), auth/headers, optimistic updates, polling, file download, blob, parseResponse. Use when defining or modifying network endpoints, REST resources, or the HTTP layer. license Apache 2.0
Guide: Using @data-client/rest for Resource Modeling
This project uses @data-client/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
This project uses schemas to define and normalize data models with type safety and automatic cache management. Apply the skill "data-client-schema" for schema patterns.
Always follow these patterns (apply the skill "data-client-schema") when generating mutable data definitions.
2. Resources (resource())
resource() creates a collection of RestEndpoints 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.partialUpdateimport { 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
const todo = useSuspense (TodoResource .get , { id : 5 });
const todoList = useSuspense (TodoResource .getList );
const todoListByUser = useSuspense (TodoResource .getList , { userId : 1 });
const ctrl = useController ();
const updateTodo = todo => ctrl.fetch (TodoResource .update , { id }, todo);
const partialUpdateTodo = todo =>
ctrl.fetch (TodoResource .partialUpdate , { id }, todo);
const addTodoToStart = todo =>
ctrl.fetch (TodoResource .getList .unshift , todo);
const addTodoToEnd = todo => ctrl.fetch (TodoResource .getList .push , { userId : 1 }, todo);
const toggleStatus = (completed : boolean ) => ctrl.fetch (TodoResource .getList .move , { id }, { completed });
const deleteTodo = id => ctrl.fetch (TodoResource .delete , { id });
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".
export const getTicker = new RestEndpoint ({
urlPrefix : 'https://api.exchange.coinbase.com' ,
path : '/products/:product_id/ticker' ,
schema : Ticker ,
pollFrequency : 2000 ,
});
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()getOptimisticResponse (snap, { id } ) {
const article = snap.get (Article , { id });
if (!article) throw snap.abort ;
return {
id,
votes : article.votes + 1 ,
};
}
RestEndpoint lifecycle methods
Perform Fetch: fetchResponse() → parseResponse() → process()
url(urlParams): urlPrefix + path + (searchParams → searchToString())
getRequestInit(body): getHeaders() + method + signal
4. Extending Resources Use .extend() to add or override endpoints.
export const IssueResource = resource ({
}).extend ((Base ) => ({
search : Base .getList .extend ({
path : '/search/issues' ,
}),
}));
5. Best Practices & Notes
When asked to browse or navigate to a web address, actual visit the address
Always set up schema on every resource/entity/collection for normalization
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 .
6. Common Mistakes to Avoid
Don't use resource() when mutation endpoints are not used or needed
References For detailed API documentation, see the references directory:
Guides (refer when user asks about these topics):
Concepts (refer when user asks about these topics):
expiry-policy - Cache invalidation, stale data, dataExpiryLength, errorExpiryLength
error-policy - 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.