Router
Routers serve as blueprints for defining the API interface, offering a structured way to organize and manage endpoints. One notable feature of this model is the ability to nest routers within a single Base
router, providing a hierarchical structure that reflects the logical organization of your API.
Moreover, routers can be merged seamlessly across files, allowing you to define routers independently and then consolidate them into a unified Base
router. This modular approach enhances code organization and maintainability, facilitating better scalability and extensibility of your API.
Exporting the type
of the Base
router is recommended as it enables clients, particularly in a monorepo project structure, to specify the server as a devDependency
. This promotes better dependency management and version control, ensuring consistency and compatibility across different parts of your project.
import { PtsqServer } from '@ptsq/server';
import express, { Request, Response } from 'express';
import { userRouter } from './userRouter';
const app = express();
const createContext = ({ req, res }: { req: Request; res: Response }) => ({
req,
res,
});
const { resolver, router, serve } = PtsqServer.init({
ctx: createContext,
}).create();
// routers can be merged as you want
const baseRouter = router({
a: router({
b: router({
c: router({
user: userRouter,
}),
}),
}),
});
export type BaseRouter = typeof baseRouter;
app.use((req, res) => serve(baseRouter)(req, res));
app.listen(4000);
Client
On the client side routers are objects (Proxy objects). If routers are nested on the server, it creates the nesting on the client side as well.
import { createProxyClient } from '@ptsq/client';
import { BaseRouter } from './server';
const client = createProxyClient<BaseRouter>({
url: 'http://localhost:4000/ptsq'
});
const result = await client.a.b.c.user.current.query();
// auto-completion
const userList = await client.a. /* b.c.user.userList.query() */
Type-level only
The BaseRouter
is a Typescript type, which means the client doesn't know anything about the server in runtime.
//@ts-ignore
const result = await client.a.wrong.route.query();
That means you can disable the type hinting and call the wrong route.
If the wrong route is called, then the server responds with BAD_REQUEST
error.