当前位置: 首页 > news >正文

您的网站不应该只提供一套通用 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,所以它几乎总是需要数据片段,而不是整个页面

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

相关文章:

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

后端应该提供两套 API,一套是外部使用的通用 API,服务特定的数据,另一套是自家使用的应用 API,服务特定的页面。 在当今的web开发中,构建一个提供JSON服务的后端和一个渲染应用程序的前端是很流行的。我不太喜欢&…...

vue tree禁用和多选变为单选

禁用的话和后台协调一下&#xff0c;参数中多返回一个disabled 多选变单选 在tree结构中加入一个方法 <el-treeaccordion:data"deptOptions":props"defaultProps"show-checkbox:expand-on-click-node"false":filter-node-method"filte…...

ES6新特性。对象、数组新增方法

ES6新特性 ES6&#xff08;ECMAScript 2015&#xff09;是 JavaScript 的一个重要版本&#xff0c;引入了许多新的语法和功能&#xff0c;增强了语言的表达能力和开发体验。以下是 ES6 中一些重要的新特性的全面总结&#xff1a; let 和 const 声明&#xff1a; let 和 const …...

request发送http请求

今天正式开始为大家介绍接口自动化&#xff0c;相信很多做测试的朋友&#xff0c;都用过一些工具&#xff0c;比如jmeter&#xff0c;loadrunner&#xff0c;postman等等&#xff0c;所以今天先给那些基础不太好的同学&#xff0c;先讲讲postman如何来测接口以及如何用pthon代码…...

leaflet实现MARK指向的方向随机

效果图&#xff1a; npm install leaflet-rotatedmarkerL.marker([48.8631169, 2.3708919], {rotationAngle: Math.random() * 180, // 旋转角度&#xff0c;以度为单位&#xff0c;顺时针方向。rotationOrigin: "center center", // 旋转中心 }).addTo(map);...

如何使用Python编写小游戏?

大家好&#xff0c;我是沐尘而生&#xff0c;如果你是一个热爱编程的小伙伴&#xff0c;又想尝试游戏开发&#xff0c;那么这篇文章一定能满足你的好奇心。不废话&#xff0c;让我们马上进入Python游戏开发的精彩世界吧&#xff01; Python游戏开发的魅力 编写小游戏不仅仅是锻…...

【Leetcode】84.柱状图中最大的矩形(Hard)

一、题目 1、题目描述 给定 n n n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。 示例1: 输入:heights = [2,1,5,6,2,3] 输出:10 解释:最大的矩形为图中红色区域,面积为 10示例2:…...

Arraylist集合

保存数据会经常使用到数组&#xff0c;但数组存在以下几个缺陷: 长度固定&#xff1b;保存的必须为同一类型的元素&#xff0c;&#xff08;基本数据类型&#xff0c;或引用数据类型&#xff09;&#xff1b;使用数组进行增加元素的步骤比较麻烦&#xff1b; 这个时候就需要用一…...

https的原理和方案

文章目录 https原理为什么要加密常见的加密方式对称加密非对称加密数据摘要&&数据指纹数据签名 https的几种工作方案方案一&#xff1a;只使用对称加密方案二&#xff1a;只使用非对称加密方案三&#xff1a;两端都使用非对称加密方案四&#xff1a;非对称加密 对称加…...

VTK 判断一个 点 是否在一个模型 stl 内部 vtk 点是否在内部 表面 寻找最近点

判断 一个点 ,判断是否在风格 stl 模型内部&#xff0c;或表面&#xff1a; 目录 1.方案一&#xff1a;使用vtkCellLocator FindClosestPoint 找到模型上距离给定点最近的一点&#xff0c;计算两点的距离 &#xff0c;小于某一阈值 则认为此点在模型上&#xff1b; 2.方案二…...

【数据结构OJ题】链表的回文结构

原题链接&#xff1a;https://www.nowcoder.com/practice/d281619e4b3e4a60a2cc66ea32855bfa?tpId49&&tqId29370&rp1&ru/activity/oj&qru/ta/2016test/question-ranking 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 在做这道…...

Nginx常见的三个漏洞

