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.

The contract declares the HTTP method, path, request body, and response body once. The server handler and client call are inferred from that declaration.

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",
			request: {
				body: {
					title: z.string().min(1),
				},
			},
			responses: {
				201: 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",
			request: {
				body: {
					title: v.pipe(v.string(), v.minLength(1)),
				},
			},
			responses: {
				201: 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",
			request: {
				body: {
					title: type("string>0"),
				},
			},
			responses: {
				201: 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",
			request: {
				body: {
					title: type("string>0"),
				},
			},
			responses: {
				201: 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<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}
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<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>>;
    };
}
routes
=
router<{
    readonly todos: {
        readonly create: Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}>(contract: {
    readonly todos: {
        readonly create: Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}, handlers: {
    ...;
}): {
    ...;
}
router
(
const api: {
    readonly todos: {
        readonly create: Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}
api
, {
todos: {
    readonly create: RouteHandler<Merge<Omit<{
        readonly method: "POST";
        readonly path: "/todos";
        readonly request: {
            readonly body: {
                readonly title: ZodString;
            };
        };
        readonly responses: {
            readonly 201: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        };
    }, "path" | "metadata" | "responses"> & {
        path: "/todos";
        metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
        responses: Merge<Omit<EmptyObject, 201> & {
            readonly 201: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }>;
    }>, HttpRouteHandlerContext>;
}
todos
: {
create: RouteHandler<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly request: {
        readonly body: {
            readonly title: ZodString;
        };
    };
    readonly responses: {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    };
}, "path" | "metadata" | "responses"> & {
    path: "/todos";
    metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
    responses: Merge<Omit<EmptyObject, 201> & {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }>;
}>, 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 { status: 201status: 201,
body: {
    id: string;
    title: string;
    completed: boolean;
}
body
:
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<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>>;
    };
}
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<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}
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<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>>;
    };
}
routes
=
router<{
    readonly todos: {
        readonly create: Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}>(contract: {
    readonly todos: {
        readonly create: Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}, handlers: {
    ...;
}): {
    ...;
}
router
(
const api: {
    readonly todos: {
        readonly create: Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}
api
, {
todos: {
    readonly create: RouteHandler<Merge<Omit<{
        readonly method: "POST";
        readonly path: "/todos";
        readonly request: {
            readonly body: {
                readonly title: ZodString;
            };
        };
        readonly responses: {
            readonly 201: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        };
    }, "path" | "metadata" | "responses"> & {
        path: "/todos";
        metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
        responses: Merge<Omit<EmptyObject, 201> & {
            readonly 201: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }>;
    }>, HttpRouteHandlerContext>;
}
todos
: {
create: RouteHandler<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly request: {
        readonly body: {
            readonly title: ZodString;
        };
    };
    readonly responses: {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    };
}, "path" | "metadata" | "responses"> & {
    path: "/todos";
    metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
    responses: Merge<Omit<EmptyObject, 201> & {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }>;
}>, 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 { status: 201status: 201,
body: {
    id: string;
    title: string;
    completed: boolean;
}
body
:
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<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>>;
    };
}
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<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}
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<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>>;
    };
}
routes
=
router<{
    readonly todos: {
        readonly create: Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}, Env>(contract: {
    readonly todos: {
        readonly create: Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}, handlers: {
    ...;
}): {
    ...;
}
router
(
const api: {
    readonly todos: {
        readonly create: Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}
api
, {
todos: {
    readonly create: RouteHandler<Merge<Omit<{
        readonly method: "POST";
        readonly path: "/todos";
        readonly request: {
            readonly body: {
                readonly title: ZodString;
            };
        };
        readonly responses: {
            readonly 201: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        };
    }, "path" | "metadata" | "responses"> & {
        path: "/todos";
        metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
        responses: Merge<Omit<EmptyObject, 201> & {
            readonly 201: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }>;
    }>, HttpRouteHandlerContext<...>>;
}
todos
: {
create: RouteHandler<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly request: {
        readonly body: {
            readonly title: ZodString;
        };
    };
    readonly responses: {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    };
}, "path" | "metadata" | "responses"> & {
    path: "/todos";
    metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
    responses: Merge<Omit<EmptyObject, 201> & {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }>;
}>, 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 { status: 201status: 201,
body: {
    id: string;
    title: string;
    completed: boolean;
}
body
:
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<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>>;
    };
}
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<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}
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<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}>(contract: {
    readonly todos: {
        readonly create: Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}, handlers: {
    ...;
}, options?: CreateRouteHandlerOptions): RouterHandlerMap
createRouterHandler
(
const api: {
    readonly todos: {
        readonly create: Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}
api
, {
todos: {
    readonly create: RouteHandler<Merge<Omit<{
        readonly method: "POST";
        readonly path: "/todos";
        readonly request: {
            readonly body: {
                readonly title: ZodString;
            };
        };
        readonly responses: {
            readonly 201: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        };
    }, "path" | "metadata" | "responses"> & {
        path: "/todos";
        metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
        responses: Merge<Omit<EmptyObject, 201> & {
            readonly 201: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }>;
    }>>;
}
todos
: {
create: RouteHandler<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly request: {
        readonly body: {
            readonly title: ZodString;
        };
    };
    readonly responses: {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    };
}, "path" | "metadata" | "responses"> & {
    path: "/todos";
    metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
    responses: Merge<Omit<EmptyObject, 201> & {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }>;
}>>
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 { status: 201status: 201,
body: {
    id: string;
    title: string;
    completed: boolean;
}
body
:
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<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}
api
} from "./contract";
const
const client: {
    readonly todos: {
        readonly create: ApiClientHappyPathRouteValue<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>>;
    };
}
client
=
initClient<{
    readonly todos: {
        readonly create: Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}>(contract: {
    readonly todos: {
        readonly create: Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}, options: ApiClientOptions): {
    ...;
}
initClient
(
const api: {
    readonly todos: {
        readonly create: Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}
api
, {
origin: stringorigin: "http://localhost:3000", }); const
const todo: {
    id: string;
    title: string;
    completed: boolean;
}
todo
= await
const client: {
    readonly todos: {
        readonly create: ApiClientHappyPathRouteValue<Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>>;
    };
}
client
.
todos: {
    readonly create: ApiClientHappyPathRouteValue<Merge<Omit<{
        readonly method: "POST";
        readonly path: "/todos";
        readonly request: {
            readonly body: {
                readonly title: ZodString;
            };
        };
        readonly responses: {
            readonly 201: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        };
    }, "path" | "metadata" | "responses"> & {
        path: "/todos";
        metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
        responses: Merge<Omit<EmptyObject, 201> & {
            readonly 201: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }>;
    }>>;
}
todos
.
create: ApiClientHappyPathRouteValue<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly request: {
        readonly body: {
            readonly title: ZodString;
        };
    };
    readonly responses: {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    };
}, "path" | "metadata" | "responses"> & {
    path: "/todos";
    metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
    responses: Merge<Omit<EmptyObject, 201> & {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }>;
}>>
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<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}
api
} from "./contract";
const
const tq: TanstackQueryTreeFor<{
    readonly todos: {
        readonly create: Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}>
tq
=
initTanstackQuery<{
    readonly todos: {
        readonly create: Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}>(contract: {
    readonly todos: {
        readonly create: Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}, options: TanstackQueryOptions): TanstackQueryTreeFor<...>
initTanstackQuery
(
const api: {
    readonly todos: {
        readonly create: Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}
api
, {
origin: stringorigin: "http://localhost:3000", }); const
const createTodo: UseMutationResult<InferRouteQueryData<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly request: {
        readonly body: {
            readonly title: ZodString;
        };
    };
    readonly responses: {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    };
}, "path" | "metadata" | "responses"> & {
    path: "/todos";
    metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
    responses: Merge<Omit<EmptyObject, 201> & {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }>;
}>>, Error | UndeclaredRouteClientResponse, {
    ...;
}, unknown>
createTodo
=
useMutation<InferRouteQueryData<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly request: {
        readonly body: {
            readonly title: ZodString;
        };
    };
    readonly responses: {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    };
}, "path" | "metadata" | "responses"> & {
    path: "/todos";
    metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
    responses: Merge<Omit<EmptyObject, 201> & {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }>;
}>>, Error | UndeclaredRouteClientResponse, {
    ...;
}, unknown>(options: UseMutationOptions<...>, queryClient?: QueryClient): UseMutationResult<...>
useMutation
(
const tq: TanstackQueryTreeFor<{
    readonly todos: {
        readonly create: Merge<Omit<{
            readonly method: "POST";
            readonly path: "/todos";
            readonly request: {
                readonly body: {
                    readonly title: ZodString;
                };
            };
            readonly responses: {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            };
        }, "path" | "metadata" | "responses"> & {
            path: "/todos";
            metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
            responses: Merge<Omit<EmptyObject, 201> & {
                readonly 201: ZodObject<{
                    id: ZodString;
                    title: ZodString;
                    completed: ZodBoolean;
                }, $strip>;
            }>;
        }>;
    };
}>
tq
.
todos: TanstackQueryTreeFor<{
    readonly create: Merge<Omit<{
        readonly method: "POST";
        readonly path: "/todos";
        readonly request: {
            readonly body: {
                readonly title: ZodString;
            };
        };
        readonly responses: {
            readonly 201: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        };
    }, "path" | "metadata" | "responses"> & {
        path: "/todos";
        metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
        responses: Merge<Omit<EmptyObject, 201> & {
            readonly 201: ZodObject<{
                id: ZodString;
                title: ZodString;
                completed: ZodBoolean;
            }, $strip>;
        }>;
    }>;
}>
todos
.
create: TanstackQueryRouteValue<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly request: {
        readonly body: {
            readonly title: ZodString;
        };
    };
    readonly responses: {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    };
}, "path" | "metadata" | "responses"> & {
    path: "/todos";
    metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
    responses: Merge<Omit<EmptyObject, 201> & {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }>;
}>>
create
.
mutationOptions: (options?: MutationOptionsFor<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly request: {
        readonly body: {
            readonly title: ZodString;
        };
    };
    readonly responses: {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    };
}, "path" | "metadata" | "responses"> & {
    path: "/todos";
    metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
    responses: Merge<Omit<EmptyObject, 201> & {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }>;
}>> | undefined) => MutationOptions<...>
mutationOptions
({
onSuccess?: ((data: InferRouteQueryData<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly request: {
        readonly body: {
            readonly title: ZodString;
        };
    };
    readonly responses: {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    };
}, "path" | "metadata" | "responses"> & {
    path: "/todos";
    metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
    responses: Merge<Omit<EmptyObject, 201> & {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }>;
}>>, variables: {
    ...;
}, onMutateResult: unknown, context: MutationFunctionContext) => Promise<unknown> | unknown) | undefined
onSuccess
(
response: InferRouteQueryData<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly request: {
        readonly body: {
            readonly title: ZodString;
        };
    };
    readonly responses: {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    };
}, "path" | "metadata" | "responses"> & {
    path: "/todos";
    metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
    responses: Merge<Omit<EmptyObject, 201> & {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }>;
}>>
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<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly request: {
        readonly body: {
            readonly title: ZodString;
        };
    };
    readonly responses: {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    };
}, "path" | "metadata" | "responses"> & {
    path: "/todos";
    metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
    responses: Merge<Omit<EmptyObject, 201> & {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }>;
}>>
response
.
body: {
    id: string;
    title: string;
    completed: boolean;
}
body
.id: stringid);
}, }), );
const createTodo: UseMutationResult<InferRouteQueryData<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly request: {
        readonly body: {
            readonly title: ZodString;
        };
    };
    readonly responses: {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    };
}, "path" | "metadata" | "responses"> & {
    path: "/todos";
    metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
    responses: Merge<Omit<EmptyObject, 201> & {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }>;
}>>, Error | UndeclaredRouteClientResponse, {
    ...;
}, unknown>
createTodo
.
mutate: (variables: {
    title: string;
}, options?: MutateOptions<InferRouteQueryData<Merge<Omit<{
    readonly method: "POST";
    readonly path: "/todos";
    readonly request: {
        readonly body: {
            readonly title: ZodString;
        };
    };
    readonly responses: {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    };
}, "path" | "metadata" | "responses"> & {
    path: "/todos";
    metadata: Merge<Omit<EmptyObject, never> & EmptyObject>;
    responses: Merge<Omit<EmptyObject, 201> & {
        readonly 201: ZodObject<{
            id: ZodString;
            title: ZodString;
            completed: ZodBoolean;
        }, $strip>;
    }>;
}>>, 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?