问个 RESTful API 设计的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
Orenoid
V2EX    程序员

问个 RESTful API 设计的问题

  •   Orenoid
    Orenoid 2019-03-28 10:25:17 +08:00 3698 次点击
    这是一个创建于 2440 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我现在想要对某个资源进行更新,路径 /path/to/resource 方法用 PUT 或者 PATCH
    这个资源有多个属性,例如 A、B、C 属性
    而我在不同场景下需要对不同属性进行更新,并且在业务上需要进行额外的判断,而不是简单的把前端给的值直接覆盖进去
    更复杂的情况可能还会有更新 A、B,或者更新 B、C 这种交错的情况,说白了就是一个资源上有多个场景下的更新逻辑
    这种情况下感觉在一个 URI 下很难实现啊,通过在接口里加字段来判断执行哪种逻辑的话,感觉本质上跟区分不同的 URI 没什么区别。。

    18 条回复    2019-03-29 15:08:31 +08:00
    alexmy
        1
    alexmy  
       2019-03-28 10:33:52 +08:00
    用 Graphql ? 之前看了看这东西,还没有实际应用。

    比如 两个用户共同关注的对象,这个...
    zivyou
        2
    zivyou  
       2019-03-28 10:42:56 +08:00
    我觉得这个 URI 设计的不合理,得定位到资源 A, B, 或 C。
    mcfog
        3
    mcfog  
       2019-03-28 10:45:32 +08:00 via Android
    一个 uri 用 patch, 传一个 array of business operation 进去就行了

    https://williamdurand.fr/2014/02/14/please-do-not-patch-like-an-idiot/
    FingerLiu
        4
    FingerLiu  
       2019-03-28 10:47:29 +08:00
    @alexmy graphQL 不是干这个事的。
    这个场景,感觉应该根据业务定义不同的 action
    mooncakejs
        5
    mooncakejs  
       2019-03-28 10:50:13 +08:00   1
    rest 不处理事务相关的,要不就是 abc 分开更新,要不就定一个组合的 resource 进行 patch
    looplj
        6
    looplj  
       2019-03-28 11:18:54 +08:00
    rest 这种所有操作都要对应资源还是不够用,明明是一个动作,就不要强行对应到一个资源上去了。
    index90
        7
    index90  
       2019-03-28 11:25:19 +08:00
    我觉得没有问题啊。
    PATCH 更新部分字段,PUT 更新所有字段,如果前端用 PATCH,他传什么属性就修改什么属性啊。问题在哪里?我没读懂
    index90
        8
    index90  
       2019-03-28 11:27:12 +08:00
    如果你是希望一个 URI 可以显式限定可修改字段,可以这样设计:
    PUT /path/to/resource/A,B // 修改 A,B 属性
    PUT /path/to/resource/B,C // 修改 B,C 属性
    wizardoz
        9
    wizardoz  
       2019-03-28 12:03:07 +08:00
    可能需要在 Restful API 之上再加一个业务层,提供业务 API。
    lhx2008
        10
    lhx2008  
       2019-03-28 12:07:47 +08:00 via Android
    是不是粒度太大了,如果有联动的操作的话,可以再细分二级的资源比较好
    MoHen9
        11
    MoHen9  
       2019-03-28 12:35:31 +08:00 via Android
    7 楼说的对
    hubqin
        12
    hubqin  
       2019-03-28 13:10:31 +08:00 via Android
    我们做过的一个是传个 type 参数,后端根据这个类型决定执行哪些操作。
    metamask
        13
    metamask  
       2019-03-28 17:05:01 +08:00
    Patch /path/to/resource/<id>/

    data :
    {
    "a" : "test",
    "b": "test"
    }

    ----
    Patch /path/to/resource/<id>/

    data :
    {
    "b" : "test",
    "c": "test"
    }


    在渲染层再做业务的处理
    Variazioni
        14
    Variazioni  
       2019-03-28 17:24:50 +08:00
    #7 没毛病。。
    mayorbryant
        15
    mayorbryant  
       2019-03-28 17:37:47 +08:00
    7 楼说了我想说的
    libook
        16
    libook  
       2019-03-29 10:23:54 +08:00   1
    REST 是围绕资源来设计的,而资源不一定是我们底层的数据结构;
    接口提现的不是数据,更多体现的是业务,所以简单粗暴把数据结构的 CRUD 直接作为 REST 接口来设计,会遇到很多问题。

    建议的思路是,将修改 A 和 B 与修改 B 和 C 看做两个业务,然后再抽象出一个或两个不同的资源,然后再以资源设计 API。

    比如底层 User 数据结构有 password、salt 这两个字段用来支持修改密码的业务,还有 company、job 用来支持修改工作信息的业务,那么可以抽象成密码和工作两个资源,各为一套接口。如果存在类似但不同的概念,为了避免歧义,可以分层,用户资源下面有密码和工作两个子资源。
    superZzr
        17
    superZzr  
       2019-03-29 10:32:06 +08:00
    #7 说的的确是没毛病,但是问题是,这样的不同业务场景识别,能放到前端去做么?
    index90
        18
    index90  
       2019-03-29 15:08:31 +08:00 via iPhone
    @superZzr 看 #16

    面向前端的接口要站在前端的角度去设计,所谓资源,也是前端角度的资源
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5661 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 39ms UTC 06:11 PVG 14:11 LAX 22:11 JFK 01:11
    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