ecyrbe/zodios

How get type of request with context ?

Closed this issue · 1 comments

Hello,

First I want to say that is a really great library :)

In my case I like to use middlewares and controllers to hanle my request. Then is is great that I can do something like :

my context:

import { zodiosContext } from '@zodios/express';
import z from 'zod';
import { userSchema } from '../schemas/user.schema';

export const ctx = zodiosContext(
	z.object({
		user: userSchema,
	})
);

my route schema:

import { makeApi } from '@zodios/core';
import { userObjSchema } from '../schemas/user.schema';

export const userApi = makeApi([
	{
		method: 'get',
		path: '/',
		alias: 'iam',
		description: 'Get a current user',
		response: userObjSchema,
	},
]);

my route implementation:

That is fine if I do something like:

import { iamMiddleware } from '../middlewares';
import { userApi } from '../api/userApi';
import { ctx } from '../api/context.api';

const userRouter = ctx.router(userApi);

userRouter.use(iamMiddleware.iam);
userRouter.get('/', (req, res) => {
        // I get correct types here :). Thanks ZODIOS / ZOD
	const { id } = req.params;
	const user = req.user;
	res.json({
		user: user,
	});
});

But I want to extract this logic inside a controller:

my controller:

import { NextFunction, Request, Response } from 'express';
import { UserContext, UserRequest } from '../types';
import { userRepository } from '../repository';
import { User } from '@supabase/supabase-js';

// here is the problem, I dont get the types, need to be explicit, I can create a types but think is good that we
// use type generated of request on context. How can I get the request type of ctx ? 

const current = async (req, res) => {
	return res.status(200).json({ user: req.user });
};

Then will to use like:

import { userController } from '../controllers';
import { iamMiddleware } from '../middlewares';
import { userApi } from '../api/userApi';
import { ctx } from '../api/context.api';

const userRouter = ctx.router(userApi);

userRouter.use(iamMiddleware.iam);
userRouter.get('/', userController.current);

The main problem is if I need use the typed request or response on another piece of code, how can I get it ?

image

Thanks for some tips :)

Hello, I asked similar question before.

Here is how you can get typed middleware and controller type definition.

lSelectral/zodios-express-middleware-test@d25871c

export type Middleware<
	M extends Method,
	Path extends ZodiosPathsByMethod<Api, Method>
> = ZodiosRequestHandler<Api, Context, M, Path>

Sample

export const verifyPermissions = <
	M extends Method,
	Path extends ZodiosPathsByMethod<Api, Method>
>(
	...permissions: PermissionType[]
) => {
	const middleware: Middleware<M, Path> = async (req, res, next) => {}}

Controller Sample

	public static create: Middleware<'post', '/booklets'> = async (
		req,
		res
	) => {
		try {
			const result = await this.getService(req, res).create(req.body)
			return res.status(200).json(result)
		} catch (error) {
			return res.status(500).json(ServerError())
		}
	}