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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/36291.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Sklearn】基于决策树算法的数据分类预测(Excel可直接替换数据)

【Sklearn】基于决策树算法的数据分类预测(Excel可直接替换数据) 1.模型原理1.1 模型原理1.2 数学模型 2.模型参数3.文件结构4.Excel数据5.下载地址6.完整代码7.运行结果 1.模型原理 决策树是一种基于树状结构的分类和回归模型,它通过一系列…

MySql(干货)

写这篇博客的目的不是为了将介绍原理,而是为了Sql中的代码操作属实太多了,在这里进行一个汇总,方便查阅!!! Sql分类 分类全称说明 DDL Data Definintion Language数据定义语言,用来定义数据库对…

微信小程序(由浅到深)

文章目录 一. 项目基本配置1. 项目组成2. 常见的配置文件解析3. app.json全局的五大配置4.单个页面中的page配置5. App函数6.tabBar配置 二. 基本语法,事件,单位1. 语法2. 事件3. 单位 三. 数据响应式修改四 . 内置组件1. button2. image3. input4. 组件…

k8s常用资源管理 控制

目录 Pod(容器组):Pod是Kubernetes中最小的部署单元,可以包含一个或多个容器。Pod提供了一种逻辑上的封装,使得容器可以一起共享网络和存储资源 1、创建一个pod 2、pod管理 pod操作 目录 创建Pod会很慢 Pod&…

什么是事务,并发带来的事务问题以及事务隔离级别(图文详解)

一、什么是事务? 简单说就是逻辑上的一组操作,要么都执行,要么都不执行。 举个例子,假如小明要给小红转账100元,这个转账会涉及到两个关键操作:①将小明的余额减少100元。 ②将小红的余额增加100元 。但…

学习笔记整理-JS-04-流程控制语句

文章目录 一、条件语句1. if语句的基本使用2. if else if多条件分支3. if语句算法题4. switch语句5. 三元运算符 二、循环语句1. for循环语句2. for循环算法题3. while循环语句4. break和continue5. do while语句 三、初识算法1. 什么是算法2. 累加器和累乘器3. 穷举法4. 综合算…

给大家推荐一些文本翻译、文档翻译API接口

最近在项目中要接入文本翻译和文档翻译功能,满足在工作时使用,又需要了解每个人的使用情况,所以采用了集成翻译API的方式,我再调研时也查了比较多的资料,总结了我感觉比较好的网站。 推荐网站 1、百度翻译&#xff0…

设计模式(2)工厂方法模式

一、 1、介绍:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说…

odoo-034 float 浮点数比较

文章目录 前提问题解决总结 前提 odoo 版本:13 python:3.6.9 问题 比较销售订单行中已送货跟已开票,在 tree 视图显示搜索后的结果。发现搜索条件为已送货 > 已开票时,结果中会包含已送货已开票的。 解决 把这两个值打印出…

LeNet中文翻译

Gradient-Based Learning Applied to Document Recognition 基于梯度的学习应用于文档识别 摘要 使用反向传播算法训练的多层神经网络构成了成功的基于梯度的学习技术的最佳示例。给定适当的网络架构,基于梯度的学习算法可用于合成复杂的决策表面,该决策…

【Vue-Router】使用 prams 路由传参失效

报错信息: [Vue Router warn]: Discarded invalid param(s) “name”, “price”, “id” when navigating. list.json {"data": [{"name": "面","price":300,"id": 1},{"name": "水",&quo…

node获取微信小程序登录用户的openid

前提准备: 1、需要知道AppID(小程序ID) 2、AppSecret(小程序密钥) 3、调wx.login成功后返回的code 代码如下: const express require(express); const router express.Router(); const request require(request) const APP_URL https://api.wei…

考研408 | 【计算机网络】 网络层

导图 网络层: 路由器功能:转发&路由选择 数据平面 数据平面执行的主要功能是根据转发表进行转发,这是路由器的本地动作。 控制平面 1.传统方法/每路由器法: 2.SDN方法(Software-Defined Networking) 控制平面中的…

C++并发多线程--多个线程的数据共享和保护

目录 1--创建并等待多个线程 2--数据共享 2-1--数据只读 2-2--数据读写 2-3--共享数据保护简单案例 1--创建并等待多个线程 创建多个线程时,可以使用同一个线程入口函数; 多个线程的执行顺序与操作系统的调度机制有关,并不和创建线程的先…

html实现商品图片放大镜,html图片放大镜预览

效果 实现 复制粘贴&#xff0c;修改图片路径即可使用 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>商品图片放大镜</title></head><style>body {margin: 0;padding: 0;}#app {padding: 10px;posit…

关于青少年学习演讲与口才对未来的领导力的塑造的探析

标题&#xff1a;青少年学习演讲与口才对未来领导力的塑造&#xff1a;一项探析 摘要&#xff1a; 本论文旨在探讨青少年学习演讲与口才对未来领导力的塑造的重要性和影响。通过分析演讲和口才对青少年的益处&#xff0c;以及如何培养这些技能来促进领导力的发展&#xff0c;我…

Harmony创建项目ohpm报错

Harmony创建FA模型的项目时报如下错&#xff1a; The registry is empty - edit .ohpmrc file or use "ohpm config set registry your_registry" command to set registry.解决方法&#xff1a; File -> Settings -> Build,Execution,Deployment -> Ohpm …

机器学习基础(五)

决策树 决策树是一种预测模型,它代表着对象属属性与对象值之间的一种映射关系。树中的每个节点代表一个对象,分叉路径(或者叫树枝)则代表一个属性值。 决策树常用方法: 分类树分析,是一种监督学习,用于预计结果可能为离散类型。 回归树分析,用于预计结果为实数。 CART,…

Mysql事务及其隔离机制/隔离级别

mysql事务特性是什么&#xff1f; 原子性(atomicity)&#xff1a;一个事务必须视为一个不可分割的最小工作单元&#xff0c;整个事务中的所有操作要么全部提交成功&#xff0c;要么全部失败回滚&#xff0c;对于一个事务来说&#xff0c;不可能只执行其中的一部分操作&#xf…

docker可视化工具Portainer

1:Portainer简介 Portainer是一个docker可视化管理工具&#xff0c;可以非常方便地管理docker镜像容器。官网地址&#xff1a;https://www.portainer.io/ 注&#xff1a;现在Portainer有BE&#xff08;收费&#xff09;和CE&#xff08;免费&#xff09;版本&#xff0c;安装的…