orpc-implementation-sops

Use when building, updating, or refactoring oRPC contracts, server handlers, clients, or React Query integration

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "orpc-implementation-sops" with this command: npx skills add wenerme/ai/wenerme-ai-orpc-implementation-sops

oRPC Implementation SOPs

You are an expert TypeScript backend and frontend engineer. When implementing oRPC, you MUST strictly follow this Contract-First development pattern and the guardrails below.

1. Contract Definition (API First)

CRITICAL RULE: API paths and resource names MUST ALWAYS use singular form (e.g., /api/user, NEVER /api/users). Nested contract keys MUST also be singular (e.g., user: UserContract, NEVER users: UserContract).

import { oc, type } from '@orpc/contract';
import { z } from 'zod';
import { ResourceSchema, ListQueryInputSchema, createListResponse } from 'common/contract';

// MUST define Entity Schema FIRST
export const UserSchema = ResourceSchema.extend({
  name: z.string().describe('用户名'),
  email: z.string().email().describe('邮箱'),
});

// Then define Contract
export const UserContract = {
  list: oc
    .input(ListQueryInputSchema)
    .output(createListResponse(UserSchema))
    .route({ method: 'GET', path: '/api/user' }),

  get: oc
    .input(type<{}>())
    .output(UserSchema)
    .route({ method: 'GET', path: '/api/user/:id' }),

  create: oc
    .input(z.object({ name: z.string(), email: z.string().email() }))
    .output(UserSchema)
    .route({ method: 'POST', path: '/api/user' }),
};

// Nested Contract — singular keys
export const AppContract = {
  user: UserContract,
  health: oc.output(z.object({ ok: z.boolean() })).route({ method: 'GET', path: '/health' }),
};

2. Server Implementation

Errors MUST be thrown using ORPCError with standard codes.

import { implement, ORPCError } from '@orpc/server';
import { handleRPCContract } from 'common/orpc/server';

export function createUserContractImpl() {
  const os = implement(UserContract);
  return {
    list: os.list.handler(async ({ input }) => {
      const data = await db.user.findMany({ take: input.limit ?? 20 });
      return { total: data.length, data };
    }),
    get: os.get.handler(async ({ input }) => {
      const user = await db.user.findUnique({ where: { id: input.id } });
      if (!user) throw new ORPCError('NOT_FOUND', { message: 'User not found' });
      return user;
    }),
  };
}

3. Client & React Query Integration

import { createRpcContractClient } from 'common/orpc';
import { createORPCReactQueryUtils } from '@orpc/react-query';

const client = createRpcContractClient<typeof AppContract>({
  baseUrl: 'http://localhost:3000',
  getApiKey: () => getAccessToken(),
});

export const orpc = createORPCReactQueryUtils(client);

// Usage in React Component
const { data } = useQuery(orpc.user.list.queryOptions({ input: { limit: 20 } }));

4. Schema & Error Handling Constraints

When generating or modifying Zod schemas and errors, you MUST adhere to these rules:

  • Documentation: MUST append .describe('...') to string fields for frontend tooltip generation.
  • Dates: MUST use z.coerce.date() to handle automatic type coercion from strings.
  • Optionality: MUST use .nullish() over .optional() or .nullable() for broader compatibility unless strictly specified.
  • Bypassing Validation: Use oc.output(type<ComplexType>()) only when standard Zod validation is too heavy.
  • File Uploads: MUST use z.instanceof(File) for Blob/File typing.
  • Type Export: MUST export inferred types: export type User = z.infer<typeof UserSchema>;
  • Error Codes: MUST use standard HTTP-mapped codes only: NOT_FOUND, BAD_REQUEST, UNAUTHORIZED, FORBIDDEN, CONFLICT, INTERNAL_SERVER_ERROR.

5. Protocol Selection

FeatureRPC (/api/rpc)OpenAPI (/api)
RoutingSingle endpointRESTful
BatchYesYes
OpenAPINoYes
PerfHigherStandard

Rule: Frontend uses RPC protocol. External/third-party API uses OpenAPI protocol.

6. Advanced Patterns

For complex operations such as modeling external REST APIs, Hono integration, File/Blob uploads, SSE/Streaming, or AsyncIterator conversion, DO NOT guess. You MUST read the detailed reference first: references/orpc-pattern.md

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

glab-cli

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

chrome-devtools

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

argocd-cli-guide

No summary provided by upstream source.

Repository SourceNeeds Review