Hybrid Architecture
Use this architecture when you have both TypeScript and non-TypeScript clients.
When to Choose Hybrid
Section titled “When to Choose Hybrid”- Mobile apps (REST) + web dashboard (tRPC)
- Public API (REST) + internal tools (tRPC)
- Gradual migration from REST to tRPC
- Different teams with different needs
How It Works
Section titled “How It Works”VeloxTS generates both REST and tRPC endpoints from the same procedures:
export const orderProcedures = procedures('orders', { // Available as: // - REST: GET /api/orders // - tRPC: trpc.orders.listOrders.query() listOrders: procedure() .output(z.array(OrderSchema)) .query(({ ctx }) => ctx.db.order.findMany()),});Client Examples
Section titled “Client Examples”Mobile App (REST)
Section titled “Mobile App (REST)”// iOS Swiftlet url = URL(string: "http://api.example.com/api/orders")!let (data, _) = try await URLSession.shared.data(from: url)let orders = try JSONDecoder().decode([Order].self, from: data)Web Dashboard (tRPC)
Section titled “Web Dashboard (tRPC)”// React with tRPCconst { data: orders } = trpc.orders.listOrders.useQuery();Third-Party Integration (REST)
Section titled “Third-Party Integration (REST)”curl https://api.example.com/api/orders \ -H "Authorization: Bearer ${API_KEY}"Selective Exposure
Section titled “Selective Exposure”You can expose different procedures to different transports:
// Internal only - tRPCexport const internalProcedures = procedures('internal', { getMetrics: procedure() .query(...) .rest(false), // Disable REST});
// Public only - RESTexport const publicProcedures = procedures('public', { getStatus: procedure() .query(...) // REST enabled by default});Authentication Across Transports
Section titled “Authentication Across Transports”The same guards work for both:
const getOrder = procedure() .guard(authenticated) .input(z.object({ id: z.string() })) .query(...)
// REST: Authorization header// tRPC: Same header or cookieAPI Versioning
Section titled “API Versioning”For REST clients that need versioning:
export const v1Procedures = procedures('v1/orders', { listOrders: procedure()...});
export const v2Procedures = procedures('v2/orders', { listOrders: procedure()... // New shape});Next Steps
Section titled “Next Steps”- REST Conventions - REST patterns
- tRPC Adapter - tRPC configuration
- OpenAPI - API documentation