如何在具有自动保存功能的网站上设计 api 端点?
Posted
技术标签:
【中文标题】如何在具有自动保存功能的网站上设计 api 端点?【英文标题】:How to design api endpoints on a website with auto save? 【发布时间】:2021-08-17 12:04:13 【问题描述】:我有一个网站,每个公司都可以在其中修改一些设置:UpperBanner、LowerBanner、Introduction 或 TextSize。这些字段中的每一个都具有自动保存功能。我应该为每个字段创建端点吗?
这是我数据库中的一个表:
这是我的网站设计(每个字段都有自动保存):
我考虑以下端点。方向好吗?
GET /PageSettings - to return a row in a database for a company
HEAD /PageSettings - to check if exists a row in a database for a company
POST /PageSettings - to create a row in a database with only Id and CompanyId
HEAD /PageSettings/UpperBanner/FileId - to check if exists UpperBanner in a database for a company
POST /PageSettings/UpperBanner - to add UpperBanner in a database for a company
PUT /PageSettings/UpperBanner/FileId - to change UpperBanner in a database for a company
HEAD /PageSettings/LowerBanner/FileId - to check if exists LowerBanner in a database for a company
POST /PageSettings/LowerBanner - to add LowerBanner in a database for a company
PUT /PageSettings/LowerBanner/FileId - to change LowerBanner in a database for a company
HEAD /PageSettings/Introduction - to check if exists Introduction in a database for a company
POST /PageSettings/Introduction - to add Introduction in a database for a company
PUT /PageSettings/Introduction - to change Introduction in a database for a company
HEAD /PageSettings/TextSize - to check if exists TextSize in a database for a company
POST /PageSettings/TextSize - to add TextSize in a database for a company
PUT /PageSettings/TextSize - to change TextSize in a database for a company
【问题讨论】:
或许可以考虑使用http方式PATH? 我有文件,所以不知道 PATH 是否简单。 【参考方案1】:最好创建一个单独的 CRUD 端点,其 PUT/PATCH 操作仅更新发送的信息。在这种情况下,您必须区分何时发送或尚未发送可能为 null 的字段。
如果您消除了包含 null 元素的可能性,则合并是微不足道的:
@Controller
... MyControllerClass
@Put / @Patch
public Response upsert(Entity upsertEntity)
...
Entity currentEntity = repository
.get(upsertEntity.getId())
.merge(upsertEntity);
...
repository.save(currentEntity);
Entity.merge
操作如下:
class Entity
...
public Entity merge(Entity other)
if(other.getField1() != null) setField1(other.getField1());
if(other.getField2() != null) setField1(other.getField2());
...
// merge hierarchy
if(other.getFieldX() != null)
getFieldX().merge(other.getFieldX());
...
return this;
如果可以将字段删除到null
状态,则此方法不起作用,并且您不能为您的 API 使用相同的持久性实体(例如 Spring Boot Forms,在许多情况下您需要一个包装器)。
因此,如果客户端想要更新 N 个字段,只需一次操作即可完成。如果当用户进行更改时您等待 X 秒,您可以检测并累积多个更改以一起发送。
如果您需要重置字段(设置为 null),请为单个操作创建特定类型:
class UpsertRequestData
private boolean resetField1; // or `field1IsPresent`
private Field1Type field1;
private boolean resetField2;
private Field2Type field2;
...
【讨论】:
不幸的是每个字段都可以为空:( 然后正如我所说,为每个字段包装数据,而不是创建一个完整的端点。以上是关于如何在具有自动保存功能的网站上设计 api 端点?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用设计自动化 API 从上传的 AutoCAD 文件中提取元数据?
保护 Firebase Cloud Function HTTP 端点