Integration
You can integrate PTSQ with multiple backend REST API frameworks such as Express, Koa or vanilla Node.js http.
node:http
import { createServer, IncommingMessage, ServerResponse } from 'http';
import { ptsq } from '@ptsq/server';
import { Type } from '@sinclair/typebox';
const { router, resolver, serve } = ptsq({
ctx: ({ req, res }: { req: IncommingMessage; res: ServerResponse }) => ({
req,
res,
}),
}).create();
const baseRouter = router({
greetings: resolver
.args(Type.Object({ name: Type.String() }))
.output(Type.String())
.query(({ input }) => `Hello, ${input.name}!`),
});
const app = createServer(serve(baseRouter));
app.listen(4000, () => {
console.log('Listening on: http://localhost:4000/ptsq');
});
export type BaseRouter = typeof baseRouter;
Express
import { ptsq } from '@ptsq/server';
import { Type } from '@sinclair/typebox';
import express, { Request, Response } from 'express';
const app = express();
const { router, resolver, serve } = ptsq({
ctx: ({ req, res }: { req: Request; res: Response }) => ({
req,
res,
}),
}).create();
const baseRouter = router({
greetings: resolver
.args(Type.Object({ name: Type.String() }))
.output(Type.String())
.query(({ input }) => `Hello, ${input.name}!`),
});
app.use((req, res) => serve(baseRouter)(req, res));
app.listen(4000, () => {
console.log('Listening on: http://localhost:4000/ptsq');
});
export type BaseRouter = typeof baseRouter;
Koa
import { ptsq } from '@ptsq/server';
import { Type } from '@sinclair/typebox';
import Koa, { Context } from 'koa';
const app = new Koa();
const { router, resolver, serve } = ptsq({
ctx: ({ koa }: { koa: Context }) => ({
koa,
}),
}).create();
const baseRouter = router({
greetings: resolver
.args(Type.Object({ name: Type.String() }))
.output(Type.String())
.query(({ input }) => `Hello, ${input.name}!`),
});
app.use(async (ctx) => {
const response = await serve(baseRouter).handleNodeRequest(ctx.req);
// Set status code
ctx.status = response.status;
// Set headers
response.headers.forEach((value, key) => {
ctx.append(key, value);
});
ctx.body = response.body;
});
app.listen(4000, () => {
console.log('Listening on: http://localhost:4000/ptsq');
});
export type BaseRouter = typeof baseRouter;
Fastify
import { ptsq } from '@ptsq/server';
import { Type } from '@sinclair/typebox';
import fastify, { FastifyReply, FastifyRequest } from 'fastify';
const app = fastify();
const { router, resolver, serve } = ptsq({
ctx: ({ req, reply }: { req: FastifyRequest; reply: FastifyReply }) => ({
req,
reply,
}),
}).create();
const baseRouter = router({
greetings: resolver
.args(Type.Object({ name: Type.String() }))
.output(Type.String())
.query(({ input }) => `Hello, ${input.name}!`),
});
app.route({
method: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
url: '/*',
async handler(req, reply) {
const response = await serve(baseRouter).handleNodeRequest(req, {
req,
reply,
});
if (response === undefined) {
reply.status(404).send('Not found.');
return reply;
}
response.headers.forEach((value, key) => {
reply.header(key, value);
});
reply.status(response.status);
reply.send(response.body);
},
});
app.listen({ port: 4000 }, () => {
console.log('Listening on: http://localhost:4000/ptsq');
});
export type BaseRouter = typeof baseRouter;
Next
import { serve } from '@/server/ptsq';
import { baseRouter } from '@/server/routes/root';
export const config = {
api: {
bodyParser: false,
},
};
export default serve(baseRouter);
SvelteKit
import { ptsq } from '@ptsq/server';
import { Type } from '@sinclair/typebox';
const { router, resolver, serve } = ptsq({
root: '/api',
ctx: () => ({}),
}).create();
const baseRouter = router({
greetings: resolver
.args(Type.Object({ name: Type.String() }))
.output(Type.String())
.query(({ input }) => `Hello, ${input.name}!`),
});
const server = serve(baseRouter);
export type BaseRouter = typeof baseRouter;
export { server as POST, server as GET };
Bun
import { ptsq } from '@ptsq/server';
import { Type } from '@sinclair/typebox';
const { router, resolver, serve } = ptsq({
ctx: () => ({}),
}).create();
const baseRouter = router({
greetings: resolver
.args(
Type.Object({
name: Type.String(),
}),
)
.output(Type.String())
.query(({ input }) => {
return `Hello, ${input.name}`;
}),
});
const server = Bun.serve(serve(baseRouter));
console.log(`Listening on: http://localhost:${server.port}/ptsq`);
export type BaseRouter = typeof baseRouter;