浅谈我对RESTful架构的理解

 

总结说在前面:

RESTful API是目前比较成熟的一套互联网应用程序的 API 设计理论,他是一种理论规范,方便不同的前端设备与后端进行通信,在 RESTful 风格的 API 设计架构中,每个网址代表一种资源(resource)

对于资源的具体操作类型,由 HTTP 动词表示,此处也就是不同的 HTTP 方法,常见的操作资源的 HTTP 方法有 GET(获取资源),POST(新增资源),PUT(更新资源整体),PATCH(更新资源局部一些属性),DELETE(删除资源)

  • RESTful 架构有一些典型的设计误区。
    • 最常见的一种设计错误,就是 URI 包含动词因为 "资源" 表示一种实体,所以应该是名词,URI 不应该有动词,动词应该放在 HTTP 协议中。
    • 另一个设计误区,就是在 URI 中加入版本号因为不同的版本,可以理解成同一种资源的不同表现形式,所以应该采用同一个 URI。至于版本号,可以在 HTTP 请求头信息的 Accept 字段中进行区分

网络应用程序,分为前端和后端两个部分。当前的发展趋势,就是前端设备层出不穷(手机、平板、桌面电脑、其他专用设备......)。

因此,必须有一种统一的机制,方便不同的前端设备与后端进行通信。这导致 API 构架的流行,甚至出现 "API First" 的设计思想。RESTful API 是目前比较成熟的一套互联网应用程序的 API 设计理论。

越来越多的人开始意识到,网站即软件,而且是一种新型的软件。

这种 "互联网软件" 采用客户端 / 服务器模式,建立在分布式体系上,通过互联网通信,具有高延时(high latency)、高并发等特点。

网站开发,完全可以采用软件开发的模式。但是传统上,软件和网络是两个不同的领域,很少有交集;软件开发主要针对单机环境,网络则主要研究系统之间的通信。互联网的兴起,使得这两个领域开始融合,现在我们必须考虑,如何开发在互联网环境中使用的软件。

RESTful 架构,就是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。

但是,到底什么是 RESTful 架构,并不是一个容易说清楚的问题。下面,我就谈谈我理解的 RESTful 架构。

一、协议

API 与用户的通信协议,总是使用 HTTPS协议。

二、域名

应该尽量将 API 部署在专用域名之下。

https://api.example.com

如果确定 API 很简单,不会有进一步扩展,可以考虑放在主域名下。

https://example.org/api/

三、版本(Versioning)

应该将 API 的版本号放入 URL。

https://api.example.com/v1/

另一种做法是,将版本号放在 HTTP 头信息中,但不如放入 URL 方便和直观。Github 采用这种做法。

四、路径(Endpoint)

路径又称 "终点"(endpoint),表示 API 的具体网址。

在 RESTful 架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。一般来说,数据库中的表都是同种记录的 "集合"(collection),所以 API 中的名词也应该使用复数。

举例来说,有一个 API 提供动物园(zoo)的信息,还包括各种动物和雇员的信息,则它的路径应该设计成下面这样。

  • https://api.example.com/v1/zoos
  • https://api.example.com/v1/animals
  • https://api.example.com/v1/employees

五、HTTP 动词

对于资源的具体操作类型,由 HTTP 动词表示。

常用的 HTTP 动词有下面五个(括号里是对应的 SQL 命令)。

  • GET(SELECT):从服务器取出资源(一项或多项)。
  • POST(CREATE):在服务器新建一个资源。
  • PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
  • PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
  • DELETE(DELETE):从服务器删除资源。

还有两个不常用的 HTTP 动词。

  • HEAD:获取资源的元数据。
  • OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。

下面是一些例子。

  • GET /zoos:列出所有动物园
  • POST /zoos:新建一个动物园
  • GET /zoos/ID:获取某个指定动物园的信息
  • PUT /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息)
  • PATCH /zoos/ID:更新某个指定动物园的信息(提供该动物园的部分信息)
  • DELETE /zoos/ID:删除某个动物园
  • GET /zoos/ID/animals:列出某个指定动物园的所有动物
  • DELETE /zoos/ID/animals/ID:删除某个指定动物园的指定动物

六、过滤信息(Filtering)

如果记录数量很多,服务器不可能都将它们返回给用户。API 应该提供参数,过滤返回结果。

