Javascript 普通函数的注解/装饰器
Javascript annotations / decorators on normal functions
我正在开发一个 Next.js 应用程序,我有一个按以下方式定义的 API:
export default function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === 'GET') {
fn1Get(req, res);
} else if (req.method === 'POST') {
fn1Post(req, res);
} else {
res.status(501).json({ operation: `${req.method}: not implemented` });
}
}
async function fn1Get(
req: NextApiRequest,
res: NextApiResponse
): Promise<void> {
const authenticated = await checkAuth(req, res);
if (authenticated) {
// Get Stuff
res.status(200).json({status: 'all right!'});
}
}
async function fn1Post(
req: NextApiRequest,
res: NextApiResponse
): Promise<void> {
const authenticated = await checkAuth(req, res);
if (authenticated) {
// Post Stuff
res.status(201).json({status: 'all right!'});
}
}
const checkAuth = async (req: NextApiRequest, res: NextApiResponse) => {
const tokenValid = await extnernalApiCall(getToken(req));
if (!tokenValid) {
res.status(403).json({ error: 'Authentication Failed' });
}
return tokenValid
};
我正在尝试找到一个更简单的设置来定义经过身份验证的方法,而不是在其中添加行 const authenticated = await checkAuth(req, res);
在 Java 或 Python 等其他语言中,我可以使用装饰器/注释/AOP,例如:
@checkAuth
async function fn1Get(
req: NextApiRequest,
res: NextApiResponse
):
我可以在 javascript 中做一些接近它的事情吗?也许通过包装函数,and/or 使用 bind/call/apply??
伪代码示例:
const checkAuth = async (fn) => {
const req = arguments[1];
const res = arguments[2];
const tokenValid = await extnernalApiCall(getToken(req));
if (!tokenValid) {
res.status(403).json({ error: 'Authentication Failed' });
}
return fn(arguments);
}
async function fn1Get = checkAuth(_fn1Get(
req: NextApiRequest,
res: NextApiResponse
): Promise<void> {
const authenticated = await checkAuth(req, res);
if (authenticated) {
// Get Stuff
res.status(200).json({status: 'all right!'});
}
})
如您所见,我要验证的所有函数都会收到相同的两个参数 req
和 res
(请求和响应),而我的验证函数也需要这两个参数来从 req
获取要进行身份验证的令牌,如果未通过身份验证,则在 res
中写入 403
我使用的技术是 Next.js React 17、TypeScript、ECMA6
是的,您可以使用包装函数来实现这一点(这基本上就是装饰器的作用)。该包装函数必须 return 一个函数。类似于以下内容(您必须相应地调整类型):
const checkAuth = (fn) => {
return async (req: NextApiRequest,res: NextApiResponse): Promise<void> => {
const tokenValid = await extnernalApiCall(getToken(req));
if (!tokenValid) {
res.status(403).json({ error: 'Authentication Failed' });
} else {
fn(req, res);
}
}
}
const fn1Get = checkAuth((
req: NextApiRequest,
res: NextApiResponse
): Promise<void> => {
// Get Stuff
res.status(200).json({status: 'all right!'});
})
话虽如此,我对next.js并不熟悉。可能有一种方法可以注册在每个请求上触发的中间件处理程序,而无需显式包装每个处理程序。
我正在开发一个 Next.js 应用程序,我有一个按以下方式定义的 API:
export default function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === 'GET') {
fn1Get(req, res);
} else if (req.method === 'POST') {
fn1Post(req, res);
} else {
res.status(501).json({ operation: `${req.method}: not implemented` });
}
}
async function fn1Get(
req: NextApiRequest,
res: NextApiResponse
): Promise<void> {
const authenticated = await checkAuth(req, res);
if (authenticated) {
// Get Stuff
res.status(200).json({status: 'all right!'});
}
}
async function fn1Post(
req: NextApiRequest,
res: NextApiResponse
): Promise<void> {
const authenticated = await checkAuth(req, res);
if (authenticated) {
// Post Stuff
res.status(201).json({status: 'all right!'});
}
}
const checkAuth = async (req: NextApiRequest, res: NextApiResponse) => {
const tokenValid = await extnernalApiCall(getToken(req));
if (!tokenValid) {
res.status(403).json({ error: 'Authentication Failed' });
}
return tokenValid
};
我正在尝试找到一个更简单的设置来定义经过身份验证的方法,而不是在其中添加行 const authenticated = await checkAuth(req, res);
在 Java 或 Python 等其他语言中,我可以使用装饰器/注释/AOP,例如:
@checkAuth
async function fn1Get(
req: NextApiRequest,
res: NextApiResponse
):
我可以在 javascript 中做一些接近它的事情吗?也许通过包装函数,and/or 使用 bind/call/apply??
伪代码示例:
const checkAuth = async (fn) => {
const req = arguments[1];
const res = arguments[2];
const tokenValid = await extnernalApiCall(getToken(req));
if (!tokenValid) {
res.status(403).json({ error: 'Authentication Failed' });
}
return fn(arguments);
}
async function fn1Get = checkAuth(_fn1Get(
req: NextApiRequest,
res: NextApiResponse
): Promise<void> {
const authenticated = await checkAuth(req, res);
if (authenticated) {
// Get Stuff
res.status(200).json({status: 'all right!'});
}
})
如您所见,我要验证的所有函数都会收到相同的两个参数 req
和 res
(请求和响应),而我的验证函数也需要这两个参数来从 req
获取要进行身份验证的令牌,如果未通过身份验证,则在 res
中写入 403
我使用的技术是 Next.js React 17、TypeScript、ECMA6
是的,您可以使用包装函数来实现这一点(这基本上就是装饰器的作用)。该包装函数必须 return 一个函数。类似于以下内容(您必须相应地调整类型):
const checkAuth = (fn) => {
return async (req: NextApiRequest,res: NextApiResponse): Promise<void> => {
const tokenValid = await extnernalApiCall(getToken(req));
if (!tokenValid) {
res.status(403).json({ error: 'Authentication Failed' });
} else {
fn(req, res);
}
}
}
const fn1Get = checkAuth((
req: NextApiRequest,
res: NextApiResponse
): Promise<void> => {
// Get Stuff
res.status(200).json({status: 'all right!'});
})
话虽如此,我对next.js并不熟悉。可能有一种方法可以注册在每个请求上触发的中间件处理程序,而无需显式包装每个处理程序。