跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 请教后端业务逻辑代码如何分离
未分類
21 2 月 2022

请教后端业务逻辑代码如何分离

请教后端业务逻辑代码如何分离

資深大佬 : px920906 25

node+koa ,有这样一个接口:

router.post(   '/order',   {...},    async ctx => {     const { body } = ctx.request     // 一些需要查询数据库的参数验证逻辑,比如:     const item = await Item.findOne({ where: { id: body.id } })     if (!item) {       throw Error('item not existing')     }     // 后续逻辑     const result = await createOrder(body)     ctx.body = result.id   } ) 

createOrder这个函数因为其他接口 /逻辑也会用到所以单独抽出来了,于是产生个问题: 函数内部也有用到查询Item的地方,那这样的话,/order这一个接口得查询Item两次。例子是查一个,查列表的情况岂不是更浪费。

抽象出来大概是:如何避免 通用业务逻辑 与 调用它的 route 之间重复相同数据库查询操作?

求赐教!谢谢!

大佬有話說 (9)

  • 資深大佬 : lscho

    createOrder 增加一个可空参数 item 呗,存在就不查数据库,不存在再查。

  • 資深大佬 : eason1874

    createOrder 传参 Item
    如果 Item 是必须查询的,类似 List 于列表页,Post 于文章页,那也可以查询出来放到一个全局变量 queried object ,后续逻辑要获取当前查询对象时读取这个变量就行

  • 資深大佬 : towave

    查还是要查的,你可以写成中间件的形式,把查数据库的验证逻辑写在中间件就不用重复这么多次了,应该是可行的

  • 資深大佬 : ElmerZhang

    一种思路是如上所说,item 传参给 createOrder 。
    另外一种思路:item 必须存在是否也是 createOrder 成功的必要条件?如果是的话,这个判断可以放到 createOrder 内部去做,这样也能避免其他调用 createOrder 的地方也提前去查询 item 是否存在。

  • 資深大佬 : zjsxwc

    orm 托管的话,如果 findone 的 id 相同可以选择直接引用内存中的 item 对象,而不去数据库中查询

  • 資深大佬 : OutOfMemery

    Item 里面封装校验逻辑,能被创建出来就是合法的,调用时只管用,这样就能将通用业务逻辑和其他业务逻辑分开

  • 資深大佬 : libook

    其实重复查两次的的问题还好,顶多是浪费一部分数据库性能而已,不会导致 bug ;目前的实现是有可能产生 bug 的,即在高并发场景下 createOrder 执行的时候不一定确保 item 一定存在,假设 item 有可能在“const item = await Item.findOne({ where: { id: body.id } })”执行后、“createOrder”执行前被其他进程的业务逻辑删除,那么此时 createOrder 就会在 item 不存在的情况下执行;若 createOrder 内部做了 item 的存在性验证,此时会抛出异常;若未做 item 的存在性验证,则会产生脏数据。同理 createOrder 内部的多项数据库操作如果不能确保事务性(原子性)的话,也会有同样的问题。
    针对题主的例子来说,item 的存在性验证仅为 createOrder 的顺利执行而服务,那么可以把这个过程并入 createOrder 内部,在 createOrder 内部查询 item 不存在则抛出异常,同时使用事务确保多表操作的原子性。

  • 主 資深大佬 : px920906

    @libook 的确,后来我也想到了,但这样的话 createOrder 抛出的异常怎样比较好地转化到客户端异常呢?见 append 第三条

  • 資深大佬 : libook

    你 throw error 的时候是可以先 new 一个 Error 对象,然后给这个对象塞自己的自定义字段,然后 router 里 catch 到这个 error 之后拿你自定义字段看一眼,然后再根据当前 router 的情况决定如何返回 response 信息。这种做法会把 HTTP 协议层和业务逻辑层区分开,使得 createOrder 可以被多个 router 复用,每个 router 又能根据自己的情况来自定义返回。

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具