V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  tangkikodo  ›  全部回复第 1 页 / 共 3 页
回复总数  51
1  2  3  
后端组合, 大概率后端自己也不喜欢拼数据所以想偷懒了。

https://github.com/allmonday/pydantic-resolve-demo 如果是 python 这边的话, 这种需求 pydantic-resolve 一把梭直接就能组合好。
怎么写(单元)测试?

要从可测的思考方式来书写代码, 才有“可能”写测试

在写实现之前,或者实现之后里面套上测试, 否则久了就不会写了

要懂得常用的 mock 第三方接口的方法, 会构造数据整合查询一起测试

知道哪些应该写, 哪些没必要

知道怎么结合 use case 来写

知道怎么结合 hook 在 commit 之前强制测试跑通

知道怎么划分出合适的 service 层并覆盖测试, 避免在应用层写无聊的测试

想到更多了在补充。

关于只在 service 覆盖测试, 应用利用继承和组合避免测试, 可以参考
https://github.com/allmonday/composition-oriented-development-pattern/blob/master/src/services/sprint/readme-cn.md
@fescover
是的 生态的优势非常重要
@justdoit123

gql 的另一个问题是数据结构关联按照什么模式来组织

如果按照业务模型的方式组织, 那么面向具体的展示层, 很多查到的关联结构要在 UI 上重新做调整。

如果按照 UI 的需求来组织,那么这个 gql 写起来就很没劲了。。 变成了大号 rest
@ilvsxk

bff 如果不是前端去维护的话, 感觉这个 bff 的组织划分就有问题哎。。 (比如现在 node 就是 bff 的绝对优势语言(虽然我不太喜欢

本质上就是让前端自己组合出所需的数据, 避免不必要的组合逻辑侵入到前端展示层。
@justdoit123 完全同意

我觉得这个工具其实不是给前后端对接用的, 围绕着他的 DSL ,明明 语言原生就有的类型, 还得顺着它定义一套类型。 啰嗦了。

臃肿的请求,前端自己通过查询串联起来许多服务, 导致后端要调整的时候非常被动。

本来能用一个 client.load_xxx_data 搞定的事情, 还得在前端维护一大串查询, 这是对迭代很不友好的~
@ilvsxk bff 应该一头受气才对呀~~
@justdoit123
前后端都是 ts 技术栈, 就非常丝滑。

但缺点就是你不能指望啥都用 node 来写吧 ~~

另外光 trpc 也不能解决如何 高效且可维护地组合数据 这个问题, 如果能在 typescript 里面用

```
class Team {

member: Member[]
async resolve_member(loader=MemberLoader) {
return await loader.load(this.team_id)
}
}
```

这样地方法来组合数据, 也会优雅很多的
@yrj

调整心态吧, 有句话说“业务逻辑是最不讲逻辑的”

在没有深度分析的情况下, 写 hard code 反而不失为一种最佳做法。

如果业务是个比萨斜塔, 代码可能就是“高质量”的定制化支架。 囧
@lingo 已经 star 啦。

我用 rsshub 的数据做持久化之后, 根据自己的 mark 历史, 在尝试构建自己的信息茧房 ~~
@yrj 如果发现 service 层都会反复变更的话=。=

事情就难办咯
@SenseHu 架构整洁之道常看常新, 之前对依赖关系的描述还比较迷茫, 最近终于弄明白了。

这个模式也是受了 DDD 的很多影响, 我也挺想总结为一套 clean architecture:)
@yrj

我对业务逻辑反复变更的观点是, 这是一个悲观主义者一定要考虑的情况。

这也是为什么我觉得面向 OPENAPI 的 RESTful 接口 和 openapi-ts 之类的 client generator 的组合是所有方案中, 对前端展示层跟随变动最友好的方式了。

不使用 client generator 的话, 前端变更简直火葬场

使用 graphql 的话, 前端跟着还要调整维护 query , 也是包袱。

但如果不维护这层,后端也不主动提供页面专供接口, 那后果必然是前端拼拼凑凑,混入很多业务逻辑。

另外 BFF 这层防腐层, 看情况是可以放在后端的, 使用继承扩展 schema + resolver 的手段, 后端也能够轻松的构建 前端视图结构。 (这就看组织架构上, 根据开发资源决定哪边更适合做了)

比如我们的项目就是把这个组合层放在后端 router / controller 。
@jones2000
是的,数据库设计和合理的领域模型设计是核心, 这个应该是后端 service 层聚焦的东西。

独立的 bff 层或者 单体应用中的 controller 层聚焦的就是合理地组合 service

因此, 如果 service 层抽象的比较烂, 做的不稳定, 后面的人总归会比较惨
@FYFX

bff/controller 层做的事情,以 V2EX 为
简单来描述是 1. 先获取主数据,以 blog 为例就是先获取 blogs, 2. 根据 schema 里面的扩展定义获取 comments ,浏览量等数据

如果会出性能问题, 一般是主数据的量太大了, 比如没有采用分页方案,blog 获取了 1w 条, 那么对应的 dataloader batch 查询 就要处理 1w 个 blog_id 的参数, 这种性能问题的优化就是按照实际需要取主数据, 控制数量。

batch 查询的接口也可以对热点数据做缓存。

另外 resolver 的优点是组合灵活, 新增关联不需要去考虑 model/entity 层,ORM 那边定义新的 relationship 。

但随着业务稳定下来以后, 性能优化的时候, 是可以逐步替换, 切换成 ORM 直接提供关联数据。

(这也是为什么强调 API 要互相独立, 这样才能纵向的, 互不影响地优化 API )
@jones2000 是的, 所以抽新的层一定要有必要才做

bff 的模式已经在很多公司采用, 客观说明了这层的价值。

让后端专注在服务, 前端专注在拼接和展示。(避免了后端为了响应 UI 层需求频繁调整接口的情景)

不稳定的层一定要依赖于稳定的层, 因此后端的服务接口质量就尤为重要了
@helbing 好巧~

没有最好的工具, 只有最适合的工具,graphql 现在就处在被人当成最好的工具的“光环”中, 近年来也开始有人来祛魅

在前后端开发中实践了 1 年 graphql 后, 我觉得 graphql 太重了, 而且向展示层暴露查询是一种危险的做法, 会反过来绑架后端的开发。

fastapi 中 pydantic 本身就能定义类型, 处理数据加载和校验, 所以动起了用 pydantic + resolve +dataloader 构建一个后端定义数据, 加载数据, 这样一套模式的脑筋。(阉割版本的 graphql, 笑)

实际使用体验非常不错。 当 schema 是固定的之后, 可以玩很多树状结构跨代的数据传输和收集, 在保持 service 提供数据不变的情况下, 满足各种展示层鬼畜的数据组合需求
108 天前
回复了 iheeleme 创建的主题 职场话题 目前工作情况下的一点困扰和问题探讨
后端接口质量不过关,并且 leader 不重视, 前端只能遭罪了。

我们 team 也不大, 但是 service 层功能的 testcase 非常重视,单测,mock 数据的集成测试, 这是这两点就让接口质量稳定了许多。
rsshub yyds

其实做 feed 的持久化, 然后平时搜索搜索信息也挺有用的
1  2  3  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2720 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 19ms · UTC 15:13 · PVG 23:13 · LAX 08:13 · JFK 11:13
Developed with CodeLauncher
♥ Do have faith in what you're doing.