繁体   English   中英

如何在其范围之外使用 req.query、req.params 或 req.* 而无需保存在数据库中

[英]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,然后将它们重定向到另一个路由器

  • 发送 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM