你为什么还在写 CRUD API ()

实践是知识的母亲,知识是生活的明灯。这篇文章主要讲述你为什么还在写 CRUD API ?相关的知识,希望能为你提供帮助。
当我开始学习编程与 WEB 开发时,开始了解到 CRUD。CRUD 在所使用的方法中是相当漂亮的。于是我开始花时间将整体作为“资源”来思考以及思考如何写出基于 CRUD 的很好的应用,这些应用的资源只包括创建,读取,更新,或删除。从本质上来说,什么才是“CRUD 思维”的最佳描述。
创建,读取,更新和删除。够简单了吧 —— 但这也是问题所在。
你上次是什么时候只在存储管理方面考虑域的?
但我理解为何初学者喜欢这种方法。CRUD 思维可以很好的转化为已有的编程概念,如 SQL 中的 INSERT, SELECT, UPDATE, DELETE 或 HTTP 中的 GET, POST, PUT/PATCH, DELETE
基于 CRUD 的应用的问题在哪里?在我看来,主要问题在于当创建一个基于 CRUD 接口的时候,你完全忽视了用户意图。对于作为开发者的我们来说,意图是很重要的一个方面,不能掩盖事实。
一旦开始一种类似 CRUD 的方式设计应用接口(如 HTTP 入口),问题就会出现。
举例来说,假设你有一个“作者”模型——虽然是手写的——定义如下,然后你开发一个 WEB API,该 WEB API 在这个作者上执行一些操作并存储到数据库中。
然后,有个作者想有个额外的笔名——顺便提下,笔名类似于作者的“假”名——但应用程序只支持以 PATCH api/authors/{id} 的方式获取整个作者模型作为输入。
起初,你可能认为这没什么大不了的。
但对于一个应用开发者来说,这是个大麻烦。根本没有机会猜到需要更新什么,因此,该实现可能变得过于冗长,像下面描述的一样更新所有属性。
这会很乱,记住,我们只想增加一个笔名而已——现在假设我们已经加上了错误处理与控制分支。这会很快成为维护的噩梦。
当我还是个软件顾问时,我告诉一些开发者试着避免更新每个属性。但他们的解决方案却是在相同的方法中增加一个额外的布局:他们接收一个属性告知用户意图。然后我们会有这样的代码。
想法是好的,但我认为这个问题并没有正确的解决掉,循环复杂性与认知复杂性 开始无法控制的盘旋。可读性也是窗外之事。
显然,尽管保留了 CRUD 式的 API,但基于任务的方法正在悄然兴起。这种方法出现了一个明显的缺陷:模型混淆。
作为 API 的调用者,我仍然允许水合化 整个 UpdateAuthorConditionally 模型,也就是说,使用数据填充所有属性,但是,UpdateReason 属性决定那作者属性实际被更新。
因此,冲突部分是:如果我只想添加一个笔名的话,我为什么要填入 Email
一种比较蠢的解决方案。停止“设计”基于 CRUD的接口。实际上,一个基于任务的接口是个很好的选择,你的调用方和其他开发人员会非常赞赏。
再看一下上面的类似 CRUD 的接口,我们可以扩展下面的入口:
其方法,类以及代码行更多。那么,怎么样才会更好?
这会变得越来越清晰:传统的条件分支语句已经一去不复返了。
每一个方法都有一个明显的责任。每一个方法只做一件事,以及每一个方法都是相互独立的。
你一旦开始使用这种方法,循环复杂度与认知复杂度就会到底了。
代码非常易于阅读和维护。臆测的工作也没了--你和你的调用者确切地知道什么时候更新什么。
“你只是在属性级别上做 CRUD 工作!”【你为什么还在写 CRUD API ()】所以,这似乎只是因为我讲一个基于 CRUD的接口直接转换成一个基于任务的接口。但是,希望这对许多人来说有助于理解,因为除了 CRUD API 中已经确定的任务之外,没有其他新的任务了。
而且,我也确定大多数人可以从实现方法中抽象出这个概念:使用更专门化的端点来匹配客户端在使用应用程序时可能具有的任何意图。
然而,让我把这说清楚:我不是说你应该为每个对象属性都有一个端点。我是说,您应该拥有匹配客户端意图和他们想要执行的操作的端点。
“但现在你需要调用 5 个入口而不是 1 个!”是的,现在你确切地清楚每个端点将要做什么。
当我为丹麦教育部创建一个应用程序时,我们必须与第三方服务提供商合作,他们拥有学校、教师、班级和学生的所有数据。
项目进行了几周后,我们需要为一所学校增加学生。因此,我只是调用了他们的端点,并为一个学生提供了 XML 数据。那该死的东西把整个学校都抹去了还加了个新学生。所以,结果基本上是一所小学只有1名学生(不,他们的终点根本没有提到这种行为)。
如果他们正好有一个像 POST/PATCH api/schools/{id}/AddStudent 的端点,我们必须避免这种让人头痛的事。
一个有趣的边注:因为第三方 API 很难使用,所以大多数学校会发送 excel 表格给第三方,他们会手动处理这些表格。
“CRUD 式应用有时确定没问题吗?”确实。基于 crud 的应用程序可能有自己的位置,尽管我主张它们应该消失。当然,主要优势是开发速度。
使用一个短暂的、一次性的概念验证(POC)应用程序来进行 CRUD 是可以的。虽然我们都知道,没有什么东西是短暂的或一次性的。
如果事实证明 POC 是可执行的、可行的和可取的,那么它通常会升级到生产状态。
所以,总而言之。。。初学者通常会学习如何创建基于crud的应用程序接口,特别是在学习如何创建 web API 时,但他们很少花时间去思考这种看似简单的方法可能会带来的一些困难。
应用基于任务的方法是 CRUD 接口的一个很好的替代方案。基于任务的接口传达意图和目的,允许每个端点单独开发,使其比 CRUD 对应的接口更容易维护。

    推荐阅读