Skip to content
rest-rpc
Esc
navigateopen⌘Jpreview
On this page

Quickstart

Define one contract, implement it on the server, and call it from a client.

This guide builds one todos.create route from a shared contract.

Install packages

Add the core package, a schema library, and the adapter for the server framework you want to use.

Define the contract

Declare the HTTP method, path, request body, and response body once in a file that both server and client code can import.

Implement the server route

Use the same route tree to write a typed handler for Express, Fastify, Hono, Next.js, or a fetch-native runtime.

Call it from the client

Create a typed fetch client or TanStack Query helpers from the same contract.

Install Packages

This guide uses Zod and Express by default. The same contract works with the other server tabs below.

pnpm add @rest-rpc/core @rest-rpc/express express zod
npm install @rest-rpc/core @rest-rpc/express express zod
yarn add @rest-rpc/core @rest-rpc/express express zod
bun add @rest-rpc/core @rest-rpc/express express zod

If you use another server tab, replace @rest-rpc/express express with the adapter and framework package you need:

  • Fastify: @rest-rpc/fastify fastify
  • Hono: @rest-rpc/hono hono
  • Next.js: @rest-rpc/next
  • Web Request/Response: @rest-rpc/web

For the TanStack Query client example, also install:

pnpm add @rest-rpc/tanstack-query @tanstack/react-query

Define A Contract

Create a shared contract file. Put it somewhere both your server and client can import.

import { router } from "@rest-rpc/core";
import { z } from "zod";

const todoSchema = z.object({
	id: z.string(),
	title: z.string(),
	completed: z.boolean(),
});

export const api = router({
	todos: {
		create: {
			method: "POST",
			path: "/todos",
			body: {
				title: z.string().min(1),
			},
			response: todoSchema,
		},
	},
});
import { router } from "@rest-rpc/core";
import * as v from "valibot";

const todoSchema = v.object({
	id: v.string(),
	title: v.string(),
	completed: v.boolean(),
});

export const api = router({
	todos: {
		create: {
			method: "POST",
			path: "/todos",
			body: {
				title: v.pipe(v.string(), v.minLength(1)),
			},
			response: todoSchema,
		},
	},
});
import { router } from "@rest-rpc/core";
import { type } from "arktype";

const todoSchema = type({
	id: "string",
	title: "string",
	completed: "boolean",
});

export const api = router({
	todos: {
		create: {
			method: "POST",
			path: "/todos",
			body: {
				title: type("string>0"),
			},
			response: todoSchema,
		},
	},
});
import { router, type } from "@rest-rpc/core";

const todoSchema = {
	id: type<string>(),
	title: type<string>(),
	completed: type<boolean>(),
};

export const api = router({
	todos: {
		create: {
			method: "POST",
			path: "/todos",
			body: {
				title: type("string>0"),
			},
			response: todoSchema,
		},
	},
});

Server implementation

Implement the contract on the server with the framework of your choice.

