RESTfulREST 与 RESTful 理解与实践

Posted Fxtack

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RESTfulREST 与 RESTful 理解与实践相关的知识,希望对你有一定的参考价值。

REST 与 RESTful 介绍与理解




一. REST 与 RESTful 简介

REST 全称表述性状态转移(Representational State Transfer)。是 Roy Fielding 博士在 2000 年发表的博士论文中提出的一种软件架构风格。REST 是一种针对于 Web Application 的设计和开发方式,其可以降低开发的复杂性,提高系统的可扩展性。REST 是一种设计风格,不是一种标准,是一种开发习惯、开发思想。

符合 REST 规范开发的应用被称为是 RESTful 的。RESTful 是一种面向资源的架构(Resource-Oriented Architecture)。


二. REST 架构原则

  • 网络上的所有事物都是资源(Resource)

    网络上有着各种各样的事物,可能是图像、视频、音频、文字,等。这些事物都被视为网络上的资源。

  • 每个资源都有一个唯一的资源标识符(URI)

    网络上的资源都拥有一个用于唯一定位该资源的资源标识符,即 URI(Universal Resource Identifier)。

    URI 与 URL 的区别


    统一资源定位符 URL(Universal Resource Locator)是 URI 的一部分。URI 由 URL 和 URN (Universal Resource Name,统一资源定位名) 构成。


    可以这样理解。URI 用于定位一个唯一的资源,而 URL 相当于资源的地址,而 URN 相当于资源的名称。通过确定资源的地址与名称,就可以唯一确定资源,因此 URI 是由 URL 与 URN 构成的。

  • 同一个资源具有多种表现形式 (Representation)

    网络上的资源可以通过多种方式呈现出来。我们将把资源具体呈现出来的形式叫做资源的 表现层 。例如:图片以 .png 文件格式呈现,也可以以 .jpg 格式呈现。

  • 对资源的各种操作不会改变资源标识符

    对于资源的增、删、查、改,等,操作不会改变资源的标识符。

  • 对于资源的各种操作是无状态的

    客户端对服务端的请求是无状态的,客户端的每一次请求会携带足够的信息让服务器识别,而不要求服务器在处理请求时检索任何类型的应用程序上下文或状态。无状态约束使得服务器的变化对客户端是透明的。这样使得客户端发起两次请求也不用依赖同一台服务器完成处理与服务。

    无状态的优缺点


    • 优点。 提高了服务器的健壮性与可扩展性,有利于负载均衡。
    • 缺点。 客户端每次请求必须携带上相同的、用于确定自身身份和状态的信息,提高了传输数据的冗余性。
  • 统一接口(Uniform Interface)

    REST 架构的核心。客户端只需要关系如何实现接口,加强了接口的可读性,方便开发人员调用与对接,有利于前后端分离。

    对于资源的各种操作使用一组有限的操作方法进行。HTTP 1.1 协议中的 7 个方法:

    方法作用
    GET获取资源
    POST新增资源
    PUT更新资源
    DELETE删除资源
    PATCH更新资源的属性
    TRACE回显服务器收到的请求,主要用于测试或诊断
    HEAD获取资源的元数据
    OPTIONS获取服务器支持的 HTTP 请求方法
    CONNECT要求在与代理服务器通信时建立隧道,实现用隧道协议进行 TCP 通信

    在 REST 中常用 GET、POST、PUT、PATCH、DELETE、方法。REST 中的状态转移(State Tramsfer)就是用这些方法来完成的。


通过统一的接口来进行请求,可以很好的完成前后端对接,避免为各种不同的端再重复定义接口。

例如,微博拥有多个用户端如:手机端、PC 端、微信小程序端,等。这些端前端实现各不相同,但是它们所调用的服务器接口是统一的 RESTful 规范接口。


三. 传统 API 与 RESTful API 对比

相比传统 API ,RESTful API 整洁统一。接下来以对产品 product 的操作接口为例进行比较。

操作类型传统 APIRESTful API
请求方法请求 URI请求方法请求 URI
查询所有产品GET/getProductsGET/products
查询 id 为 1 的产品GET/getProducts?id=1GET/products/1
添加新产品POST/addProductPOST/products
更新 id 为 1 的产品POST/updateProductPUT/products/1
更新 id 为 1 的产品的名字POST/updateProductNamePATCH/products/1
删除 id 为 1 的产品GET/deleteProduct?id=1DELETE/products/1

可见传统 API 多用动词,而 RESTful API 多用名词,动作由请求方法表示出来。

注意


PUTPATCH 方法同为更新,有何不同呢?

