现代网站愈来愈多的使用先后端分离架构,先用前端 MVC 框架快速堆砌出 SPA,再用 API 获取动态数据也已经成为平常的开发内容;而用来链接先后端的 API,其重要性也天然言而喻。作为一个前端码农,认识后端的 API 设计方式也是很重要的,今天让咱们针对 API 设计来一探究竟。html
毕竟是网站的先后端,其中间的通信终究仍是要依赖 HTTP 这个无状态的协议;在 HTTP 规范中定义了一系列的请求方法,其中较经常使用的以下:前端
GET
同为获取资源,但只取回 Header在规范中也提到,不一样的方法指的是对同一件事作不一样的操做,并经过语意化的方法,让不一样的操做获得预期的结果。程序员
你们对 GET
、POST
都不陌生,这是 HTML 的<form action="...">
所支持的两个方法;GET
是使用最频繁的,不管是获取得页面仍是数据,通常都会用 GET
,而 POST
则经常使用在新增资源上,但因为 HTML <form action="...">
不支持其余方法,在传统网站中可能会用 POST
处里除了获取数据以外的全部事情。面试
PUT
和 PATCH
一般都用在更新资源上,二者的差别是 PUT
的行为是取代整个资源,而 PATCH
则是更新部分资源;把二者对应到平常生活中的话,就比如在餐厅吃饭,整桌菜从新点是 PUT
,另外加菜是 PATCH
。segmentfault
DELETE
一般用在删除资源;HEAD
与 GET
相似,但只取回 Header,一般用在测试资源是否存在上;OPTION
是询问这个资源应该要怎样获取,一般用在发送 CORS 的预检(preflight)请求。后端
目前讲的都是在规范中提到且建议的通常用法,实际服务器的 API 怎么开发依然是看实现的人;但经过语意化的方法去设计 API,绝对可让 API 对开发者更加友好。浏览器
前面所说只是规范,并且只涉及到了 HTTP 方法;有没有更完整的实现方法呢?缓存
固然有,这就是你们耳熟能详的 RESTFul API;它由 Roy Fieldin 在 IEFT 开发HTTP 标准的六年间持续研究、验证的,并在 2000 年在他的博士论文 《Architectural Styles and the Design of Network-based Software Architectures》 中所提出,是一种网络程序的设计风格;所谓的 REST 是 表现层状态转换(Resource Representational State Transfer) 的缩写,简单说就是经过动词(HTTP 方法)、名词(URI/URL,表明目标资源)、内容型态(响应的内容,如 HTML、XML、JSON 等),让无状态的网络通讯能经过 REST 的语意化设计,携带全部的状态进行通讯,下降对网络的重复请求而形成的资源消耗。bash
例如假设有一个视频网站: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 规范中提到要如何正确使用方法,若是咱们没有按照规范实现,会形成必定的影响。
浏览器默认会对 GET
、HEAD
这两个方法作缓存,若是经过 POST
而不是 GET
获取资源的话,浏览器及中间的代理服务器通常都不会实现缓存机制,这时就必须由先后端开发自行经过其余方式设置缓存。
在规范中虽然也提到了POST
在 Header 合适的状况下也能够缓存,但因为实际上一般把POST
用在新增操做上,作缓存的话反而会形成不可预期的后果,大部分浏览器也都没有实现针对POST
的缓存机制。
当搜索引擎的爬虫在扫网站时,若是发现须要经过 POST
获取的资源,为了不形成意外的行为或反作用,一般不会尝试爬取 POST
响应的结果。
虽然 RESTful API 的设计风格优势不少,但也有一些难以免的缺点。
例如在查找存在依赖关系的嵌套数据时,颇有可能必需要通过屡次请求想要才能找到想要的结果;而随着项目架构逐渐扩张,同一页面的资料也会愈来愈复杂,可能须要多个来源的资料才能堆砌出页面,这时候 RESTful API 须要说明每一个资源位置的特性,就会使 RESTful API 显得不太好用;也由于如今移动设备很是普及,一个后端服务器可能须要服务于 PC 版网页、手机 APP 等多设备的需求,须要的数据可能不同,RESTful API 也就必需要实现出多个功能相似的接口,API 会逐渐变得庞大并且庞杂,相对难以管理。
有需求就会有解决的方法。这时 GraphQL 就应运而生了,这是由 Facebook 提出的开源语言标准,经过 Schema 定义资料,再依靠与 JSON 格式高度相似的查询语句取得查询的结果,它的主要特色是:
这些特性有效的解决了 RESTful API 在复杂架构下的问题,使 GraphQL 充满弹性、很是好用,社区也已经有了庞大的的生态系统支持,例如 Apollo GraphQL 能够与三大框架深度整合,再加上多查询合并的特性,让 GraphQL 与现代框架中组件的概念完美契合。
缺点大概就是必需要把全部复杂的数据拼接逻辑都实如今后端,对于习惯于 RESTful API 的开发者来讲,须要付出很多学习成本。
值得注意的是 GraphQL 发出的所有都是 POST
请求,缓存机制必须仰赖开发者或是框架实现;例如在 Apollo Client 中,开发者必须按照应用场景,调整 fetchPolicy
的设置,避免快取形成的意外结果。
本文的标题是我一位朋友去面试某大厂后端时的一道面试题,由这个题目引伸出 HTTP 方法及主流的 RESTful API 设计风格,并对 GraphQL 作了简短的介绍,但愿以上内容可以帮到你。