Nextjs 高阶 API 函数:解析器不是函数
Nextjs higher order API function: resolver is not a function
我想为我的 NextJs API 路由编写一个包装器来检查请求中的 JWT,验证它然后执行原始 API 处理程序。
所以我已经像这样定义了我的包装函数
interface ApiError {
message: string,
}
export async function withJwt<T>(
handler: ((req: NextApiRequest, res: NextApiResponse<T>, user?: User)=>void|Promise<void>))
: Promise<(req: NextApiRequest, res: NextApiResponse<T | ApiError>)=>Promise<void>> {
return async (req: NextApiRequest, res: NextApiResponse<T | ApiError>) => {
const authHeader = req.headers.authorization;
if(!authHeader || !authHeader.startsWith(JWT_PREFIX)){
return res.status(401).json({
message: `Provide the header 'Authorization: ${JWT_PREFIX}<token>'`,
});
}
let user: User;
try {
user = await verify(authHeader.substring(JWT_PREFIX.length));
} catch(err) {
return res.status(401).json({message: (err as any).message as string});
}
try {
return handler(req, res, user);
} catch(err){
return res.status(500).json({message: (err as any).message});
}
};
}
然后,我的API路线看起来像这样
// page/api/hello.ts
type Data = {
name: string
}
const wrapped = withJwt((
req: NextApiRequest,
res: NextApiResponse<Data>
) => {
res.status(200).json({ name: 'John Doe' })
});
export default wrapped;
然而,当我导航到 /api/hello
时,我收到以下错误输出:
Server Error
TypeError: resolver is not a function
Uncaught at Object.apiResolver
(file:///root/projects/taskmanager-next/node_modules/next/dist/server/api-utils.js:101:15)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async DevServer.runApi (file:///root/projects/taskmanager-next/node_modules/next/dist/server/next-server.js:320:9)
at async Object.fn (file:///root/projects/taskmanager-next/node_modules/next/dist/server/base-server.js:486:37)
at async Router.execute (file:///root/projects/taskmanager-next/node_modules/next/dist/server/router.js:228:32)
at async DevServer.run (file:///root/projects/taskmanager-next/node_modules/next/dist/server/base-server.js:598:29)
at async DevServer.run (file:///root/projects/taskmanager-next/node_modules/next/dist/server/dev/next-dev-server.js:444:20)
at async DevServer.handleRequest (file:///root/projects/taskmanager-next/node_modules/next/dist/server/base-server.js:305:20)
我在这里错过了什么?
好的,我明白了:
我的错误是将 withJwt
设为 async
函数。只有 returned 函数需要 async
,因此 return 是一个 Promise。
所以以下是有效的:
export function withJwt<T>(
handler: ((req: NextApiRequest, res: NextApiResponse<T>, user?: User)=>void|Promise<void>))
: (req: NextApiRequest, res: NextApiResponse<T | ApiError>)=>Promise<void> {
return async (req: NextApiRequest, res: NextApiResponse<T | ApiError>) => {
const authHeader = req.headers.authorization;
if(!authHeader || !authHeader.startsWith(JWT_PREFIX)){
return res.status(401).json({
message: `Provide the header 'Authorization: ${JWT_PREFIX}<token>'`,
});
}
let user: User;
try {
user = await verify(authHeader.substring(JWT_PREFIX.length));
} catch(err) {
return res.status(401).json({message: (err as any).message as string});
}
try {
return handler(req, res, user);
} catch(err){
return res.status(500).json({message: (err as any).message});
}
};
}
我想为我的 NextJs API 路由编写一个包装器来检查请求中的 JWT,验证它然后执行原始 API 处理程序。
所以我已经像这样定义了我的包装函数
interface ApiError {
message: string,
}
export async function withJwt<T>(
handler: ((req: NextApiRequest, res: NextApiResponse<T>, user?: User)=>void|Promise<void>))
: Promise<(req: NextApiRequest, res: NextApiResponse<T | ApiError>)=>Promise<void>> {
return async (req: NextApiRequest, res: NextApiResponse<T | ApiError>) => {
const authHeader = req.headers.authorization;
if(!authHeader || !authHeader.startsWith(JWT_PREFIX)){
return res.status(401).json({
message: `Provide the header 'Authorization: ${JWT_PREFIX}<token>'`,
});
}
let user: User;
try {
user = await verify(authHeader.substring(JWT_PREFIX.length));
} catch(err) {
return res.status(401).json({message: (err as any).message as string});
}
try {
return handler(req, res, user);
} catch(err){
return res.status(500).json({message: (err as any).message});
}
};
}
然后,我的API路线看起来像这样
// page/api/hello.ts
type Data = {
name: string
}
const wrapped = withJwt((
req: NextApiRequest,
res: NextApiResponse<Data>
) => {
res.status(200).json({ name: 'John Doe' })
});
export default wrapped;
然而,当我导航到 /api/hello
时,我收到以下错误输出:
Server Error
TypeError: resolver is not a function
Uncaught at Object.apiResolver (file:///root/projects/taskmanager-next/node_modules/next/dist/server/api-utils.js:101:15) at processTicksAndRejections (node:internal/process/task_queues:96:5) at async DevServer.runApi (file:///root/projects/taskmanager-next/node_modules/next/dist/server/next-server.js:320:9) at async Object.fn (file:///root/projects/taskmanager-next/node_modules/next/dist/server/base-server.js:486:37) at async Router.execute (file:///root/projects/taskmanager-next/node_modules/next/dist/server/router.js:228:32) at async DevServer.run (file:///root/projects/taskmanager-next/node_modules/next/dist/server/base-server.js:598:29) at async DevServer.run (file:///root/projects/taskmanager-next/node_modules/next/dist/server/dev/next-dev-server.js:444:20) at async DevServer.handleRequest (file:///root/projects/taskmanager-next/node_modules/next/dist/server/base-server.js:305:20)
我在这里错过了什么?
好的,我明白了:
我的错误是将 withJwt
设为 async
函数。只有 returned 函数需要 async
,因此 return 是一个 Promise。
所以以下是有效的:
export function withJwt<T>(
handler: ((req: NextApiRequest, res: NextApiResponse<T>, user?: User)=>void|Promise<void>))
: (req: NextApiRequest, res: NextApiResponse<T | ApiError>)=>Promise<void> {
return async (req: NextApiRequest, res: NextApiResponse<T | ApiError>) => {
const authHeader = req.headers.authorization;
if(!authHeader || !authHeader.startsWith(JWT_PREFIX)){
return res.status(401).json({
message: `Provide the header 'Authorization: ${JWT_PREFIX}<token>'`,
});
}
let user: User;
try {
user = await verify(authHeader.substring(JWT_PREFIX.length));
} catch(err) {
return res.status(401).json({message: (err as any).message as string});
}
try {
return handler(req, res, user);
} catch(err){
return res.status(500).json({message: (err as any).message});
}
};
}