bcb6通过https接口post数据_设计通过 POST 获取数据的 API 时需要注意的问题

// 每日前端夜话 第423篇
// 正文共:2100 字
// 预计阅读时间:9 分钟
2408b578e8e9b989c85c1218593e783c.png

现代网站越来越多的使用前后端分离架构,先用前端 MVC 框架快速堆砌出 SPA,再用 API 获取动态数据也已经成为日常的开发内容;而用来连接前后端的 API,其重要性也自然言而喻。做为一个前端码农,认识后端的 API 设计方式也是很重要的,今天让我们针对 API 设计来一探究竟。

HTTP 方法

毕竟是网站的前后端,其中间的通讯终究还是要依赖 HTTP 这个无状态的协议;在 HTTP 规范中定义了一系列的请求方法[1] ,其中较常用的如下:

  • GET:获取资源
  • HEAD:与 GET 同为获取资源,但只取回 Header
  • POST:提交资源
  • PUT:替换指定的资源
  • PATCH:修改指定的资源
  • DELETE:删除指定的资源
  • OPTION:询问与指定资源的沟通方法

在规范中也提到,不同的方法指的是对同一件事做不同的操作,并通过语意化的方法,让不同的操作得到预期的结果。

大家对 GETPOST  都不陌生,这是 HTML 的 所支持的两个方法;GET 是使用最频繁的,无论是获取得页面还是数据,一般都会用 GET,而 POST 则常用在新增资源上,但由于 HTML 不支持其他方法,在传统网站中可能会用 POST 处里除了获取数据之外的所有事情。

PUTPATCH 通常都用在更新资源上,两者的差异是 PUT  的行为是取代整个资源,而 PATCH 则是更新部分资源;把两者对应到日常生活中的话,就好比在餐厅吃饭,整桌菜重新点是 PUT,另外加菜是 PATCH

DELETE 通常用在删除资源;HEADGET 类似,但只取回 Header,通常用在测试资源是否存在上;OPTION 是询问这个资源应该要怎样获取,通常用在发送 CORS 的预检(preflight)请求。

目前讲的都是在规范中提到且建议的一般用法,实际服务器的 API 怎么开发依然是看实现的人;但通过语意化的方法去设计 API,绝对可以让 API 对开发者更加友好。

RESTFul API

前面所说只是规范,而且只涉及到了 HTTP 方法;有没有更完整的实现方法呢?

当然有,这就是大家耳熟能详的 RESTFul API;它由 Roy Fieldin 在 IEFT[2] 开发HTTP 标准的六年间持续研究、验证的,并在 2000 年在他的博士论文 《Architectural Styles and the Design of Network-based Software Architectures》[3] 中所提出,是一种网络程序的设计风格;所谓的 REST 是 表现层状态转换(Resource Representational State Transfer)[4] 的缩写,简单说就是通过动词(HTTP 方法)、名词(URI/URL,代表目标资源)、内容型态(响应的内容,如 HTML、XML、JSON 等),让无状态的网络通信能通过 REST 的语意化设计,携带所有的状态进行通信,降低对网络的重复请求而造成的资源消耗。

例如假设有一个视频网站:myku.com,它的的 API 有可能就会是这样:

[GET] http://myku.com/v1/videos/ -> 获取 video 列表
[POST] http://myku.com/v1/videos/-> 新增 video
[GET] http://myku.com/v1/videos/MgphHyGgeQU -> 获取指定 ID 的 video
[PUT] http://myku.com/v1/videos/MgphHyGgeQU -> 修改指定 ID 的 video
[DELETE] http://myku.com/v1/videos/MgphHyGgeQU -> 刪除指定 ID 的 video

除了所使用的方法之外,也要注意代表资源的 URL 的编写方式,不是 HTTP 方法与实际动作相符合就算是 RESTful API !

同样的,RESTFul API 只是设计风格而不是 HTTP 的规范,很有可能在设计时基于 RESTful 的精神,但实际开发的结果却完全不是 RESTful 的风格;但不可否认的是通过 RESTful API 的设计风格,每个资源都会得到一个到对应的位置(URL),并能通过 HTTP 语意化的方法,对指定的资源做相对应的互动,整体资源管理会变得非常有语意化并且清晰,这确实是一个优秀的 API 设计方式。

规范与实现

在 HTTP 规范中提到要如何正确使用方法,如果我们没有按照规范实现,会造成一定的影响。

缓存

浏览器默认会对 GETHEAD  这两个方法做缓存,如果通过 POST 而不是 GET 获取资源的话,浏览器及中间的代理服务器一般都不会实现缓存机制,这时就必须由前后端开发自行通过其他方式设置缓存。

在规范中虽然也提到了 POST 在 Header 合适的情况下也可以缓存,但由于实际上通常把 POST  用在新增操作上,做缓存的话反而会造成不可预期的后果,大部分浏览器也都没有实现针对 POST 的缓存机制。

SEO

当搜索引擎的爬虫在扫网站时,如果发现需要通过 POST 获取的资源,为了避免造成意外的行为或副作用,通常不会尝试爬取 POST 响应的结果。

GraphQL

虽然 RESTful API 的设计风格优点很多,但也有一些难以避免的缺点。

例如在查找存在依赖关系的嵌套数据时,很有可能必须要经过多次请求想要才能找到想要的结果;而随着项目架构逐渐扩张,同一页面的资料也会越来越复杂,可能需要多个来源的资料才能堆砌出页面,这时候 RESTful API 需要说明每个资源位置的特性,就会使 RESTful API 显得不太好用;也因为现在移动设备非常普及,一个后端服务器可能需要服务于 PC 版网页、手机 APP 等多设备的需求,需要的数据可能不一样,RESTful API 也就必须要实现出多个功能类似的接口,API 会逐渐变得庞大而且庞杂,相对难以管理。

有需求就会有解决的方法。这时 GraphQL[5] 就应运而生了,这是由 Facebook 提出的开源语言标准,通过 Schema 定义资料,再依靠与 JSON 格式高度类似的查询语句取得查询的结果,它的主要特点是:

  • 強类型
  • 查询语句即文件
  • 查询语句即响应的数据结构,不会有冗余的内容
  • 统一的对外入口
  • 可以多查询合并,一起返回

这些特性有效的解决了 RESTful API 在复杂架构下的问题,使 GraphQL 充满弹性、非常好用,社区也已经有了庞大的的生态系统支持,例如 Apollo GraphQL[6] 可以与三大框架深度整合,再加上多查询合并的特性,让 GraphQL  与现代框架中组件的概念完美契合。

缺点大概就是必须要把所有复杂的数据拼接逻辑都实现在后端,对于习惯于 RESTful API 的开发者来说,需要付出不少学习成本。

值得注意的是 GraphQL 发出的全部都是 POST 请求,缓存机制必须仰赖开发者或是框架实现;例如在 Apollo Client 中,开发者必须按照应用场景,调整 fetchPolicy 的设置,避免快取造成的意外结果。

后记

本文的标题是我一位朋友去面试某大厂后端时的一道面试题,由这个题目引申出 HTTP 方法及主流的 RESTful API 设计风格,并对 GraphQL 做了简短的介绍,希望以上内容能够帮到你。


Reference

[1]

HTTP 规范中: https://tools.ietf.org/html/rfc7231#section-4

[2]

IEFT: https://www.ietf.org/

[3]

《Architectural Styles and the Design of Network-based Software Architectures》: https://roy.gbiv.com/pubs/dissertation/top.htm

[4]

表现层状态转换(Resource Representational State Transfer): https://zh.wikipedia.org/wiki/表现层状态转换

[5]

GraphQL: https://graphql.org/

[6]

Apollo GraphQL: https://www.apollographql.com/

18ff197b396dfbb30f24ce78c083b937.gif
5e1d8482487339fc7de1dfc4265f7ff6.png
精彩文章回顾,点击直达

eac4313accb3dd155d97f6af773b8334.png
8faebba824ffc180e3f47fcb41338dfc.gif转了吗 bc80da0dce71164c7228b73d0ee15e5c.gif赞了吗 b1746c3f9b403fe71741a3847bc33f3e.gif在看吗
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值