[英]What is the difference between req.path, req.params and req.query?
[英]How can I use either req.query, or req.params, or req.* outside its scope without saving in database
我一直在尝试构建一个辅助函数,允许我应用 DRY 模式以停止重复自己。 我的后端和整个应用程序是完整的,但是,我想优化我的代码,而我的实际问题是几乎每个 express http 方法的格式都类似。 我碰巧接近解决方案的唯一一次是我省略了 req.params 作为参数。 问题是每个方法都有自己的 req.params 格式。 这是我试图解决的方法:
我尝试使用node-persist 包来存储 req.params,它只有在我更改并重新保存文件后才有效,这是有道理的。 这发生在我第一次将 params 作为参数传递并在调用函数时尝试传递持久的 params 值。 如果有办法先将 req.params 存储在本地某个地方,我不会担心。
第二个选项,我尝试使用递归并两次调用所谓的函数。 我希望第一个调用返回一个未定义的参数,第二个函数调用返回存储的 req.params,但不幸的是事实并非如此。
然后我决定尝试使用 req.redirect,我必须使用来自 req.query 的 req.params 访问数据库。 虽然这可行,但它仍然让我回到同样的问题,因为我将继续重定向所有内容
我的问题,我想要一个如下的辅助函数:
export const storage = require('node-persist'); //package to persist data
使用的几种类型:
type AllHTTPMethods = "post" | "delete" | "all" | "get" | "put" | "patch" | "options" | "head";
type HTTPMethod = core.IRouterMatcher<core.Express, AllHTTPMethods>;
export async function onFetch(httpMethod: HTTPMethod | any, sql: string, path:string, params?: string){
httpMethod(path, async(req, res) => {
await storage.init({});
/**
Check if there is something already stored
*/
if (Object.keys(req.params).length === 0) {
await storage.setItem('params', req.params)
await storage.updateItem('params', req.params)
}
conn.query(sql, [params],
(err:any, data:any) => {
if (err) {
return new Error("Something went wrong\n"+err)
}
console.log("Successfully fetched");
console.log(data)
return res.json(data);
})
})
}
以下是我调用它们的方式:
//This one works because params aren't involved
async all() {
await onFetch(app.get.bind(app), "select * from products", "/products")
.then(() => console.log("Successfully fetched products"))
.catch(e => console.error(e))
}
//This one didn't work Because the function needs to called first before
//persisting
getProductById = async () => {
await storage.init()
const paramsObj = await storage.getItem("params"); //returns empty object {}
await onFetch(app.post.bind(app), "select * from products where id = ?", "/product/:id", paramsObj.id)
}
我尝试的最后一个技巧是预先从客户端获取 req.params,然后将它们重定向到另一个路由器
export function generateParams(
httpMethod: HTTPMethod,
path: string,
params: string,
) {
httpMethod(path, (req, res) => {
const paramsObject = JSON.stringify(req.params);
return res.redirect(`/params/api/?${params}=${paramsObject}`)
})
}
来电:
generateParams(app.post.bind(app), "/product/:id", "product")
它有效,但它仍然是我事先试图避免的同一个问题
app.get('/params/api', async (req, res)=> {
var product: string | string[] | any | undefined = req.query.product;
var id:any = JSON.parse(product).id
conn.query("select * from products where id = ?", [id], (err, data)=>{
if (err) {
return
}
res.json(data)
})
});
提前致谢
我创建了一个辅助函数来处理基于当前 req.route.path 的查询和参数,然后返回一个包含这些查询的字符串数组
function setRequestData(request: any) {
var arr: any[] = [];
const query = request.query
const path = request.route.path
if (path === '/product/:id') {
arr = [...arr, request.params.id]
}
else if (path === '/add/user') {
arr = [...arr,
query.firstName,
query.lastName,
query.email,
query.phoneNumber,
query.passCode,
query.age,
]
}
console.log(arr)
return arr
}
然后我使用它如下:
export function onFetch(httpMethod: HTTPMethod, sql: string | mysql.QueryOptions, path:string){
try {
httpMethod(path, (req, res) => {
var queries:any[] = setRequestData(req)
conn.query(sql, queries, (err:any, data:any) => {
if (err) {
return new Error("Something went wrong\n"+err)
}
console.log("Successful request");
res.json(data);
})
})
} catch (error) {
console.error(error)
}
}
现在,无论我打算使用哪种方法,我都只需调用一行代码与 mysql 数据库进行通信:
var sql = `insert into Users(firstName, lastName, email, phoneNumber, passCode, age, joined) values(?, ?, ?, ?, ?, ?, current_timestamp())`;
onFetch(app.post.bind(app), sql, '/add/user')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.