设想我们的产品对象是一个拥有大量属性的对象。若使用 PUT 更新,则发起请求时,我们需要一次上传一个完整的对象信息,相当于更新整个产品对象。也就是说,即便我只要更新我产品的数量,但是我还是要附上产品的其他属性,例如产地、厂家、型号、颜色等等。但我只更新产品的数量仅需要提供产品的 id 和更新后的数量即可,其他属性属于冗余,会给网络传输带来负担。

为了解决这一问题,就可以使用 PATCH 方法。PATCH 方法下只需要提供要更新的少许属性即可,从而完成部分属性的更新。这样减少了不必要的数据冗余,增加了网络通讯效率。


四. RESTful API 实践

用 Spring boot 简单实现 RESTful API。并与传统 API 实现进行对比。

  • RESTful API 实现

    package com.example.demo.controller;
    
    import org.springframework.web.bind.annotation.*;
    
    @RestController
    @CrossOrigin
    public class MainController {
    
    	@GetMapping("/products")
    	String getProducts() {
        	return "find";
    	}
    
    	@GetMapping("/products/{id}")
    	String getProduct(@PathVariable int id) {
        	return "find " + id;
    	}
    
    	@PostMapping("/products")
    	String addProduct(@RequestParam int id, @RequestParam String name, @RequestParam int number) {
        	return "Add" + " id:" + id + " name:" + name + " number" + number;
    	}
    
    	@PutMapping("/products/{id}")
    	String updateProduct(@PathVariable int id, @RequestParam String name, @RequestParam int number) {
        	return "Update " + " id:" + id + " name:" + name + " number:" + number;
    	}
    
    	@PatchMapping("/products/{id}")
    	String updateProductName(@PathVariable int id, @RequestParam String name) {
        	return "Update " + " id:" + id + " name:" + name;
    	}
    
    	@DeleteMapping("/products/{id}")
    	String deleteProduct(@PathVariable int id) {
        	return "Delete " + "id:" + id;
    	}
    }
    
  • 传统 API 实现

    package com.example.demo.controller;
    
    import org.springframework.web.bind.annotation.*;
    
    @RestController
    @CrossOrigin
    public class OldController {
    
    	@GetMapping("/getProducts")
    	String getProducts() {
        	return "find";
    	}
    
    	@GetMapping("/getProduct")
    	String getProduct(@RequestParam String id) {
        	return "find " + id;
    	}
    
    	@PostMapping("/addProduct")
    	String addProduct(@RequestParam int id, @RequestParam String name, @RequestParam int number) {
        	return "Add" + " id:" + id + " name:" + name + " number" + number;
    	}
    
    	@PostMapping("/updateProduct")
    	String updateProduct(@RequestParam int id, @RequestParam String name, @RequestParam int number) {
        	return "Update " + " id:" + id + " name:" + name + " number:" + number;
    	}
    
    	@PostMapping("/updateProductName")
    	String updateProductName(@RequestParam int id, @RequestParam String name) {
        	return "Update " + " id:" + id + " name:" + name;
    	}
    
    	@GetMapping("/deleteProduct")
    	String deleteProduct(@RequestParam int id){
        	return "Delete " + "id:" + id;
    	}
    }
    

使用 IDEA 的 REST Client 对 RESTful API 进行测试。HTTP 请求文件如下。

提示


CSDN 文章编辑器中没有 .http 文件对应的代码块着色。因此笔者在这里使用了看上去较为合适的 python 代码块着色。在此说明避免读者迷惑。

### 获取所有产品
GET http://localhost:8080/products
Accept: */*
Cache-Control: no-cache

### 获取 id 为 1 的产品
GET http://localhost:8080/products/1
Accept: */*
Cache-Control: no-cache

### 添加新产品
POST http://localhost:8080/products
Accept: */*
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded; charset=UTF-8

id=5&name="BOOK"&number=10

### 更新 id 为 5 的产品信息
PUT http://localhost:8080/products/5
Accept: */*
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded; charset=UTF-8

name="BOOK"&number=15

### 更新 id 为 5 的产品的数量信息
PATCH http://localhost:8080/products/5
Accept: */*
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded; charset=UTF-8

number=20

### 删除 id 为 5 的产品
DELETE http://localhost:8080/products/5
Accept: */*
Cache-Control: no-cache

请求测试尽数通过

在这里插入图片描述


相关文献


文章内容来自个人学习总结
欢迎指出本笔记中存在的问题
未经本人同意禁止转载,不得用于商业用途

以上是关于RESTfulREST 与 RESTful 理解与实践的主要内容,如果未能解决你的问题,请参考以下文章

RESTfulREST 与 RESTful 理解与实践

RESTful 规范

RESTful规范

restful规范

$Django RESTful规范

RestFul接口设计