下面是一些常见的参数。

  • ?limit=10:指定返回记录的数量
  • ?offset=10:指定返回记录的开始位置。
  • ?page=2&per_page=100:指定第几页,以及每页的记录数。
  • ?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
  • ?animal_type_id=1:指定筛选条件

参数的设计允许存在冗余,即允许 API 路径和 URL 参数偶尔有重复。比如,GET /zoo/ID/animals 与 GET /animals?zoo_id=ID 的含义是相同的。

七、状态码(Status Codes)

服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的 HTTP 动词)。

  • 200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
  • 201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
  • 202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
  • 204 NO CONTENT - [DELETE]:用户删除数据成功。
  • 400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
  • 401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
  • 403 Forbidden - [*] 表示用户得到授权(与 401 错误相对),但是访问是被禁止的。
  • 404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
  • 406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求 JSON 格式,但是只有 XML 格式)。
  • 410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
  • 422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
  • 500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

状态码的完全列表参见这里。

八、错误处理(Error handling)

如果状态码是 4xx,就应该向用户返回出错信息。一般来说,返回的信息中将 error 作为键名,出错信息作为键值即可。

{error: "Invalid API key"
}

九、返回结果

针对不同操作,服务器向用户返回的结果应该符合以下规范。

  • GET /collection:返回资源对象的列表(数组)
  • GET /collection/resource:返回单个资源对象
  • POST /collection:返回新生成的资源对象
  • PUT /collection/resource:返回完整的资源对象
  • PATCH /collection/resource:返回完整的资源对象
  • DELETE /collection/resource:返回一个空文档

十、综述

综合上面的解释,我们总结一下什么是 RESTful 架构:

  (1)每一个 URI 代表一种资源;

  (2)客户端和服务器之间,传递这种资源的某种表现层;

  (3)客户端通过五个 HTTP 动词,对服务器端资源进行操作,实现 "表现层状态转化"。

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

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

相关文章

maven介绍 搭建Nexus3(maven私服搭建)

Maven是一个强大的项目管理工具,它基于项目对象模型(POM:Project Object Model)的概念,通过XML格式的配置文件(pom.xml)来管理项目的构建 Maven确实可以被视为一种工程管理工具或项目自动化构…

飞凌嵌入式技术创新日深圳站,8月26日见!

飞凌嵌入式技术创新日(深圳站)将于8月26日举行,一场嵌入式前沿科技的高端局就在眼前。届时,将有多位重量级技术大咖出席,为大家分享最新的研究成果、独到的行业见解和典型的应用案例,紧密结合当前行业热点和…

网络服务综合项目(一键部署shell脚本)

目录 需求: 主机环境描述 注意: 项目需求: 代码讲解 配置本地仓库 安装软件包 配置防火墙 配置策略中的一个布尔值 配置web服务 配置网络仓库 配置DNS服务 配置NTP服务 配置MySQL服务 配置NFS服务 配置论坛服务 进入网站配置…

Python数据分析案例55——基于LSTM结构自编码器的多变量时间序列异常值监测

案例背景 时间序列的异常值检测是方兴未艾的话题。比如很多单变量的,一条风速,一条用电量这种做时间序列异常值检测,想查看一下哪个时间点的用电量异常。 多变量时间序列由不同变量随时间变化的序列组成,这些时间序列在实际应用…

小黄人欢乐来袭,国漫萌物大集结

最近上映的《神偷奶爸》4不知道大家有没有去看,小黄人作为该系列电影的标志性角色,继续以其呆萌可爱的形象和幽默搞怪的性格赢得了观众的喜爱。 在中国动漫中,也有许多可爱且深受观众喜爱的萌物角色。这些角色以其独特的形象、有趣的性格和与…

数据结构day6

一、思维导图 二、模拟面试 typedef定义函数指针的方式typedef int(*p)(int,int);对void*指针的理解,相关应用万能指针,可以定义形参用来接收任意类型的指针变量,也可以定义函数用来返回任意类型的指针变量例如malloc函数在堆区申请内存&…

HTTP协议和RPC协议的区别是什么

从功能层面来说,HTTP协议是一个应用层的超文本传输协议,它是万维网数据通信的一个基础,主要服务在网页端和服务端的一个数据传输上。而RPC是一个远程过程调用协议,它是定位在实现分布式应用之间的一个数据通信,屏蔽了通…

