Almost completed development env
This commit is contained in:
@@ -21,7 +21,9 @@
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@trpc/server": "^11.1.2",
|
||||
"dotenv": "^16.5.0",
|
||||
"fastify": "^5.3.3"
|
||||
"fastify": "^5.3.3",
|
||||
"zod": "^3.25.23"
|
||||
}
|
||||
}
|
||||
|
||||
8
apps/backend/src/context.ts
Normal file
8
apps/backend/src/context.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import type { CreateFastifyContextOptions } from '@trpc/server/adapters/fastify';
|
||||
|
||||
export function createContext({ req, res }: CreateFastifyContextOptions) {
|
||||
const user = { name: req.headers.username ?? 'anonymous' };
|
||||
return { req, res, user };
|
||||
}
|
||||
|
||||
export type Context = Awaited<ReturnType<typeof createContext>>;
|
||||
@@ -1,42 +1,29 @@
|
||||
import Fastify from 'fastify';
|
||||
const fastify = Fastify({
|
||||
logger: true,
|
||||
import { fastifyTRPCPlugin, type FastifyTRPCPluginOptions } from '@trpc/server/adapters/fastify';
|
||||
import fastify from 'fastify';
|
||||
import { createContext } from './context.ts';
|
||||
import { appRouter, type AppRouter } from './router.ts';
|
||||
|
||||
const server = fastify({
|
||||
maxParamLength: 5000,
|
||||
});
|
||||
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
schema: {
|
||||
// request needs to have a querystring with a `name` parameter
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: { type: 'string' },
|
||||
},
|
||||
required: ['name'],
|
||||
server.register(fastifyTRPCPlugin, {
|
||||
prefix: '/api/trpc',
|
||||
trpcOptions: {
|
||||
router: appRouter,
|
||||
createContext,
|
||||
onError({ path, error }) {
|
||||
// report to error monitoring
|
||||
console.error(`Error in tRPC handler on path '${path}':`, error);
|
||||
},
|
||||
// the response needs to be an object with an `hello` property of type 'string'
|
||||
response: {
|
||||
200: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: { type: 'string' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
// this function is executed for every request before the handler is executed
|
||||
preHandler: async (request, reply) => {
|
||||
// E.g. check authentication
|
||||
},
|
||||
handler: async (request, reply) => {
|
||||
return { hello: 'world' };
|
||||
},
|
||||
} satisfies FastifyTRPCPluginOptions<AppRouter>['trpcOptions'],
|
||||
});
|
||||
|
||||
try {
|
||||
await fastify.listen({ port: 3000 });
|
||||
} catch (err) {
|
||||
fastify.log.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
(async () => {
|
||||
try {
|
||||
await server.listen({ port: 3000 });
|
||||
} catch (err) {
|
||||
server.log.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
||||
|
||||
33
apps/backend/src/router.ts
Normal file
33
apps/backend/src/router.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { initTRPC } from '@trpc/server';
|
||||
import { z } from 'zod';
|
||||
type User = {
|
||||
id: string;
|
||||
name: string;
|
||||
bio?: string;
|
||||
};
|
||||
|
||||
const users: Record<string, User> = {};
|
||||
export const t = initTRPC.create();
|
||||
|
||||
export const appRouter = t.router({
|
||||
demo: t.procedure.query(() => 'test'),
|
||||
getUserById: t.procedure.input(z.string()).query((opts) => {
|
||||
return users[opts.input]; // input type is string
|
||||
}),
|
||||
createUser: t.procedure
|
||||
.input(
|
||||
z.object({
|
||||
name: z.string().min(3),
|
||||
bio: z.string().max(142).optional(),
|
||||
}),
|
||||
)
|
||||
.mutation((opts) => {
|
||||
const id = Date.now().toString();
|
||||
const user: User = { id, ...opts.input };
|
||||
users[user.id] = user;
|
||||
return user;
|
||||
}),
|
||||
});
|
||||
|
||||
// export type definition of API
|
||||
export type AppRouter = typeof appRouter;
|
||||
Reference in New Issue
Block a user