Server
Contract-first
Describe procedures in a contract, implement them later, and type clients from the contract alone.
On this page
A contract describes procedures without implementing them. It lives in its own package, and clients and the OpenAPI generator accept it like a router.
import { contract } from '@trpc12/trpc/contract';
const c = contract.create<{ meta: Meta }>().errors({ UNAUTHORIZED: {} });
export const appContract = {
post: {
byId: c.input(ById).output(Post).errors({ NOT_FOUND: {} }).query(),
create: c.meta({ auth: true }).input(NewPost).output(Post).mutation(),
},
};Implementing a contract
t.implement(contract) mirrors the contract. Each leaf already has its input, output, errors and route, and offers only .use(), .provide() and the terminal the contract declares. impl.router() checks at the type level and at runtime that every procedure is implemented and nothing else is added.
const impl = t.implement(appContract).use(authed).provide(Db, () => db);
export const appRouter = impl.router({
post: {
byId: impl.post.byId.query(({ input, errors }) => /* … */),
create: impl.post.create.mutation(({ input }) => /* … */),
},
});- An implementation may only return errors its contract declares. Middleware passed to
impl.use()orimpl.provide()runs for every procedure, so all of them must declare its errors. - The contract's meta keys must exist in
t's meta with typestaccepts, because middleware reads them ast's meta. - Top-level contract keys named
router,useorprovidewould shadow the implementer's methods, sot.implement()throws on them.
Clients from a contract
A client takes the contract as its router, so the browser imports no server code and can validate calls against the contract's schemas:
const client = createTrpcClient({
router: appContract,
links: [validationLink({ contract: appContract }), httpLink({ url })],
});From a router or a document
toContract(router) derives the contract of an existing router, for the OpenAPI handler and build steps (Lazy subtrees). To start from an OpenAPI document instead, see A contract from OpenAPI.