docyrus-app-dev
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDocyrus App Developer
Docyrus应用开发者
Build React TypeScript web apps with Docyrus as the backend. Authenticate via OAuth2 PKCE, query data sources with powerful filtering/aggregation, and follow established patterns.
使用Docyrus作为后端构建React TypeScript Web应用。通过OAuth2 PKCE进行身份验证,借助强大的筛选/聚合功能查询数据源,并遵循既定开发模式。
Tech Stack
技术栈
- React 19 + TypeScript + Vite
- TanStack Router (code-based), TanStack Query (server state)
- Tailwind CSS v4, shadcn/ui components
- (REST client) +
@docyrus/api-client(auth provider)@docyrus/signin - Auto-generated collections from OpenAPI spec
- React 19 + TypeScript + Vite
- TanStack Router(基于代码)、TanStack Query(服务端状态管理)
- Tailwind CSS v4、shadcn/ui组件
- (REST客户端)+
@docyrus/api-client(身份验证提供者)@docyrus/signin - 从OpenAPI规范自动生成的集合
Quick Start: New App Setup
快速开始:新应用搭建
- Wrap root with :
DocyrusAuthProvider
tsx
import { DocyrusAuthProvider } from '@docyrus/signin'
<DocyrusAuthProvider
apiUrl={import.meta.env.VITE_API_BASE_URL}
clientId={import.meta.env.VITE_OAUTH2_CLIENT_ID}
redirectUri={import.meta.env.VITE_OAUTH2_REDIRECT_URI}
scopes={['offline_access', 'Read.All', 'DS.ReadWrite.All', 'Users.Read']}
callbackPath="/auth/callback"
>
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
</QueryClientProvider>
</DocyrusAuthProvider>- In App.tsx, sync API client for collections:
tsx
const { status } = useDocyrusAuth()
const client = useDocyrusClient()
useEffect(() => {
if (client) setApiClient(client)
}, [client])
if (status === 'loading') return <Spinner />
if (status === 'unauthenticated') return <SignInButton />- Use collections in hooks:
tsx
const { data: projects } = useQuery({
queryKey: ['projects'],
queryFn: () => baseProjectCollection.list({
columns: ['name', 'status', 'record_owner(firstname,lastname)'],
filters: { rules: [{ field: 'status', operator: '!=', value: 'archived' }] },
orderBy: 'created_on DESC',
limit: 50,
}),
})- 用包裹根组件:
DocyrusAuthProvider
tsx
import { DocyrusAuthProvider } from '@docyrus/signin'
<DocyrusAuthProvider
apiUrl={import.meta.env.VITE_API_BASE_URL}
clientId={import.meta.env.VITE_OAUTH2_CLIENT_ID}
redirectUri={import.meta.env.VITE_OAUTH2_REDIRECT_URI}
scopes={['offline_access', 'Read.All', 'DS.ReadWrite.All', 'Users.Read']}
callbackPath="/auth/callback"
>
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
</QueryClientProvider>
</DocyrusAuthProvider>- 在App.tsx中,同步API客户端以使用集合:
tsx
const { status } = useDocyrusAuth()
const client = useDocyrusClient()
useEffect(() => {
if (client) setApiClient(client)
}, [client])
if (status === 'loading') return <Spinner />
if (status === 'unauthenticated') return <SignInButton />- 在钩子中使用集合:
tsx
const { data: projects } = useQuery({
queryKey: ['projects'],
queryFn: () => baseProjectCollection.list({
columns: ['name', 'status', 'record_owner(firstname,lastname)'],
filters: { rules: [{ field: 'status', operator: '!=', value: 'archived' }] },
orderBy: 'created_on DESC',
limit: 50,
}),
})Critical Rules
重要规则
- Always send in
columnsand.list()calls. Without it, only.get()is returned.id - Collections only work after auth — must be called first.
setApiClient(client) - Data source endpoints are dynamic — they only exist if the data source is defined in the tenant's OpenAPI spec.
- Use field for
idcalculations. Use the actual field slug forcount,sum,avg,min.max - Child query keys must appear in — e.g., if childQuery key is
columns, includeordersin the columns array.'orders' - Formula keys must appear in — e.g., if formula key is
columns, includetotalin the columns array.'total' - Use for current user profile, not a direct API call.
UsersCollection.getMyInfo()
- 在和
.list()调用中务必传入.get()。如果不传入,将只返回columns字段。id - 集合仅在身份验证后可用 — 必须先调用。
setApiClient(client) - 数据源端点是动态的 — 仅当数据源在租户的OpenAPI规范中定义时才存在。
- 使用字段进行
id计算。count、sum、avg、min请使用实际字段别名。max - 子查询键必须出现在中 — 例如,如果子查询键为
columns,需在columns数组中包含orders。'orders' - 公式键必须出现在中 — 例如,如果公式键为
columns,需在columns数组中包含total。'total' - 使用获取当前用户信息,而非直接调用API。
UsersCollection.getMyInfo()
Collection CRUD Methods
集合CRUD方法
Every generated collection provides:
typescript
collection.list(params?: ICollectionListParams) // Query with filters, sort, pagination
collection.get(id, { columns }) // Single record
collection.create(data) // Create
collection.update(id, data) // Partial update
collection.delete(id) // Delete one
collection.deleteMany({ recordIds }) // Delete manyAPI endpoint pattern:
/v1/apps/{appSlug}/data-sources/{slug}/items每个生成的集合都提供以下方法:
typescript
collection.list(params?: ICollectionListParams) // 带筛选、排序、分页的查询
collection.get(id, { columns }) // 获取单条记录
collection.create(data) // 创建记录
collection.update(id, data) // 部分更新记录
collection.delete(id) // 删除单条记录
collection.deleteMany({ recordIds }) // 批量删除记录API端点模式:
/v1/apps/{appSlug}/data-sources/{slug}/itemsQuery Capabilities Summary
查询功能概述
The method supports:
.list()| Feature | Purpose |
|---|---|
| Select fields, expand relations |
| Nested AND/OR groups with 50+ operators (comparison, date shortcuts, user-related) |
| Full-text search |
| Sort by fields with direction, including related fields |
| Pagination (default 100) |
| Return total count alongside results |
| Aggregations: count, sum, avg, min, max with grouping |
| Computed virtual columns (simple functions, block AST, correlated subqueries) |
| Fetch related child records as nested JSON arrays |
| Cross-tab matrix queries with date range series |
| Return full objects for relation/user/enum fields instead of IDs |
For query details, read:
references/query-guide.md.list()| 功能 | 用途 |
|---|---|
| 选择字段、展开关联关系 |
| 支持嵌套AND/OR分组,包含50+种操作符(比较、日期快捷方式、用户相关操作符等) |
| 全文搜索 |
| 按字段及方向排序,包括关联字段 |
| 分页(默认每页100条) |
| 返回结果的同时返回总记录数 |
| 聚合操作:统计、求和、平均值、最小值、最大值,并支持分组 |
| 计算虚拟列(简单函数、块AST、关联子查询) |
| 获取关联的子记录并以嵌套JSON数组形式返回 |
| 带日期范围序列的交叉表矩阵查询 |
| 返回关联/用户/枚举字段的完整对象,而非仅ID |
查询详情请阅读:
references/query-guide.mdTanStack Query Pattern
TanStack Query 模式
typescript
// Query hook
function useItems(params?: ICollectionListParams) {
return useQuery({
queryKey: ['items', 'list', params],
queryFn: () => collection.list({ columns: COLUMNS, ...params }),
})
}
// Mutation hook
function useCreateItem() {
const qc = useQueryClient()
return useMutation({
mutationFn: (data: Record<string, unknown>) => collection.create(data),
onSuccess: () => { void qc.invalidateQueries({ queryKey: ['items'] }) },
})
}typescript
// 查询钩子
function useItems(params?: ICollectionListParams) {
return useQuery({
queryKey: ['items', 'list', params],
queryFn: () => collection.list({ columns: COLUMNS, ...params }),
})
}
// 变更钩子
function useCreateItem() {
const qc = useQueryClient()
return useMutation({
mutationFn: (data: Record<string, unknown>) => collection.create(data),
onSuccess: () => { void qc.invalidateQueries({ queryKey: ['items'] }) },
})
}References
参考资料
Read these files when you need detailed information:
- — RestApiClient API, @docyrus/signin hooks, auth provider config, interceptors, error handling, SSE/streaming, file upload/download
references/api-client-and-auth.md - — Full query payload reference: column syntax, all filter operators, aggregations, simple/block/subquery formulas, child queries, pivot tables, expand
references/query-guide.md - — Generated collection structure, UsersCollection, TanStack Query/mutation hook patterns, query key factories, app bootstrap flow, routing setup, API endpoints
references/collections-and-patterns.md
需要详细信息时请阅读以下文件:
- — RestApiClient API、@docyrus/signin钩子、身份验证提供者配置、拦截器、错误处理、SSE/流处理、文件上传/下载
references/api-client-and-auth.md - — 完整查询负载参考:列语法、所有筛选操作符、聚合、简单/块/子查询公式、子查询、透视表、展开字段
references/query-guide.md - — 生成的集合结构、UsersCollection、TanStack Query/变更钩子模式、查询键工厂、应用启动流程、路由设置、API端点
references/collections-and-patterns.md