您的网站不应该只提供一套通用 API

后端应该提供两套 API,一套是外部使用的通用 API,服务特定的数据,另一套是自家使用的应用 API,服务特定的页面。

在当今的web开发中,构建一个提供JSON服务的后端和一个渲染应用程序的前端是很流行的。我不太喜欢,但还好。但是如果你认为你的后端需要被设计成一个通用的公共API是不行的。这不会节省你的时间。

为什么不喜欢呢?

当你设计一个通用API时,你必须弄清楚一堆烦人的东西。

  1. 如何预测和启用所有可能的工作流
  2. 如何避免N+1请求的尴尬工作流程
  3. 如何测试每个可能的请求的功能、性能和安全性
  4. 如何在不破坏现有工作流的情况下更改API
  5. 如何在内部需求和公共需求之间确定API变更的优先级
  6. 如何记录每件事,以便各方都能完成工作

在前端,还有很多:

  1. 如何收集呈现页面所需的所有数据
  2. 如何优化对多个端点的请求
  3. 如何避免以非预期的方式使用API数据字段
  4. 如何权衡新功能的好处和新API请求的成本

如果你只是为前端制作后端,这些真的是你的问题吗?你是否必须想象每一个可能的工作流程,避免N+1请求问题,测试每个请求配置,或者在确切知道每个页面应该是什么样子的情况下拒绝使用自己的功能?你们可以看出我的意思。

那有什么建议呢

我建议你不要再把你的前端当成一些通用的API客户端,而是把它当成你应用的一半。

想象一下,如果你可以将整个"page"的JSON值发送给它。为/page/a创建一个端点,并在那里渲染/page/a的整个JSON。对每一页都这样做。不要强迫你的前端开发人员发送一堆单独的请求来渲染复杂的页面。不要用人为的限制来烦他们。

在那个JSON中,实际渲染页面。不要渲染抽象的模型和集合。渲染具体的框、节、段落、列表。渲染可视化页面结构。

{
  "section1": {
    "topBoxTitle": "Foo",
    "leftBoxTitle": "Bar",
    "linkToClose": "https://..."
  },
  "section2": {
    ...
  }
}

这与服务器驱动的UI类似但不完全相同。也许我们可以称它为服务器通知的UI。

怎么做会更好呢?

你见过上面那些烦人的决定吗?首先,他们现在已经走了。

其次,你现在可以自由决定"我想要页面 a",然后在后端和前端实现"页面 a"。超级简单。

不再有"我们需要引入什么API工作流才能让这个页面几乎成为可能?"。你可以让"页面 a"保持沉默,只做它需要做的事情。你把"第一页"的漏洞,安全性,性能都测试了个遍。你甚至可以在一个简单的SQL查询中获取"页面a"的所有内容。你可以缓存"页面 a"的整个JSON负载。

前端确切地知道"页面 a"有效载荷中的每个字段的用途。在字段含义上没有差异。它们完全代表了前端的需求。

当项目干系人告诉你修改"页面a"时,你可以直接修改"页面a",而不是花很多时间来弄清楚后端API如何适应"页面a"的更改。它不是API请求编排的集合。只是"第1页"。你已经将自己从自己强加的API限制中解放出来。

您的业务逻辑现在已经从随意地在前端和后端之间划分为仅后端。你的前端终于可以专注于表现和UI了。你的后端最终可以专注于实现所需的功能。有点像目标,不是吗?

你真的试过这个吗

是的,到目前为止,我已经在几个生产项目中尝试过这种方法。其中一个是个人原因,另一个是在现有公司中持续多年的重构工作。整个团队都被说服了,结果很好。我们遇到的唯一问题是前端团队变得越来越无聊。几乎所有的业务逻辑都被剥夺了。与此同时,后端团队并没有感到"兴奋"。一切都变得有点无聊。不知怎么的,我们最终都讨论了更多的业务而不是代码。

如果你被说服了,请随时停止阅读。下一部分是对我不断听到的各种反驳的回应。

但我希望我的前端团队有自由!(或者我希望我的前端解耦!)

老实说,你的前端没有自由。当他们向你发送7个请求来渲染一个页面时,这不是自由。这是为了满足基本要求而跳的。一旦需求改变,您可能需要改变后端来适应它。自由都是偶然的,而且大多是在错误的地方。

如果你真的想给予你的前端团队自由,直接在Postgres上安装GraphQL包装器,然后退出。

但我们实际上想要一个通用API,所以这是一石二鸟,不是吗?

不,您实际上并不希望将此API公开。你以为你会,但到了时候,你会说"糟了,也许我不应该"。这两个API有非常不同的原因来改变。公共API需要启用客户端的工作流。私有后端需要启用您的产品经理的下一个心血来潮。别再把棍子塞进你自己的自行车轮子里了。

但是在为页面构建JSON时,我将如何重用逻辑呢?我在我的CRUD控制器中重用了这么多逻辑!

如果你的编程语言允许重用逻辑(它确实如此),那么你就可以重用逻辑。使用合成,继承,任何你需要使用的东西。如果你自己做了一些好的抽象,那么你将有一个惊人的时间从你的乐高积木组合在一起页面。

但我们也可以将此API重用到移动的应用程序中!

您的移动的应用程序有一组不同的页面,其中包含不同的信息、结构和更改原因。您将保存更多的时间和理智为它制作另一个后端专门。但是,嘿,你可以重用很多逻辑(见上一段)。

但是,如果页面需要部分XHR更新怎么办?我总是要返回一整页吗?

不,创建一个只返回特定内容的端点是可以的。我允许你去。为特定页面部分的数据片段创建端点或其他内容。没事了,我没事了从初始负载渲染React组件,然后通过XHR调用对这些端点进行更新。但只有在某些页面上需要它们时才引入这些端点。这些都是例外情况,而不是默认情况。

但是我的前端是SPA,所以它几乎总是需要数据片段,而不是整个页面

这些数据片段仍然可以作为部分页面结构而不是通用资源来提供。只要你的后端只服务于前端的确切需求,你就很好。

相关推荐
她似晚风般温柔7893 分钟前
Uniapp + Vue3 + Vite +Uview + Pinia 分商家实现购物车功能(最新附源码保姆级)
开发语言·javascript·uni-app
咩咩大主教4 分钟前
C++基于select和epoll的TCP服务器
linux·服务器·c语言·开发语言·c++·tcp/ip·io多路复用
FuLLovers34 分钟前
2024-09-13 冯诺依曼体系结构 OS管理 进程
linux·开发语言
Jiaberrr1 小时前
前端实战:使用JS和Canvas实现运算图形验证码(uniapp、微信小程序同样可用)
前端·javascript·vue.js·微信小程序·uni-app
everyStudy2 小时前
JS中判断字符串中是否包含指定字符
开发语言·前端·javascript
城南云小白2 小时前
web基础+http协议+httpd详细配置
前端·网络协议·http
前端小趴菜、2 小时前
Web Worker 简单使用
前端
luthane2 小时前
python 实现average mean平均数算法
开发语言·python·算法
web_learning_3212 小时前
信息收集常用指令
前端·搜索引擎
Ylucius2 小时前
动态语言? 静态语言? ------区别何在?java,js,c,c++,python分给是静态or动态语言?
java·c语言·javascript·c++·python·学习