记因 API 第一次挨同事骂 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
unbinilium
V2EX    程序员

记因 API 第一次挨同事骂

  •  
  •   unbinilium 11 小时 57 分钟前 2763 次点击

    背景:leader 最近接手了个嵌入式上的管理后台项目,架构比较古早 Static Web <-> Nginx <-> CGI (C, via Unix Socket) <-> Backend Application (C) <-> Modules 。同事抢了前端部分的工作,我分到了和储存系统相关的后端模块。评审完原型后就开工了,我写好自己模块前端部分 API 的草案后,请前端的同事先帮我 review 一下,结果被怒批了一顿。

    从对方比较尖锐的评价里我大概总结出以下几点:

    对方观点:

    1. 我不会做项目,完成任务优先级第一
    2. 我不是产品经理,不要替产品经理操心
    3. 我是学生思维,抓不到项目重点,写出来的东西不专业他看不懂(用不惯企微文档,加上有些术语想不到中文的名字, 草案就先用 md 写了英文的)
    4. 我协作不到位,我写这部分前端接口没提前通知他(事实上一起开会时我不仅说了,还把规划写在白板上了)

    对方理由:

    1. 他也写了这部分 API ,比我的简单很多;我的命名不符合他的规范(这点在 review 前就提醒了,我的出发点是先确定数据结构上有没有分歧,之后命名样式一定会按照他的要求改好)
    2. 他自称写过很多爬虫,也写过前端(他本职做 AI 算法的,211 硕)
    3. 不能反映到前端原型的字段上就别加,不要自作聪明以为其他人没想到
    4. 一年前上司曾批评过我过度设计,效率低

    事后也虚心看了下他写的 API ,这里仅以我的视角总结一下他的思路(因保密协议就不贴代码了):

    1. 前端页面下一个子组件对应到一个 endpoint ,不再分级,组件全部信息放在一个相同的 JSON schema 里就好
    2. 根据请求类型,后端自动去 request payload 里找需要的字段用或选择性更新 response body 里的部分字段
    3. 对于一个组件内部依赖其它组件信息或状态的情况,后端应该在这个组件的 API endpoint 里也提供
    4. 不假定某个地方需要扩展,不加冗余信息,产品有需求再改,总有办法能在现有接口上承载起新需求(顶多可能会让接口变得奇怪)

    下面说一下这部分我的观点(个人职场新人,非 CS 专业,目前也就做做 embedded infra ,这方面可能不专业):

    1. 前端原型里部分组件 anti-pattern 的迹象很明显,一个模块里揉合状态信息、配置信息和控制指令,我倾向做 decomposition 拆到该 endpoint 的子路径里做(我很难接受前端把这种模式通过 API 扩散给后端)
    2. 跨组件的状态信息,前端这边去调用对应的其它 API 处理,我的组件接口只维护生命周期在我模块内的信息
    3. 在后端仅读 payload 的数据结构上做扩展冗余,及 response 里加一些未来可能用上的信息,不会对前端解析处理增加太多负担(私有 C/S 场景也不必拮据带宽成本)
    4. 我的模块 leader 限制 C/C++/Rust 实现,一致性和 forward compatibility 比提前出第一阶段 demo 重要,未来有新需求需要调整数据结构或者实现时,改起来熵太高(后端规模远大于前端 / 前端 JS 解 JSON )

    其它的一些想法:

    1. 在设计和评审产品原型时,从时间和交互维度审视十分重要(这次其实原型就有问题)
    2. 产品经理几乎完全决定了一个产品的命运,很多时候向前端开发推进,需要先让产品经理认识到这个设计有问题(直接告诉前端要多点工作量可能挨骂)
    3. 理想主义在职场很难行得通,某种程度上我发展得的比我同事差(比较看 leader 和项目的 context 就是了,这点确实我做得不好)
    4. 即使我的主张合理,说服了大家做对的事情往往得不到任何好处,分外的事情,让市场和用户差评教产品做事就够了(自由市场也可能首先打我的脸)
    5. 和人交好很难,这件事看出同事应该是对我有不少意见,但是自己实在想不到哪里得罪了人家(感觉很多时候我已经比较注意了,比如有些会影响到大局的细节问题在评审时我想提一下,但觉得在那么多人的会上说可能不合适,毕竟我不是产品也不是设计,leader 也没开口,也是后面单独找产品旁敲侧击让他意识到有问题)

    也想听听大家的建议(比如技术方面或为人处事方面)

    嗯,再补充一些细节吧:

    1. 产品经理能 vibe coding 把原型网页做出来(虽然很粗糙),我模块的原型有问题要改结果一个星期还没改好,于是定接口时同事拿有问题的原型跟我对峙(产品想学习我理解,不过既然项目赶时间,老老实实上个 Figma 或者什么的不好吗)
      1. 原型里显示一个可能包含几十万个文件的文件夹没有分页,不加排序、过滤和搜索的情况下,期望用户能一下子找到自己想要的文件
      2. 原型过于简化,将操作/状态隐含在数据对象内,比如用户想临时关闭日程功能,做法是把之前辛辛苦苦写好的日程都删掉
    2. 同事写的 API 规范中,很多字段应该是谷歌翻译的(概念不合适且有不少拼写错误),以及他开始打算 HTTP 明文传输密码,后面其他人说不安全换成了传密码的 sha256 (不加 salt 和开始有什么区别...)

    (应该还有不少,就不浪费社会资源吐槽了)

    34 条回复    2025-10-20 01:05:46 +08:00
    lymanbernadette6
        1
    lymanbernadette6  
       11 小时 38 分钟前   5
    他行,让他来。
    他不给你发工资,你能挨他骂? 如果是好好说话,就好好探讨问题, 上来给你上强度就别惯着。
    chachi
        2
    chachi  
       11 小时 24 分钟前
    你们没研发经理?
    dsw0719
        3
    dsw0719  
       11 小时 23 分钟前
    你在工作中不发火就是不会工作。懂吗?别管对不对。下次他大声说你,你就加更大的声音顶回去。
    SGL
        4
    SGL  
       10 小时 36 分钟前   2
    朋友来了有酒肉,敌人来了有猎枪。
        5
    rabbbit  
       10 小时 33 分钟前
    字太多看的脑壳痛,谁来总结下重点.
    意思是你想按功能分 api,前端想按他前端组件分 api?

    随便举个例子啊,有个页面里需要: 用户信息和商品列表.
    你的: 分两个 api 用户信息和商品
    他的: 调一个 api 把用户信息和商品给他
    Biem
        6
    Biem  
       10 小时 23 分钟前
    j 工是这样的。
    rabbbit
        7
    rabbbit  
       10 小时 10 分钟前
    上面理解错了,只是前端也把一部分接口写了.

    工作么,这玩意商量着来.
    特别是什么内部的 xx 管理系统,没人关心这玩意咋设计的.
    前端忙就后端多写点聚合的接口免得前端调来调去.
    后端忙就前端多调几次接口.
    实在解决不了那找领导.
    vonfry
        8
    vonfry  
       9 小时 58 分钟前   1
    > 前端页面下一个子组件对应到一个 endpoint ,不再分级,组件全部信息放在一个相同的 JSON schema 里就好
    > 根据请求类型,后端自动去 request payload 里找需要的字段用或选择性更新 response body 里的部分字段

    听起来很像 graphql 的想法,如果要用 json 也有类似的框架。简单来说就是后端不把功能拆得非常细,而是由前端来控制数据的获取,这样其实对迭代会比较简单,后续维护很多需求可能都不用过后端。不过就是初期开发会有点成本,用框架的话会好一点。

    > 一年前上司曾批评过我过度设计,效率低

    我觉得得看人和项目。对很多企业来说,产品能跑就行,根本不关心内部质量。以技术角度来说我个人认为不可取,企业内,你自己想明白就行。我觉得满足自己最重要,再严重也就是丢份工作而已。

    > 他自称写过很多爬虫,也写过前端(他本职做 AI 算法的,211 硕)
    > 前端原型里部分组件 anti-pattern 的迹象很明显,一个模块里揉合状态信息、配置信息和控制指令,我倾向做 decomposition 拆到该 endpoint 的子路径里做(我很难接受前端把这种模式通过 API 扩散给后端)

    和学历无关,身边统计学。国内前端、AI 出身的大部分不关注代码质量。另外做过什么并不能说明代码能力。何况爬虫这种又是调库为主的;并不是去维护了爬虫库,做了很复杂的反爬,或是有很好的性能调优或者架构。说明不了什么。
    vonfry
        9
    vonfry  
       9 小时 55 分钟前   1
    你有 leader ,也提了前身兼容这种要求。那么你应该和 leader 多沟通,确认技术细节。
    另外开会说的东西遗忘还蛮正常的,毕竟那么多内容,一般都主要关心自己的部分。这种会后开工前要对接的,提供沟通会比较合适。
    kneo
        10
    kneo  
       9 小时 53 分钟前 via Android
    朋友,我看前面感觉可能是作为新员工的你太优秀了遭到同事妒忌。但是怎么感觉你写着写着就跑题了呢。不是很明白你要表达的重点。也不知道怎么回复。
    bbbblue
        11
    bbbblue  
       9 小时 51 分钟前
    他这个应该是前端也写的菜 所以最好你一个接口就对应他页面/组件里全部数据吧
    数据组装全都在后端做 后面前端改后端跟着改

    你和他互换一下 你写前端 他写后端搞不好就要反过来了

    他这个评价标准就是你们都要配合他 他怎么简单怎么来
    unbinilium
        12
    unbinilium  
    OP
       9 小时 4 分钟前
    @rabbbit 是的,这是第一个分歧点,我比较 RESTful ,endpoint 想做成 `/{组件}/{功能}`

    第二个分歧点在 payload 部分,比如一个划定时间段的日程组件(`.../schedule`),对方倾向平铺 `{"monday":[{...},...],"tuesday":[...],...}`, 我是倾向规则化 `{"weekly":[{...},...],"exceptions":[...],...}`

    以上两个分歧延伸到了其他接口上,再举个例子就是磁盘管理组件:

    - 显示当前可用的磁盘、每个磁盘的状态
    - 用户对磁盘的配置(配额、清理策略等)
    - 用户执行的操作等(挂载、格式化等)

    由于上面几点在原型里比较模糊,产品迟迟没有给出确定的需求,我就自己打了个草稿:

    - 按功能把 endpoint 分了两级
    - response body 按磁盘->分区做了结构化的组合,然后加了一些冗余字段
    - 比如状态机区分:错误/格式化中/未挂载/正常/同步中/索引中
    - 状态机的冗余属性:格式化中状态下代表格式化进度(类型不变)
    - revision:用于将状态机与用户行为同步,比如用户请求格式化,重命名等( POST 非幂等)
    - 其他冗余字段如当前分区格式等...

    可能对比现有的原型确实复杂了点,之前确实也没这方面的项目经验
    ksedz
        13
    ksedz  
       8 小时 57 分钟前
    我觉得你不应该太理想化,哪一点都是可以让步的,前提是对方当个人。
    既然对方这么强硬,直接怼回去,或者跟领导说跟不会说人话的合作不了。
    fregie
        14
    fregie  
       8 小时 56 分钟前   1
    没仔细看,但是我整体认同对方的思想,在不破坏可拓展性的前提下,能简单(simple)就尽可能的简单,能不加的东西就不加,能不分的层就不分
    当然在老板需要的情况下也可以破坏拓展性来换时间,但是要提前说清楚免得未来背锅
    rabbbit
        15
    rabbbit  
       8 小时 50 分钟前   1
    @unbinilium

    产品没明说的按简单的来,不建议复杂化.
    否则后期产品设计变动,你俩都要改.
    DefoliationM
        16
    DefoliationM  
       8 小时 49 分钟前   3
    >> 我写好自己模块前端部分 API 的草案后,请前端的同事先帮我 review 一下

    ???


    为什么要让前端 review 你的接口,直接给 swagger 让他用就完事了,设计好的东西没有 bug 就不要听别人的瞎改。


    >> 一年前上司曾批评过我过度设计,效率低

    我也不建议过度包装,很没用,尤其是项目大了以后很容易忘记这些复杂的设计,维护起来也累,越直观越好。


    >> 在后端仅读 payload 的数据结构上做扩展冗余,及 response 里加一些未来可能用上的信息

    看情况吧,后面大改也可以直接接口路径加版本号,比如 /api/user/v1, /api/user/v2, /api/user/v3


    >> 需要先让产品经理认识到这个设计有问题

    建议不要和产品 battle ,产品有自己的想法(也有可能单纯按照用户需求来),所以你就按产品的设计实现,不然后面出问题很可能背锅的就是你。


    >> 我协作不到位,我写这部分前端接口没提前通知他

    你们公司没有 jira 或者 gitlab issue 之类的东西吗?


    >> 我是学生思维,抓不到项目重点,写出来的东西不专业他看不懂

    呃呃,就软件工程那点东西,按上学学的来就行,需求分析,概要设计,详细设计...


    >> 不能反映到前端原型的字段上就别加,不要自作聪明以为其他人没想到

    这我觉得无所谓,swagger 上解释好接口的数据结构就行了,加不加跟前端一点关系都没有。


    >> 我很难接受前端把这种模式通过 API 扩散给后端

    跟上面类似,接口是后端写的,没有 bug 的情况下不需要向前端确认设计,谁说要改就让谁做,改了也不背锅。


    >> 以及他开始打算 HTTP 明文传输密码,后面其他人说不安全换成了传密码的 sha256 (不加 salt 和开始有什么区别...)

    现在都有 tls 了,我实在是想不通为什么很多人还要二次加密,是嫌资源用的太少了吗?前端代码都是公开的,你再怎么加密都没用。
    难道你们公司也请了某些信创的人来验证安全性?
    rb6221
        17
    rb6221  
       8 小时 39 分钟前
    我在想,你自称非 CS 专业+职场新人,怎么就能上来就做出这么复杂的设计?你所谓的设计其中的优点,有经过实践验证吗?(比如说某些设计是真的曾经帮你减少过工作量)
    MYDB
        18
    MYDB  
       7 小时 37 分钟前 via iPhone
    技术宅就爱以技术角度分析双方对错,别人很有可能就是讨厌你,闹到骂人的地步,要么骂回去,要么打回去,不要想着沟通和优化对接流程,一旦对他人有不好的印象,除了你俩一拯救世界,不然你俩永远有隔阂
    mightofcode
        19
    mightofcode  
       6 小时 59 分钟前
    我想到了我的同事(水平很差)
    一开始我对其非常友善 准备长期互帮互助好好做同事
    然后某一天开始就工作上的事教训我指导我做事 由于其水平本就一般 其说的话非常没道理
    被我一通反教训
    然后就一直老实了
    unbinilium
        20
    unbinilium  
    OP
       6 小时 49 分钟前
    @fregie 这点其实我也是认同对方的,这样双方都轻松一些,后面开会对的时候明确好责任就好,有时候把事情简单化更难。
    unbinilium
        21
    unbinilium  
    OP
       6 小时 34 分钟前
    @rabbbit 嗯,我确实复杂化了。

    不过我上面还有一层意思是,冗余设计覆盖到了我能想到的产品那边的未来需求:比如之后储存组件需求变化,大概率后端不需要任何调整( e.g. 加个进度条,增删合并分区,安全弹出之类的),只是前端来调整对后端接口的使用就好。

    不过反思了下我这种冗余设计确实不妥,相当于把 OS 的接口间接暴露给前端了,还是应该先等原型改完再定。
    zacard
        22
    zacard  
       5 小时 24 分钟前
    对方是有点咄咄逼人了,接口定义他要有异议提出来就行,再有分歧大不了拉个会再评审下。不过如果是在国内你用英文写文档就有点装了,什么术语能想不到中文啊。然后什么语法拼写错误的,真没有必要抓这些
    a33291
        23
    a33291  
       5 小时 18 分钟前
    我个人的习惯也是"轻前端",也就是只负责呈现,回收数据,所有必要的数据都由 api 准备好(api 职责单一,通过多个 api 组合使用完成业务)
    这个事从结果来看,都能完成任务,从过程来说,就是个人偏好和团队偏好
    就 OP 描述的事情来说,感觉不是纯技术输出,带点情绪
    NotLongNil
        24
    NotLongNil  
       4 小时 46 分钟前
    @unbinilium #12 看到你说 RESTful ,我就知道你领导说你过度设计是对的,这玩意过于理想化,在实际业务中强行使用,除了增加工作量,完全没有其他收益。内部系统,按照功能写接口才是最优的。我曾经跟领导有过这样的对话:“这个设计有问题,后面很难维护”,“这个功能都不知道会不会继续改,可能明年系统都下线了”。
    NotLongNil
        25
    NotLongNil  
       4 小时 42 分钟前
    你是不是还在实践 DDD ?
    e3c78a97e0f8
        26
    e3c78a97e0f8  
       3 小时 51 分钟前
    我最好奇的是,你们单位没有任何规范吗?比如我其实不喜欢 RESTFUL ,但是我们公司是明文规定要用 RESTFUL ,而且还有一堆细节设定,所以大家都得用。

    如果没有明文规范,那以前的项目是哪种模式,照做就可以了。再不行,就问领导,让领导给意见。这种主观的东西,说到底看权力,没什么好争的。
    unbinilium
        27
    unbinilium  
    OP
       3 小时 32 分钟前 via iPhone
    @zacard 啊,我的问题,忘说了… 英文版对方没看,当时 review 的是我这边重新在他企业微信文档里补充的中文版,命名样式没来得及改成他定的规范,提前也说是主要看结构,样式尽快改好(我工作日常 linux ,企微跑在 qemu 里面确实不太好用)

    拼写语法这些都是小问题,我从没提过,这里提一嘴是因为讨论时对方先批评了我,以及后面我理解他的文档十分费解。

    @a33291 嗯,是有一点。当时临时 review 双方应该也是没想好,对面找我问题,我应该是没把我这边的设计思路用语言很好地传达给对方,表达能力还是太重要了。
    GuangXiN
        28
    GuangXiN  
       3 小时 19 分钟前   1
    经典的 API 设计一般要么贴近页面内容,要么贴近数据模型。

    贴近页面的 API 一个 endpoint 对应一个页面,其优势在于前端只需要一次请求即可拿到全部需要的字段,加载/错误状态处理非常简单,字段数据按设计图填充即可,汇总拼装数据的工作主要在后端完成。这种方式的缺点在于页面内容是随产品迭代经常修改的,这意味着每次需求变更都需要变更接口数据结构以适配页面变化。如果要无缝升级,要么给 endpoint 加版本号,要么确保只新增字段不修改、删除现有字段。

    贴近数据模型的设计一般每个 endpoint 对应一个数据库里的一个表,汇总拼装数据的工作由前端完成。这种方式的优点在于数据模型相对页面更稳定,受需求变更影响更少,而且真有变更大都是加字段的行为,比较容易向下兼容;缺点是前端需要组织从多个 endpoint 加载数据,管理它们之间的依赖顺序,记录跟踪每个请求的状态、错误处理等,前端复杂度会增加不少。
    badreamm
        29
    badreamm  
       3 小时 13 分钟前
    我随便一扯,你这长篇大论我只看了一半,我估计你设计的 api 也是这样
    iseki
        30
    iseki  
       2 小时 47 分钟前 via Android   1
    大家不是你的同事,没办法只通过描述判定你俩画的 API 好还是不好。
    API 好不好要看情况,我大概能猜出你俩的分歧实质上在于前后端对问题的建模不统一时,中间的适配器谁来写的问题。当然,这是抛开那些关于“过度设计”、“太理想化”这样的屁话不谈的。这种问题如果没有一个专门的第三方来完成,那基本上只能是你俩 battle ,属于复杂的人和复杂的职场问题,与技术无关。一个潜在的解决方案是多和领导沟通,有时候把他搬出来当仲裁官是有用的,但是这个就全看你对上班这件事的能力了……
    unbinilium
        31
    unbinilium  
    OP
       2 小时 46 分钟前 via iPhone
    @GuangXiN 嗯,我实际情况感觉是更适合混合模式做,初期决定先试试贴近页面的方案
    iseki
        32
    iseki  
       2 小时 45 分钟前 via Android
    我在这种事上就比较缺乏耐心,处置手段很低级:
    前端:你给我把前端文案拼好了我多省事呢?
    我:我 NM 把你活干了多好呢?你工资给我吗,让我给你擦屁股?
    isnullstring
        33
    isnullstring  
       2 小时 23 分钟前
    针对“理由”
    1 、前端写什么 API ?不都是后端先出 API 或者先定义名字给前端,不影响各自开发进度
    2 、过(能力背书)
    3 、他说的对,UI 上不显示、前后端交互也用不上的字段,肯定不加
    4 、刚出来工作确实容易犯这个,有时候任务完成更重要,扩展性(也不是完全不考虑,需要自我平衡)、效率 后面再说。
    unbinilium
        34
    unbinilium  
    OP
       2 小时 9 分钟前 via iPhone
    @iseki 很准确的定位,谁写中间件是核心矛盾,也确实没有第三方来做。

    另外一方面是我希望通过产品精细化原型定义来消除部分和前端之间的建模误差,这一步虽得到认可,但是进度缓慢,开发受到阻碍。

    所以着急的话大概率还是得麻烦领导决策。

    技术方面的话主要是觉得我在这方面缺乏体系,寻建议不是为了定夺谁好谁坏,想看看其他人在这方面有没有书籍或项目推荐。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     912 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 19:15 PVG 03:15 LAX 12:15 JFK 15:15
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86