SpringBoot入门:如何新建SpringBoot项目(保姆级教程)

在本文中,我们将演示如何新建一个基本的 Spring Boot 项目。写这篇文章的时候我还是很惊讶的,因为我发现有些java的初学者,甚至工作10年的老员工居然并不会新建一个SpringBoot项目,所以特别出了一篇文章来教大家新建一个SpringBoo…

数据挖掘-数据预处理

来自🥬🐶程序员 Truraly | 田园 的博客,最新文章首发于:田园幻想乡 | 原文链接 | github (欢迎关注) 文章目录 3.3.1 数据的中心趋势平均数和加权平均数众数,中位数和均值描述数据的离散程度 &a…

VSCode | 修改编辑器注释的颜色

1 打开VsCode的设置进入settings.json 2 添加如下代码 "editor.tokenColorCustomizations": {"comments": "#17e917"},3 保存即可生效

Linux源码阅读笔记14-IO体系结构与访问设备

IO体系结构 与外设通信通常称为输入输出,一般缩写为I/O。在实现外设IO的时候,内核必须处理三个可能出现的问题: 必须根据具体的设备类型和模型,使用各种方法对硬件寻址。内核必须向用户应用程序和系统工具提供访问各种设备的方法…

hugging face 使用教程———快速入门

概述 本篇存在的意义是快速介绍hugging face使用,梳理主要部件,梳理易混淆概念。原因是:目前hugging face的使用,官方放在了3个地方(参考链接部分):使用文档、NLP教程、Transformers git的readm…

Vue3+Element Plus 实现table表格中input的验证

实现效果 html部分 <template><div class"table"><el-form ref"tableFormRef" :model"form"><el-table :data"form.detailList"><el-table-column type"selection" width"55" align&…

基于springboot+vue+uniapp的养老院系统小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

repo 工具安装和使用教程(windows+gitee)

repo是什么 官方的定义&#xff1a;Repo是谷歌用python脚本写的调用git的一个脚本&#xff0c;可以实现管理多个git库。 Android的源代码使用Repo 命令行工具来管理多个git仓库&#xff0c;大概有百多个。要想克隆和管理百多个 Git 仓库&#xff0c;不是一件简单的事情。Repo 命…

LoRaWAN网络中的chirpstack

目录 一、chirpstack介绍 二、网关与chirpstack之间的通信 三、NS与AS之间的通信 1、Protobuf 2、gRPC 一、chirpstack介绍 ChirpStack 是一个开源的 LoRaWAN 网络服务器&#xff0c;可用于 设置私有或公共 LoRaWAN 网络。ChirpStack 提供了一个 Web 界面 用于管理网关、设…

HBuilder X中配置vue-cli项目和UI库

目录 一.前端项目结构 二.在HBuilder X中搭建vue-cli项目 1. 安装node.js前端环境 2. HBuilder X创建一个vue-cli项目 3. vue-cli项目结构 4. 如何运行前端项目 5. 创建组件 6. 组件路由(页面跳转) 6.1 创建router目录 6.2 使用路由 6.3 在main.js中配置路由 6.4 路…

【IoTDB 线上小课 05】时序数据文件 TsFile 三问“解密”!

【IoTDB 视频小课】持续更新&#xff01;第五期来啦~ 关于 IoTDB&#xff0c;关于物联网&#xff0c;关于时序数据库&#xff0c;关于开源... 一个问题重点&#xff0c;3-5 分钟详细展开&#xff0c;为大家清晰解惑&#xff1a; IoTDB 的 TsFile 科普&#xff01; 了解了时序数…

系统移植(三)u-boot移植 ① 相关概念

文章目录 一、u-boot概念&#xff08;一&#xff09;概念&#xff08;二&#xff09;获取u-boot源码1.从u-boot官网获取2. 从 STM官网3. 开发板厂商获取 &#xff08;三&#xff09;分析u-boot源码1. u-boot源码的目录结构2. 获取make的帮助信息3. 分析README文件 &#xff08;…

讨逆猴子剪切板,浏览器复制失败?

讨逆猴子剪切板&#xff0c;复制失败&#xff1f; 问题&#xff1a;本地开发情况下可以直接复制&#xff0c;公网就不行了…触发了安全机制。 const link 内容;navigator.clipboard.writeText(link);报错&#xff1a; 解决方案&#xff1a; if (navigator.clipboard &&…