简体   繁体   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

I've been trying to build a helper function that will allow me to apply DRY pattern in order to stop repeating myself.我一直在尝试构建一个辅助函数,允许我应用 DRY 模式以停止重复自己。 My backend and the whole application is complete, however, I'd like to optimize my code, and my actual problem is that pretty much every express http method is similarly formatted the same way.我的后端和整个应用程序是完整的,但是,我想优化我的代码,而我的实际问题是几乎每个 express http 方法的格式都类似。 The only time I've happened to come close to the solution is when I've omitted the req.params as arguments.我碰巧接近解决方案的唯一一次是我省略了 req.params 作为参数。 The problem is that each method has its own req.params format.问题是每个方法都有自己的 req.params 格式。 Here's how I was trying to solve:这是我试图解决的方法:

  • I tried to use node-persist package to store req.params, and it only works after I change and resave the file, which makes sense.我尝试使用node-persist 包来存储 req.params,它只有在我更改并重新保存文件后才有效,这是有道理的。 This happened as I first passed the params as the argument and tried to pass the persisted params value when I call the function.这发生在我第一次将 params 作为参数传递并在调用函数时尝试传递持久的 params 值。 If there's a way to have the req.params stored somewhere locally first, I wouldn't be worried.如果有办法先将 req.params 存储在本地某个地方,我不会担心。

  • Second Option, I tried to use recursion and called the so-called function twice.第二个选项,我尝试使用递归并两次调用所谓的函数。 I expected the first call to return an undefined params, and the second function call to return stored req.params, but unfortunately it wasn't the case.我希望第一个调用返回一个未定义的参数,第二个函数调用返回存储的 req.params,但不幸的是事实并非如此。

  • I then decided to try using req.redirect where I've to access the database with req.params that came from req.query.然后我决定尝试使用 req.redirect,我必须使用来自 req.query 的 req.params 访问数据库。 Although this works, it still brings me back to the same problem as I'll keep redirecting everything虽然这可行,但它仍然让我回到同样的问题,因为我将继续重定向所有内容

  • My problem, I want to have a helper function like the following:我的问题,我想要一个如下的辅助函数:

  export const storage = require('node-persist'); //package to persist data
 

Few of types used:使用的几种类型:

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);

            })
    })
}

Here's how I invoked them:以下是我调用它们的方式:

    //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)
    }

And the last trick I tried was to have req.params from client upfront, then redirect them to another router我尝试的最后一个技巧是预先从客户端获取 req.params,然后将它们重定向到另一个路由器

  • Helper function to send 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}`)
    })
}

Calling:来电:

generateParams(app.post.bind(app), "/product/:id", "product")

It works but it's still the same problem I was trying to avoid beforehand它有效,但它仍然是我事先试图避免的同一个问题

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)
  })
});

Thanks in advance提前致谢

I created a helper function to handle the queries and params based on the current req.route.path, then return an array of string containing those queries我创建了一个辅助函数来处理基于当前 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
}

Then I used it as the following:然后我使用它如下:

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)
    }
}

Now, I'd be just calling one line of code to communicate with mysql database no matter which method I intend to use:现在,无论我打算使用哪种方法,我都只需调用一行代码与 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