import { const registerRoutes: (app: express.Application, implementations: ImplementationTree<RouteDeclaration>, options?: RegisterRoutesOptions) => voidregisterRoutes, const router: <const TNode extends Contract<RouteDeclaration>>(contract: TNode, handlers: ImplementationShape<TNode, HttpRouteHandlerContext, WebSocketRouteHandlerContext>) => ImplementationTreeFor<TNode, RouteDeclaration>router } from "@rest-rpc/express";
import function express(): Express
Creates an Express application. The express() function is a top-level function exported by the express module.
express
from "express";
import {
const api: {
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}
api
} from "./contract";
const const app: Expressapp = function express(): Express
Creates an Express application. The express() function is a top-level function exported by the express module.
express
();
const app: Expressapp.Application<Record<string, any>>.use: (...handlers: RequestHandler<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>[]) => Express (+8 overloads)use(function express(): Express
Creates an Express application. The express() function is a top-level function exported by the express module.
express
.var e.json: (options?: bodyParser.OptionsJson) => createServer.NextHandleFunction
Returns middleware that only parses json and only looks at requests where the Content-Type header matches the type option.
@since4.16.0
json
());
const
const todos: Map<string, {
    id: string;
    title: string;
    completed: boolean;
}>
todos
= new
var Map: MapConstructor
new <string, {
    id: string;
    title: string;
    completed: boolean;
}>(iterable?: Iterable<readonly [string, {
    id: string;
    title: string;
    completed: boolean;
}]> | null | undefined) => Map<string, {
    id: string;
    title: string;
    completed: boolean;
}> (+3 overloads)
Map
<string, {
id: stringid: string; title: stringtitle: string; completed: booleancompleted: boolean; }>(); const
const routes: {
    readonly todos: {
        readonly create: RouteImplementation<Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>>;
    };
}
routes
=
router<{
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}>(contract: {
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}, handlers: {
    ...;
}): {
    ...;
}
router
(
const api: {
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}
api
, {
todos: {
    readonly create: RouteHandler<Merge<Omit<Merge<Omit<{
        readonly method: "POST";
        readonly path: "/todos";
        readonly body: {
            readonly title: ZodString;
        };
        readonly response: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }, "responses" | "response"> & {
        responses: {
            201: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip> & ResponseBodySchema;
        };
    }>, "path" | "metadata" | "openApi" | "responses"> & {
        ...;
    }>, HttpRouteHandlerContext>;
}
todos
: {
create: RouteHandler<Merge<Omit<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly body: {
        readonly title: ZodString;
    };
    readonly response: ZodObject<{
        id: ZodString;
        title: ZodString;
        completed: ZodBoolean;
    }, $strip>;
}, "responses" | "response"> & {
    responses: {
        201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip> & ResponseBodySchema;
    };
}>, "path" | "metadata" | "openApi" | "responses"> & {
    ...;
}>, HttpRouteHandlerContext>
create
({ title: stringtitle }) {
const
const todo: {
    id: `${string}-${string}-${string}-${string}-${string}`;
    title: string;
    completed: boolean;
}
todo
= {
id: `${string}-${string}-${string}-${string}-${string}`id: var crypto: Crypto
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/crypto)
crypto
.Crypto.randomUUID(): `${string}-${string}-${string}-${string}-${string}`
The **`randomUUID()`** method of the Crypto interface is used to generate a v4 UUID using a cryptographically secure random number generator. Available only in secure contexts. [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/randomUUID)
randomUUID
(),
title: stringtitle, completed: booleancompleted: false, };
const todos: Map<string, {
    id: string;
    title: string;
    completed: boolean;
}>
todos
.
Map<string, { id: string; title: string; completed: boolean; }>.set(key: string, value: {
    id: string;
    title: string;
    completed: boolean;
}): Map<string, {
    id: string;
    title: string;
    completed: boolean;
}>
Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set
(
const todo: {
    id: `${string}-${string}-${string}-${string}-${string}`;
    title: string;
    completed: boolean;
}
todo
.id: `${string}-${string}-${string}-${string}-${string}`id,
const todo: {
    id: `${string}-${string}-${string}-${string}-${string}`;
    title: string;
    completed: boolean;
}
todo
);
return
const todo: {
    id: `${string}-${string}-${string}-${string}-${string}`;
    title: string;
    completed: boolean;
}
todo
;
}, }, }); function registerRoutes(app: express.Application, implementations: ImplementationTree<RouteDeclaration>, options?: RegisterRoutesOptions): voidregisterRoutes(const app: Expressapp,
const routes: {
    readonly todos: {
        readonly create: RouteImplementation<Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>>;
    };
}
routes
);
const app: Expressapp.Application<Record<string, any>>.listen(port: number, callback?: (error?: Error) => void): Server (+5 overloads)
Listen for connections. A node `http.Server` is returned, with this application (which is a `Function`) as its callback. If you wish to create both an HTTP and HTTPS server you may do so with the "http" and "https" modules as shown here: var http = require('http') , https = require('https') , express = require('express') , app = express(); http.createServer(app).listen(80); https.createServer({ ... }, app).listen(443);
listen
(3000);
import { const registerRoutes: (app: FastifyInstance, implementations: ImplementationTree<RouteDeclaration>, options?: RegisterRoutesOptions) => voidregisterRoutes, const router: <const TNode extends Contract<RouteDeclaration>>(contract: TNode, handlers: ImplementationShape<TNode, HttpRouteHandlerContext, WebSocketRouteHandlerContext>) => ImplementationTreeFor<TNode, RouteDeclaration>router } from "@rest-rpc/fastify";
import const Fastify: typeof fastifyFastify from "fastify";
import { 
const api: {
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}
api
} from "./contract";
const
const app: FastifyInstance<Server<typeof IncomingMessage, typeof ServerResponse>, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault> & PromiseLike<FastifyInstance<Server<typeof IncomingMessage, typeof ServerResponse>, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>> & {
    ...;
}
app
=
Fastify<Server<typeof IncomingMessage, typeof ServerResponse>, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>(opts?: fastify.FastifyHttpOptions<Server<typeof IncomingMessage, typeof ServerResponse>, FastifyBaseLogger> | undefined): FastifyInstance<Server<typeof IncomingMessage, typeof ServerResponse>, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault> & PromiseLike<...> & {
    ...;
} (+3 overloads)
Fastify factory function for the standard fastify http, https, or http2 server instance. The default function utilizes http
@paramopts Fastify server options@returnsFastify server instance
Fastify
();
const
const todos: Map<string, {
    id: string;
    title: string;
    completed: boolean;
}>
todos
= new
var Map: MapConstructor
new <string, {
    id: string;
    title: string;
    completed: boolean;
}>(iterable?: Iterable<readonly [string, {
    id: string;
    title: string;
    completed: boolean;
}]> | null | undefined) => Map<string, {
    id: string;
    title: string;
    completed: boolean;
}> (+3 overloads)
Map
<string, {
id: stringid: string; title: stringtitle: string; completed: booleancompleted: boolean; }>(); const
const routes: {
    readonly todos: {
        readonly create: RouteImplementation<Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>>;
    };
}
routes
=
router<{
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}>(contract: {
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}, handlers: {
    ...;
}): {
    ...;
}
router
(
const api: {
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}
api
, {
todos: {
    readonly create: RouteHandler<Merge<Omit<Merge<Omit<{
        readonly method: "POST";
        readonly path: "/todos";
        readonly body: {
            readonly title: ZodString;
        };
        readonly response: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }, "responses" | "response"> & {
        responses: {
            201: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip> & ResponseBodySchema;
        };
    }>, "path" | "metadata" | "openApi" | "responses"> & {
        ...;
    }>, HttpRouteHandlerContext>;
}
todos
: {
create: RouteHandler<Merge<Omit<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly body: {
        readonly title: ZodString;
    };
    readonly response: ZodObject<{
        id: ZodString;
        title: ZodString;
        completed: ZodBoolean;
    }, $strip>;
}, "responses" | "response"> & {
    responses: {
        201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip> & ResponseBodySchema;
    };
}>, "path" | "metadata" | "openApi" | "responses"> & {
    ...;
}>, HttpRouteHandlerContext>
create
({ title: stringtitle }) {
const
const todo: {
    id: `${string}-${string}-${string}-${string}-${string}`;
    title: string;
    completed: boolean;
}
todo
= {
id: `${string}-${string}-${string}-${string}-${string}`id: var crypto: Crypto
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/crypto)
crypto
.Crypto.randomUUID(): `${string}-${string}-${string}-${string}-${string}`
The **`randomUUID()`** method of the Crypto interface is used to generate a v4 UUID using a cryptographically secure random number generator. Available only in secure contexts. [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/randomUUID)
randomUUID
(),
title: stringtitle, completed: booleancompleted: false, };
const todos: Map<string, {
    id: string;
    title: string;
    completed: boolean;
}>
todos
.
Map<string, { id: string; title: string; completed: boolean; }>.set(key: string, value: {
    id: string;
    title: string;
    completed: boolean;
}): Map<string, {
    id: string;
    title: string;
    completed: boolean;
}>
Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set
(
const todo: {
    id: `${string}-${string}-${string}-${string}-${string}`;
    title: string;
    completed: boolean;
}
todo
.id: `${string}-${string}-${string}-${string}-${string}`id,
const todo: {
    id: `${string}-${string}-${string}-${string}-${string}`;
    title: string;
    completed: boolean;
}
todo
);
return
const todo: {
    id: `${string}-${string}-${string}-${string}-${string}`;
    title: string;
    completed: boolean;
}
todo
;
}, }, }); function registerRoutes(app: FastifyInstance, implementations: ImplementationTree<RouteDeclaration>, options?: RegisterRoutesOptions): voidregisterRoutes(
const app: FastifyInstance<Server<typeof IncomingMessage, typeof ServerResponse>, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault> & PromiseLike<FastifyInstance<Server<typeof IncomingMessage, typeof ServerResponse>, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>> & {
    ...;
}
app
,
const routes: {
    readonly todos: {
        readonly create: RouteImplementation<Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>>;
    };
}
routes
);
await
const app: FastifyInstance<Server<typeof IncomingMessage, typeof ServerResponse>, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault> & PromiseLike<FastifyInstance<Server<typeof IncomingMessage, typeof ServerResponse>, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>> & {
    ...;
}
app
.FastifyInstance<Server<typeof IncomingMessage, typeof ServerResponse>, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>.listen(opts?: FastifyListenOptions): Promise<string> (+2 overloads)listen({ FastifyListenOptions.port?: number | undefined
Default to `0` (picks the first available open port).
port
: 3000 });
import { const registerRoutes: <TEnv extends Env = Env>(app: Hono<TEnv>, implementations: ImplementationTree<RouteDeclaration>, options?: RegisterRoutesOptions<TEnv>) => voidregisterRoutes, const router: <const TNode extends Contract<RouteDeclaration>, TEnv extends Env = Env>(contract: TNode, handlers: ImplementationShape<TNode, HttpRouteHandlerContext<TEnv>, WebSocketRouteHandlerContext<TEnv>>) => ImplementationTreeFor<TNode, RouteDeclaration>router } from "@rest-rpc/hono";
import { class Hono<E extends Env = BlankEnv, S extends Schema = BlankSchema, BasePath extends string = "/">
The Hono class extends the functionality of the HonoBase class. It sets up routing and allows for custom options to be passed.
@templateE - The environment type.@templateS - The schema type.@templateBasePath - The base path type.
Hono
} from "hono";
import {
const api: {
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}
api
} from "./contract";
const const app: Hono<BlankEnv, BlankSchema, "/">app = new new Hono<BlankEnv, BlankSchema, "/">(options?: HonoOptions<BlankEnv> | undefined): Hono<BlankEnv, BlankSchema, "/">
Creates an instance of the Hono class.
@paramoptions - Optional configuration options for the Hono instance.
Hono
();
const
const todos: Map<string, {
    id: string;
    title: string;
    completed: boolean;
}>
todos
= new
var Map: MapConstructor
new <string, {
    id: string;
    title: string;
    completed: boolean;
}>(iterable?: Iterable<readonly [string, {
    id: string;
    title: string;
    completed: boolean;
}]> | null | undefined) => Map<string, {
    id: string;
    title: string;
    completed: boolean;
}> (+3 overloads)
Map
<string, {
id: stringid: string; title: stringtitle: string; completed: booleancompleted: boolean; }>(); const
const routes: {
    readonly todos: {
        readonly create: RouteImplementation<Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>>;
    };
}
routes
=
router<{
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}, Env>(contract: {
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}, handlers: {
    ...;
}): {
    ...;
}
router
(
const api: {
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}
api
, {
todos: {
    readonly create: RouteHandler<Merge<Omit<Merge<Omit<{
        readonly method: "POST";
        readonly path: "/todos";
        readonly body: {
            readonly title: ZodString;
        };
        readonly response: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }, "responses" | "response"> & {
        responses: {
            201: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip> & ResponseBodySchema;
        };
    }>, "path" | "metadata" | "openApi" | "responses"> & {
        ...;
    }>, HttpRouteHandlerContext<...>>;
}
todos
: {
create: RouteHandler<Merge<Omit<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly body: {
        readonly title: ZodString;
    };
    readonly response: ZodObject<{
        id: ZodString;
        title: ZodString;
        completed: ZodBoolean;
    }, $strip>;
}, "responses" | "response"> & {
    responses: {
        201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip> & ResponseBodySchema;
    };
}>, "path" | "metadata" | "openApi" | "responses"> & {
    ...;
}>, HttpRouteHandlerContext<...>>
create
({ title: stringtitle }) {
const
const todo: {
    id: `${string}-${string}-${string}-${string}-${string}`;
    title: string;
    completed: boolean;
}
todo
= {
id: `${string}-${string}-${string}-${string}-${string}`id: var crypto: Crypto
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/crypto)
crypto
.Crypto.randomUUID(): `${string}-${string}-${string}-${string}-${string}`
The **`randomUUID()`** method of the Crypto interface is used to generate a v4 UUID using a cryptographically secure random number generator. Available only in secure contexts. [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/randomUUID)
randomUUID
(),
title: stringtitle, completed: booleancompleted: false, };
const todos: Map<string, {
    id: string;
    title: string;
    completed: boolean;
}>
todos
.
Map<string, { id: string; title: string; completed: boolean; }>.set(key: string, value: {
    id: string;
    title: string;
    completed: boolean;
}): Map<string, {
    id: string;
    title: string;
    completed: boolean;
}>
Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set
(
const todo: {
    id: `${string}-${string}-${string}-${string}-${string}`;
    title: string;
    completed: boolean;
}
todo
.id: `${string}-${string}-${string}-${string}-${string}`id,
const todo: {
    id: `${string}-${string}-${string}-${string}-${string}`;
    title: string;
    completed: boolean;
}
todo
);
return
const todo: {
    id: `${string}-${string}-${string}-${string}-${string}`;
    title: string;
    completed: boolean;
}
todo
;
}, }, }); registerRoutes<BlankEnv>(app: Hono<BlankEnv, BlankSchema, "/">, implementations: ImplementationTree<RouteDeclaration>, options?: RegisterRoutesOptions<BlankEnv> | undefined): voidregisterRoutes(const app: Hono<BlankEnv, BlankSchema, "/">app,
const routes: {
    readonly todos: {
        readonly create: RouteImplementation<Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>>;
    };
}
routes
);
export default const app: Hono<BlankEnv, BlankSchema, "/">app;
import { const createRouterHandler: <const TContract extends WebContract>(contract: TContract, handlers: WebRouterHandlers<TContract>, options?: CreateRouteHandlerOptions) => RouterHandlerMapcreateRouterHandler } from "@rest-rpc/next";
import { 
const api: {
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}
api
} from "./contract";
const
const todos: Map<string, {
    id: string;
    title: string;
    completed: boolean;
}>
todos
= new
var Map: MapConstructor
new <string, {
    id: string;
    title: string;
    completed: boolean;
}>(iterable?: Iterable<readonly [string, {
    id: string;
    title: string;
    completed: boolean;
}]> | null | undefined) => Map<string, {
    id: string;
    title: string;
    completed: boolean;
}> (+3 overloads)
Map
<string, {
id: stringid: string; title: stringtitle: string; completed: booleancompleted: boolean; }>(); export const { const POST: WebRequestHandlerPOST } =
createRouterHandler<{
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}>(contract: {
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}, handlers: {
    ...;
}, options?: CreateRouteHandlerOptions): RouterHandlerMap
createRouterHandler
(
const api: {
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}
api
, {
todos: {
    readonly create: RouteHandler<Merge<Omit<Merge<Omit<{
        readonly method: "POST";
        readonly path: "/todos";
        readonly body: {
            readonly title: ZodString;
        };
        readonly response: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }, "responses" | "response"> & {
        responses: {
            201: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip> & ResponseBodySchema;
        };
    }>, "path" | "metadata" | "openApi" | "responses"> & {
        ...;
    }>>;
}
todos
: {
create: RouteHandler<Merge<Omit<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly body: {
        readonly title: ZodString;
    };
    readonly response: ZodObject<{
        id: ZodString;
        title: ZodString;
        completed: ZodBoolean;
    }, $strip>;
}, "responses" | "response"> & {
    responses: {
        201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip> & ResponseBodySchema;
    };
}>, "path" | "metadata" | "openApi" | "responses"> & {
    ...;
}>>
create
({ title: stringtitle }) {
const
const todo: {
    id: `${string}-${string}-${string}-${string}-${string}`;
    title: string;
    completed: boolean;
}
todo
= {
id: `${string}-${string}-${string}-${string}-${string}`id: var crypto: Crypto
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/crypto)
crypto
.Crypto.randomUUID(): `${string}-${string}-${string}-${string}-${string}`
The **`randomUUID()`** method of the Crypto interface is used to generate a v4 UUID using a cryptographically secure random number generator. Available only in secure contexts. [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/randomUUID)
randomUUID
(),
title: stringtitle, completed: booleancompleted: false, };
const todos: Map<string, {
    id: string;
    title: string;
    completed: boolean;
}>
todos
.
Map<string, { id: string; title: string; completed: boolean; }>.set(key: string, value: {
    id: string;
    title: string;
    completed: boolean;
}): Map<string, {
    id: string;
    title: string;
    completed: boolean;
}>
Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set
(
const todo: {
    id: `${string}-${string}-${string}-${string}-${string}`;
    title: string;
    completed: boolean;
}
todo
.id: `${string}-${string}-${string}-${string}-${string}`id,
const todo: {
    id: `${string}-${string}-${string}-${string}-${string}`;
    title: string;
    completed: boolean;
}
todo
);
return
const todo: {
    id: `${string}-${string}-${string}-${string}-${string}`;
    title: string;
    completed: boolean;
}
todo
;
}, }, });

