home / skills / langgenius / dify / orpc-contract-first
This skill guides implementing oRPC contract-first API patterns in the Dify frontend, from contract creation to router registration and typed service hooks.
npx playbooks add skill langgenius/dify --skill orpc-contract-firstReview the files below or copy the command above to add this skill to your agents.
---
name: orpc-contract-first
description: Guide for implementing oRPC contract-first API patterns in Dify frontend. Triggers when creating new API contracts, adding service endpoints, integrating TanStack Query with typed contracts, or migrating legacy service calls to oRPC. Use for all API layer work in web/contract and web/service directories.
---
# oRPC Contract-First Development
## Project Structure
```
web/contract/
├── base.ts # Base contract (inputStructure: 'detailed')
├── router.ts # Router composition & type exports
├── marketplace.ts # Marketplace contracts
└── console/ # Console contracts by domain
├── system.ts
└── billing.ts
```
## Workflow
1. **Create contract** in `web/contract/console/{domain}.ts`
- Import `base` from `../base` and `type` from `@orpc/contract`
- Define route with `path`, `method`, `input`, `output`
2. **Register in router** at `web/contract/router.ts`
- Import directly from domain file (no barrel files)
- Nest by API prefix: `billing: { invoices, bindPartnerStack }`
3. **Create hooks** in `web/service/use-{domain}.ts`
- Use `consoleQuery.{group}.{contract}.queryKey()` for query keys
- Use `consoleClient.{group}.{contract}()` for API calls
## Key Rules
- **Input structure**: Always use `{ params, query?, body? }` format
- **Path params**: Use `{paramName}` in path, match in `params` object
- **Router nesting**: Group by API prefix (e.g., `/billing/*` → `billing: {}`)
- **No barrel files**: Import directly from specific files
- **Types**: Import from `@/types/`, use `type<T>()` helper
## Type Export
```typescript
export type ConsoleInputs = InferContractRouterInputs<typeof consoleRouterContract>
```
This skill guides contract-first oRPC API development for the Dify frontend, focused on the web/contract and web/service layers. It codifies where to add new contracts, how to register them in the router, and how to create typed service hooks. The goal is consistent, typed API surface and smooth migration of legacy calls to oRPC patterns.
The skill inspects project layout and enforces adding contracts under web/contract/console/{domain}.ts using the base contract and @orpc/contract types. It ensures routes declare path, method, and structured inputs (params, query?, body?) and that each domain contract is registered in web/contract/router.ts without barrel imports. For client usage it expects hooks in web/service/use-{domain}.ts that rely on consoleQuery.{group}.{contract}.queryKey() and consoleClient.{group}.{contract}() for typed calls.
Can I use barrel files to import contracts?
No. Import contracts directly from their domain files to keep tree-shaking predictable and avoid circular dependency issues.
How should path parameters be declared?
Use {paramName} in the path and include the same key in the params object of the input structure for proper typing.