目录 $uri导致的CRLF注入漏洞 两种常见场景 表示uri的三个变量 案例 目录穿越漏洞 案例 Http Header被覆盖的问题 案例 $uri导致的CRLF注入漏洞 两种常见场景 用户访问http://example.com/aabbcc&#xff0c;自动跳转到https://example.com/aabbcc 用户访问http://exa…...

爬虫逆向实战(十六)--某建筑市场平台

一、数据接口分析 主页地址&#xff1a;某建筑市场平台 1、抓包 通过抓包可以发现数据接口是list 2、判断是否有加密参数 请求参数是否加密&#xff1f; 无请求头是否加密&#xff1f; 无响应是否加密&#xff1f; 通过查看“响应”模块可以发现&#xff0c;返回的响应是…...

用Python做一个滑雪小游戏

游戏是让人娱乐和放松的好方式&#xff0c;而编写和玩自己的游戏则是一种特别有趣的体验。在本文中&#xff0c;我们将使用Python和pygame库来创建一个简单的滑雪小游戏。通过这个小游戏项目&#xff0c;我们将学习如何使用Python编程语言来制作自己的游戏&#xff0c;并且享受…...

EXCEL按列查找,最终返回该列所需查询序列所对应的值,VLOOKUP函数

EXCEL按列查找&#xff0c;最终返回该列所需查询序列所对应的值 示例&#xff1a;国标行业分类汉字&#xff0c;匹配id 使用VLOOKUP函数 第一参数&#xff1a;拿去查询的值。 第二参数&#xff1a;匹配的数据。 Ps&#xff1a;Sheet1!$C 21 : 21: 21:E 117 &#xff0c;需要…...

java编译报错,get方法报错

java编译报错&#xff0c;get方法报错 处理方式&#xff1a; 在空间中&#xff0c;将 buid 文件夹删除 再不行的话&#xff0c;重启电脑&#xff0c;删除各种缓存 试试...

可以降低CPU负载的网络传输技术——LSO

LSO 是个啥&#xff1f; Large Send Offload&#xff08;LSO&#xff09;是一种网络传输协议技术&#xff0c;旨在提高网络传输的性能和效率。它通过将大型数据包拆分成小型数据包&#xff0c;降低网络传输负载&#xff0c;提高传输速度。 在传统的网络传输协议中&#xff0c…...

[管理与领导-25]:IT基层管理者 - 团队管理 - 如何留人, 如何留住关键人才

目录 一、离职前的五大信号&#xff0c;你读懂了吗&#xff1f; 二、员工为什么会离职 三、如何留住关键人才 一、离职前的五大信号&#xff0c;你读懂了吗&#xff1f; 离职前的信号是指员工可能在准备离职之前表现出的一些迹象或行为。 这些信号可以帮助雇主或同事们察觉…...

【Redis】Redis 的学习教程(二)之 Jedis

仅仅知道 Redis 服务端的操作知识&#xff0c;还是远远不够的&#xff0c;如果想要真正在项目中得到应用&#xff0c;我们还需要一个 Redis 的客户端&#xff0c;然后将其集成到项目中&#xff0c;让程序自动根据我们的业务需要自动处理。 基于 Redis 开放的通信协议&#xff…...

VB+SQL银行设备管理系统设计与实现

摘要 随着银行卡的普及,很多地方安装了大量的存款机、取款机和POS机等银行自助设备。银行设备管理系统可以有效的记录银行设备的安装和使用情况,规范对自助设备的管理,从而为用户提供更加稳定和优质的服务。 本文介绍了银行设备管理系统的设计和开发过程,详细阐述了整个应…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

基于SpringBoot在线拍卖系统的设计和实现

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

uniapp 小程序 学习(一)

利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 &#xff1a;开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置&#xff0c;将微信开发者工具放入到Hbuilder中&#xff0c; 打开后出现 如下 bug 解…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关

在水泥厂的生产流程中&#xff0c;工业自动化网关起着至关重要的作用&#xff0c;尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关&#xff0c;为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多&#xff0c;其中不少设备采用Devicenet协议。Devicen…...