Client implementation

Use the same contract to create a typed client.

import { const initClient: <TContract extends Contract>(contract: TContract, options: ApiClientOptions) => ApiClientFor<TContract>initClient } from "@rest-rpc/core";
import { 
const api: {
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}
api
} from "./contract";
const
const client: {
    readonly todos: {
        readonly create: ApiClientHappyPathRouteValue<Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>>;
    };
}
client
=
initClient<{
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}>(contract: {
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}, options: ApiClientOptions): {
    ...;
}
initClient
(
const api: {
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}
api
, {
baseUrl: stringbaseUrl: "http://localhost:3000", }); const
const todo: {
    id: string;
    title: string;
    completed: boolean;
}
todo
= await
const client: {
    readonly todos: {
        readonly create: ApiClientHappyPathRouteValue<Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>>;
    };
}
client
.
todos: {
    readonly create: ApiClientHappyPathRouteValue<Merge<Omit<Merge<Omit<{
        readonly method: "POST";
        readonly path: "/todos";
        readonly body: {
            readonly title: ZodString;
        };
        readonly response: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }, "responses" | "response"> & {
        responses: {
            201: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip> & ResponseBodySchema;
        };
    }>, "path" | "metadata" | "openApi" | "responses"> & {
        ...;
    }>>;
}
todos
.
create: ApiClientHappyPathRouteValue<Merge<Omit<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly body: {
        readonly title: ZodString;
    };
    readonly response: ZodObject<{
        id: ZodString;
        title: ZodString;
        completed: ZodBoolean;
    }, $strip>;
}, "responses" | "response"> & {
    responses: {
        201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip> & ResponseBodySchema;
    };
}>, "path" | "metadata" | "openApi" | "responses"> & {
    ...;
}>>
create
.
fetch: (request: {
    title: string;
}, options?: FetchOptions | undefined) => Promise<{
    id: string;
    title: string;
    completed: boolean;
}>
fetch
({
title: stringtitle: "Ship v1", });
import { const initTanstackQuery: <TContract extends Contract>(contract: TContract, options: TanstackQueryOptions) => TanstackQuery<TContract>initTanstackQuery } from "@rest-rpc/tanstack-query";
import { function useMutation<TData = unknown, TError = Error, TVariables = void, TOnMutateResult = unknown>(options: UseMutationOptions<TData, TError, TVariables, TOnMutateResult>, queryClient?: QueryClient): UseMutationResult<TData, TError, TVariables, TOnMutateResult>useMutation } from "@tanstack/react-query";
import { 
const api: {
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}
api
} from "./contract";
const
const tq: TanstackQueryTreeFor<{
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}>
tq
=
initTanstackQuery<{
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}>(contract: {
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}, options: TanstackQueryOptions): TanstackQueryTreeFor<...>
initTanstackQuery
(
const api: {
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}
api
, {
baseUrl: stringbaseUrl: "http://localhost:3000", }); const
const createTodo: UseMutationResult<InferRouteQueryData<Merge<Omit<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly body: {
        readonly title: ZodString;
    };
    readonly response: ZodObject<{
        id: ZodString;
        title: ZodString;
        completed: ZodBoolean;
    }, $strip>;
}, "responses" | "response"> & {
    responses: {
        201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip> & ResponseBodySchema;
    };
}>, "path" | "metadata" | "openApi" | "responses"> & {
    ...;
}>>, Error | UndeclaredRouteClientResponse, {
    ...;
}, unknown>
createTodo
=
useMutation<InferRouteQueryData<Merge<Omit<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly body: {
        readonly title: ZodString;
    };
    readonly response: ZodObject<{
        id: ZodString;
        title: ZodString;
        completed: ZodBoolean;
    }, $strip>;
}, "responses" | "response"> & {
    responses: {
        201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip> & ResponseBodySchema;
    };
}>, "path" | "metadata" | "openApi" | "responses"> & {
    ...;
}>>, Error | UndeclaredRouteClientResponse, {
    ...;
}, unknown>(options: UseMutationOptions<...>, queryClient?: QueryClient): UseMutationResult<...>
useMutation
(
const tq: TanstackQueryTreeFor<{
    readonly todos: {
        readonly create: Merge<Omit<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly body: {
                readonly title: ZodString;
            };
            readonly response: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }, "responses" | "response"> & {
            responses: {
                201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip> & ResponseBodySchema;
            };
        }>, "path" | "metadata" | "openApi" | "responses"> & {
            ...;
        }>;
    };
}>
tq
.
todos: TanstackQueryTreeFor<{
    readonly create: Merge<Omit<Merge<Omit<{
        readonly method: "POST";
        readonly path: "/todos";
        readonly body: {
            readonly title: ZodString;
        };
        readonly response: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }, "responses" | "response"> & {
        responses: {
            201: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip> & ResponseBodySchema;
        };
    }>, "path" | "metadata" | "openApi" | "responses"> & {
        ...;
    }>;
}>
todos
.
create: TanstackQueryRouteValue<Merge<Omit<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly body: {
        readonly title: ZodString;
    };
    readonly response: ZodObject<{
        id: ZodString;
        title: ZodString;
        completed: ZodBoolean;
    }, $strip>;
}, "responses" | "response"> & {
    responses: {
        201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip> & ResponseBodySchema;
    };
}>, "path" | "metadata" | "openApi" | "responses"> & {
    ...;
}>>
create
.
mutationOptions: (options?: MutationOptionsFor<Merge<Omit<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly body: {
        readonly title: ZodString;
    };
    readonly response: ZodObject<{
        id: ZodString;
        title: ZodString;
        completed: ZodBoolean;
    }, $strip>;
}, "responses" | "response"> & {
    responses: {
        201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip> & ResponseBodySchema;
    };
}>, "path" | "metadata" | "openApi" | "responses"> & {
    ...;
}>> | undefined) => MutationOptions<...>
mutationOptions
({
onSuccess?: ((data: InferRouteQueryData<Merge<Omit<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly body: {
        readonly title: ZodString;
    };
    readonly response: ZodObject<{
        id: ZodString;
        title: ZodString;
        completed: ZodBoolean;
    }, $strip>;
}, "responses" | "response"> & {
    responses: {
        201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip> & ResponseBodySchema;
    };
}>, "path" | "metadata" | "openApi" | "responses"> & {
    ...;
}>>, variables: {
    ...;
}, onMutateResult: unknown, context: MutationFunctionContext) => Promise<unknown> | unknown) | undefined
onSuccess
(
response: InferRouteQueryData<Merge<Omit<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly body: {
        readonly title: ZodString;
    };
    readonly response: ZodObject<{
        id: ZodString;
        title: ZodString;
        completed: ZodBoolean;
    }, $strip>;
}, "responses" | "response"> & {
    responses: {
        201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip> & ResponseBodySchema;
    };
}>, "path" | "metadata" | "openApi" | "responses"> & {
    ...;
}>>
response
) {
var console: Consoleconsole.Console.log(...data: any[]): void
The **`console.log()`** static method outputs a message to the console. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)
log
(
response: InferRouteQueryData<Merge<Omit<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly body: {
        readonly title: ZodString;
    };
    readonly response: ZodObject<{
        id: ZodString;
        title: ZodString;
        completed: ZodBoolean;
    }, $strip>;
}, "responses" | "response"> & {
    responses: {
        201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip> & ResponseBodySchema;
    };
}>, "path" | "metadata" | "openApi" | "responses"> & {
    ...;
}>>
response
.
body: {
    id: string;
    title: string;
    completed: boolean;
}
body
.id: stringid);
}, }), );
const createTodo: UseMutationResult<InferRouteQueryData<Merge<Omit<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly body: {
        readonly title: ZodString;
    };
    readonly response: ZodObject<{
        id: ZodString;
        title: ZodString;
        completed: ZodBoolean;
    }, $strip>;
}, "responses" | "response"> & {
    responses: {
        201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip> & ResponseBodySchema;
    };
}>, "path" | "metadata" | "openApi" | "responses"> & {
    ...;
}>>, Error | UndeclaredRouteClientResponse, {
    ...;
}, unknown>
createTodo
.
mutate: (variables: {
    title: string;
}, options?: MutateOptions<InferRouteQueryData<Merge<Omit<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly body: {
        readonly title: ZodString;
    };
    readonly response: ZodObject<{
        id: ZodString;
        title: ZodString;
        completed: ZodBoolean;
    }, $strip>;
}, "responses" | "response"> & {
    responses: {
        201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip> & ResponseBodySchema;
    };
}>, "path" | ... 2 more ... | "responses"> & {
    ...;
}>>, Error | UndeclaredRouteClientResponse, {
    title: string;
}, unknown> | undefined) => void
The mutation function you can call with variables to trigger the mutation and optionally hooks on additional callback options.
@paramvariables - The variables object to pass to the `mutationFn`.@paramoptions.onSuccess - This function will fire when the mutation is successful and will be passed the mutation's result.@paramoptions.onError - This function will fire if the mutation encounters an error and will be passed the error.@paramoptions.onSettled - This function will fire when the mutation is either successfully fetched or encounters an error and be passed either the data or error.@remarks- If you make multiple requests, `onSuccess` will fire only after the latest call you've made. - All the callback functions (`onSuccess`, `onError`, `onSettled`) are void functions, and the returned value will be ignored.
mutate
({
title: stringtitle: "Ship v1", });

Next Steps

Was this page helpful?