您的当前位置:首页>全部文章>文章详情

【PHP】RestFul简介和使用

CrazyPanda发表于:2024-05-24 23:38:31浏览:216次TAG:

1.1 RestFul简介

REST全称是(Resource) Representational State Transfer,翻译过来为“资源代表状态转移”,中文意思是表述性状态转移。它首次出现在2000年Roy Fielding的博士论文中,Roy Fielding是HTTP规范的主要编写者之一。 他在论文中提到:“我这篇文章的写作目的,就是想在符合架构原理的前提下,理解和评估以网络为基础的应用软件的架构设计,得到一个功能强、性能好、适宜通信的架构。REST指的是一组架构约束条件原则不是标准不是规范。” 如果一个架构符合REST的约束条件和原则,我们就称它为RESTful架构。

RestFul: 是一种以网络为基础构架一种架构风格 一个架构符合Rest设计原则和约束称这个架构为RestFul

Rest 词: 并没有 更新技术 组件 服务 让我们web请求能够利用web中标准 和 能力 更好描述架构

REST本身并没有创造新的技术、组件或服务,而隐藏在RESTful背后的理念就是使用Web的现有特征和能力, 更好地使用现有Web标准中的一些准则和约束。虽然REST本身受Web技术的影响很深, 但是理论上REST架构风格并不是绑定在HTTP上,只不过目前HTTP是唯一与REST相关的实例。 所以我们这里描述的REST也是通过HTTP实现的REST。

总结

Restful 一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

web开发: 实现所有功能

restful: 软件设计风格 标准 简洁 层次 优雅

符合rest设计原则和约束的架构称之为restFul

URL定义

  • 资源:互联网所有的事物都可以被抽象为资源

    • 一首歌 一张图片 数据库一条记录

  • 资源操作:使用POST(添加)、DELETE(删除)、PUT(修改)、GET(查询),使用不同请求方法对资源进行操作。

    • 删除 delete

    • 查询 get

    • 添加 post

    • 修改 put (修改全部字段)| patch(更新部分字段)

1.2 传统方式与RESTful操作资源对比

传统方式操作资源

  • http://127.0.0.1/item/queryUser.action?id=1 查询,GET

  • http://127.0.0.1/item/saveUser.action 新增,POST

  • http://127.0.0.1/item/updateUser.action 更新,PUT

  • http://127.0.0.1/item/deleteUser.action?id=1 删除,DELETE

    注意:传统的操作是没有问题的,大神认为是有问题的,有什么问题呢?你每次请求的接口或者地址,都在做描述,例如查询的时候用了queryUser,新增的时候用了saveUser ,修改的时候用了updateUser,其实完全没有这个必要,我使用了get请求,就是查询.使用post请求,就是新增的请求,PUT就是修改,delete就是删除,我的意图很明显,完全没有必要做描述,这就是为什么有了restful.

使用RESTful操作资源

  • 【GET】 /users # 查询用户信息列表

  • 【GET】 /users/1001 # 查看某个用户信息

  • 【POST】 /users # 新建用户信息

  • 【PUT】 /users/1001 # 更新用户信息(全部字段)

  • 【PATCH】 /users/1001 # 更新用户信息(部分字段)

  • 【DELETE】 /users/1001 # 删除用户信息

Rest API设计风格原则

# 1.使用名词而不是动词
- 不要使用:
	如:
    /getAllUsers    get   /users  get /users/002
    /createNewUser  post  /users
    /deleteAllUser  delete /users/001

# 2.Get方法和查询参数不应该涉及状态改变
- 使用PUT, POST 和DELETE 方法 而不是 GET 方法来改变状态,不要使用GET 进行状态改变


# 3.使用复数名词
- 不要混淆名词单数和复数,为了保持简单,只对所有资源使用复数。
	如:
    /cars 而不是 /car
    /users 而不是 /user
    /products 而不是 /product
    /settings 而不是 /setting
    /orders   而不是 /order
		
# 4. 使用子资源表达关系
- 如果一个资源与另外一个资源有关系,使用子资源:
	如:
    GET /cars/711/drivers/ 返回 car 711的所有司机
    GET /cars/711/drivers/4 返回 car 711的4号司机
    GET /users/11/pets      返回 user 11的所有宠物
    GET /users/11/pets/2    返回 user 11的2号宠物

# 5.使用Http头声明序列化格式
- 在客户端和服务端,双方都要知道通讯的格式,格式在HTTP-Header中指定
	对于controller:
	Accept 定义接受的类型
	Content-Type 定义响应类型


# 6.为集合提供过滤 排序 选择和分页等功能
- Filtering过滤:使用唯一的查询参数进行
	GET /cars?color=red 返回红色的cars
	GET /cars?seats<=2 返回小于两座位的cars集合

- Sorting排序:允许针对多个字段排序
	GET /cars?sort=-manufactorer,+model
	这是返回根据生产者降序和模型升序排列的car集合

- Field selection
	移动端能够显示其中一些字段,它们其实不需要一个资源的所有字段,给API消费者一个选择字段的能力,这会降低网络流量,提高API可用性。
	GET /cars?fields=manufacturer,model,id,color
	
- Paging分页
	使用 limit 和offset.实现分页,缺省limit=20 和offset=0;
	GET /cars?offset=10&limit=5
	为了将总数发给客户端,使用订制的HTTP头: X-Total-Count.
	链接到下一页或上一页可以在HTTP头的link规定,遵循Link规定:
	Link: <https://blog.mwaysolutions.com/sample/api/v1/cars?offset=15&limit=5>; rel="next",<https://blog.mwaysolutions.com/sample/api/v1/cars?offset=50&limit=3>; rel="last",<https://blog.mwaysolutions.com/sample/api/v1/cars?offset=0&limit=5>; rel="first",<https://blog.mwaysolutions.com/sample/api/v1/cars?offset=5&limit=5>; rel="prev",
	

# 7.版本化你的API  支付宝  v1  v2   v3
- 使得API版本变得强制性,不要发布无版本的API,使用简单数字,避免小数点如2.5.
	一般在Url后面使用?v
	/blog/api/v1

# 8. 使用Http状态码处理错误
- 如果你的API没有错误处理是很难的,只是返回500和出错堆栈不一定有用
- Http状态码提供70个出错,我们只要使用10个左右:
 	`200 – OK – 一切正常
  `201 – OK – 新的资源已经成功创建
  `204 – OK – 资源已经成功删除
  `304 – Not Modified – 客户端使用缓存数据
  `400 – Bad Request – 请求无效,需要附加细节解释如 "JSON无效"
  `401 – Unauthorized – 请求需要用户验证
  `403 – Forbidden – 服务器已经理解了请求,但是拒绝服务或这种请求的访问是不允许的。
  `404 – Not found – 没有发现该资源
  `422 – Unprocessable Entity – 只有服务器不能处理实体时使用,比如图像不能被格式化,或者重要字段丢失。
  `500 – Internal Server Error – API开发者应该避免这种错误。
使用详细的错误包装错误:  状态码  错误信息      正确:状态码  +  数据  复杂的话还有header头信息
{
  "errors": [
   {
    "userMessage": "Sorry, the requested resource does not exist",		// 错误信息
    "internalMessage": "No car found in the database",
    "code": 34,			// 状态码
    "more info": "http://dev.mwaysolutions.com/blog/api/v1/errors/12345"	// 错误链接
   }
  ]
}

传统方式操作资源会在控制器方法上使用@RequestMapping注解来接收添加、删除、更新、查询的请求,

RestFul方式操作资源会在方法上使用@PostMapping注解专门来接收添加请求

使用@DeleteMapping注解专门来接收删除请求

使用@PutMapping注解专门来接收更新请求(全部字段)|@PatchMapping(部分字段)

使用@GetMapping注解专门来接收查询请求

这样的话对于每一种方法都有唯一类型的请求,而不是使用@RequestMapping注解可以接受所有类型的请求,RestFul更加标准

1.3 使用RestFul方式开发Controller

用到的包结构

1.png

用到的资源类

User

public class User {

    private Integer id;
    private String name;
    private Double salary;
    private Date bir;

  	// 以免影响阅读体验构造方法、get、set方法没有粘,但是是有的
}

Pet

public class Pet {

    private Integer id;
    private String name;
    private Integer age;

		// 以免影响阅读体验构造方法、get、set方法没有粘,但是是有的
}

开发Controller

UserController

//@RestController  // @RestController: 专用于restful风格的注解 = @Controller (控制器) + @ResponseBody (方法返回值为json)
@RestController
@RequestMapping("/v1/users")
public class UserController {

    private static final Logger log = LoggerFactory.getLogger(UserController.class);

    // ResponseEntity:springmvc封装的专用于restful的响应类 这个类在响应时可以提供响应的状态码,同时还可以自定义响应头信息

    // HttpStatus:  springmvc封装的一个枚举类  这个类中都是网络中状态码

    /**
     * 查询某个用户详细
     * @param id
     * @return
     */
    @GetMapping("/{id}")   // 也可以写成@RequestMapping(value = "/{id}", method = RequestMethod.GET)
    // @GetMapping是@RequestMapping的子类注解,使用@GetMapping代表只能使用GET方式访问到当前请求
    // @GetMapping的参数这里不能写死,日后需要传一个参数,所以写一个占位id
    // @PathVariable注解:代表在路径中获取请求参数  (不获取form表单了也不获取问号后面的了)
    // @PathVariable注解的value属性写获取路径中的哪个参数,获取上面@GetMapping("/{id}")中的id
    // Integer id  接收路径中的参数
    //@ResponseBody   // 将控制器方法返回值转为json
    public ResponseEntity<User> user(@PathVariable("id")  Integer id){
        log.info("本次id: {}", id);
        User user = new User(id, "小陈", 2300.23, new Date());
        return new ResponseEntity<>(user, HttpStatus.OK);
        // 第一个参数是body是什么
        // 第二个参数是状态码是什么  HttpStatus.OK :代表返回成功
    }

    /**
     * 用户列表
     * @return
     */
    @GetMapping
    //@ResponseBody
    public ResponseEntity<List<User>> users(){
        List<User> users = new ArrayList<>();
        users.add(new User(21, "小王", 2300.23, new Date()));
        users.add(new User(24, "小金豆", 3400.23, new Date()));
        return new ResponseEntity<>(users, HttpStatus.OK);
    }

    /**
     * 添加用户
     * @param user
     */
    @PostMapping
    //@ResponseBody
    // @ResponseBody 将方法返回值转为json格式数据 并响应请求
    // @RequestBody: 接收请求的json格式数据 将json格式数据转化为对象
    public ResponseEntity<Void> save(@RequestBody User user){   // 只接受json
        log.info("name:{}, salary:{}, bir:{}", user.getName(), user.getSalary(), user.getBir());
        // 调用业务方法
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        // 查询成功返回状态码为 HttpStatus.NO_CONTENT : 没有内容
    }

    /**
     * 更新用户
     * @param user
     */
    @PutMapping("/{id}")         // 全字段更新
    //@ResponseBody
    // @PathVariable 从路径中获取
    // @RequestBody 从响应体获取
    public ResponseEntity<Void> update(@PathVariable("id") Integer id, @RequestBody User user){
        log.debug("id: {}", id);
        log.info("name:{}, salary:{}, bir:{}", user.getName(), user.getSalary(), user.getBir());
        // 调用业务方法
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        // 更新成功返回状态码为 HttpStatus.NO_CONTENT : 没有内容
    }

    /**
     * 删除用户
     * @param id
     */
    @DeleteMapping("/{id}")
    //@ResponseBody
    public ResponseEntity<Void> delete(@PathVariable("id") Integer id){
        log.info("本次id: {}", id);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        // 更新成功返回状态码为 HttpStatus.NO_CONTENT : 没有内容
    }

    /**
     * 获取这个人的所有宠物
     * @return
     */
    @GetMapping("/{id}/pets")
    public ResponseEntity<List<Pet>> pets(@PathVariable("id") Integer id){
        log.info("查询哪个人id: {}", id);
        List<Pet> pets = Arrays.asList(new Pet(21, "小红帽", 23), new Pet(22, "小猪", 22));
        return new ResponseEntity<>(pets, HttpStatus.OK);
    }

    /**
     * 获取这个人的某个宠物
     * @return
     */
    @GetMapping("/{id}/pets/{pid}")
    public ResponseEntity<Pet> pet(@PathVariable("id") Integer id, @PathVariable("pid") Integer petId){
        log.info("查询哪个人id: {}", id);
        Pet pet = new Pet(21, "小红帽", 23);
        return new ResponseEntity<>(pet, HttpStatus.OK);
    }
}

1.4 具体分析和测试

因为测试时要用到Postman软件,官网下载又极慢,所以这里提供了百度网盘的链接:

链接:Postman安装包
提取码:dnbf

1.4.0 前提了解

在这里插入图片描述


1.png


用到的注解:

  • @GetMapping:方法加上这个注解之后方法只能接受GET请求

  • @PostMapping:方法加上这个注解之后方法只能接受POST请求

  • @PutMapping:方法加上这个注解之后方法只能接受PUT请求

  • @DeleteMapping:方法加上这个注解之后方法只能接受DELETE请求

  • @PathVariable:在方法前参数前加上这个用来获取路径中数据给参数

  • @RequestBody:在方法前加上这个数据代表这个数据从路径中接受的话只能接受json形式的数据

  • @ResponseBody:将控制器方法的返回值转化为json

用到的类:

ResponseEntity:springmvc封装的专用于restful的响应类 这个类在响应时可以提供响应的状态码,同时还可以自定义响应头信息

HttpStatus: springmvc封装的一个枚举类 这个类中都是网络中状态码

注:

路径中获取数据不等于在url中以问号拼接数据,而是

http://localhost:8080/v1/users/100 后面的100就是路径中的数据

过滤、排序、分页、选择字段时用 ? 号传参

1.4.1 查询某个用户信息

1.png

1.png

1.4.2 查询用户列表

1.png

1.png

1.4.3 添加用户

1.png

1.png

日志中的数据

1.png

1.4.4 测试更新

1.png

1.png

日志中的内容

1.png

1.4.5 测试删除

1.png

1.png

1.png

1.5 User与Pet之间的关联关系

User可以有多个Pet,但是一个Pet只能属于一个User

1.png

1.png

猜你喜欢

【PHP】PHP开发中如何使用Nginx实现负载均衡
在现代web应用开发中,高并发访问是一个必须要面对的挑战。负载均衡是解决这个问题的一种有效的方案。在php开发中,使用nginx实现负载均衡是一个非常常见的方法。本文将详细介绍如何在php开发中使用nginx实现负载均衡。一、Nginx及负载均衡的基本概念NginxNginx是一款轻量级的高性能的web服务器和反向代理服务器。它的出现解决了Apache这样的传统web服务器在高并发访问下的性能瓶颈。Nginx具有极高的性能、稳定性和安全性,并且支持大量的并发连接。负载均衡负载均衡是一种将网络流量
发表于:2024-05-29 浏览:334 TAG:
【PHP】php中的compact()的用法
compact()参数有两种变量名的字符串形式数组的变量名变量名的字符串$city&nbsp;&nbsp;=&nbsp;&quot;San&nbsp;Francisco&quot;; $state&nbsp;=&nbsp;&quot;CA&quot;; $event&nbsp;=&nbsp;&quot;SIGGRAPH&quot;; $location=[&quot;city&quot;,&#39;state&#39;]; $result=compact(&#39;city&#39;,&#39;
发表于:2024-09-07 浏览:409 TAG: #php #compact
【PHP】php8的扩展arginfo生成工具之使用初体验
hp8提供了非常方便的扩展函数或类参数信息的生成工具。只需要维护一份xyz.stub.php,就可以使用工具生成 xyz_arginfo.h。毫无疑问,这种方式,又降低了广大 phper 开发扩展的门槛,更易维护。上手体验:生成扩展骨架。cd&nbsp;ext php&nbsp;ext_skel.php&nbsp;--ext&nbsp;test随便添加一个函数,更改 test.stub.php。&lt;?php &nbsp; /**&nbsp;@generate-function-entrie
发表于:2024-01-01 浏览:286 TAG:
【PHP】微信JSAPI支付V3版本
article class="baidu_pl"><div id="article_content" class="article_content clearfix"><link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/kdoc_html_views-1a98987dfd.css"/><link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/ck_htmledit_views-044f2cf1dc.css"/></div></article><!--autointro--
发表于:2023-12-01 浏览:667 TAG:
【PHP】PHP 8.3 重磅发布:创新与增强,开创未来
PHP 8.3 于 2023 年 11 月 23 日发布,标志着该语言的发展又迈出了重要的一步。该版本引入了许多新功能、性能改进和弃用,旨在增强 PHP 开发体验。在这份综合指南中,我们将深入探讨这些更新,提供见解、技巧和创造性的代码示例,以帮助您适应并充分利用 PHP 8.3。只读类的增强PHP 8.3 对只读类的克隆行为进行了修改,允许在克隆期间重新初始化只读属性。这一更改解决了深度克隆中的特定边缘情况。参考以下示例:12345678910class Article {&nbsp;
发表于:2023-12-04 浏览:640 TAG:
【PHP】tp使用lunar-php,获取节日节气
lunar-php 是一个用于获取公历和农历(即阳历和阴历)信息的 PHP 库。要使用 lunar-php 获取节日和节气,你需要先安装这个库。&nbsp;首先,通过 Composer 安装 lunar-php:composer&nbsp;require&nbsp;chenmingl/lunar-php获取阳历阴历节日及节气:require&nbsp;&#39;vendor/autoload.php&#39;; &nbsp; use&nbsp;Lunar\Lunar; &nbsp; //&amp;nbs
发表于:2024-04-09 浏览:310 TAG:
【PHP】PHP去除字符串中的标点符号
1. 使用str_replace()2. 使用正则表达式3. 使用ctype_punct函数4. 去除中文字符
发表于:2024-11-11 浏览:230 TAG: #php
【PHP】用PHP从数据库到后端到前端完整实现一个中秋节祝福语项目
文章目录🚀一、前言🚀二、开发环境准备🚀三、功能实现🍁3.3.1 HTML布局🍁3.3.2 JQuery事件处理🍁3.2.1 连接数据库🍁3.2.1 获取祝福语🍁3.2.3 处理请求🍁3.2.4 配置Nginx与FPM🍁3.1.1 创建数据库及表结构🍁3.1.2 准备数据🔎3.1 准备数据库和数据🔎3.2 后端开发🔎3.3 前端开发🚀四、运行和测试🔎4.1 绑定host🔎4.2 开始测试🚀五、总结中秋佳节即将来临!在这特殊的时刻,我们特别举办一场属于程序员的中秋
发表于:2023-12-06 浏览:439 TAG:
【PHP】支付宝小程序授权登录踩坑记录
最近做了个uniapp转支付宝小程序的项目,遇到了很多问题,在此记录一下。1 授权登录,提示grant_type参数不正确接口链接https://opendocs.alipay.com/mini/05dxgc?pathHash=1a3ecb13小程序端先获取授权codePage({ &nbsp;&nbsp;getAuthCode()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;my.getAuthCode({ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;nbs
发表于:2023-12-27 浏览:382 TAG:
【PHP】如何在PHP中使用ReactPHP进行异步操作和事件驱动开发
随着 web 应用的复杂度不断提高,对性能和高并发的要求也越来越高。php 作为一门广泛应用于 web 开发的语言,也需要紧跟时代步伐,提供更高效、更灵活的解决方案。而 reactphp 正是针对 php 的高性能、事件驱动的异步解决方案。在本篇文章中,我们将讨论如何在 php 中使用 reactphp 进行异步操作和事件驱动开发,以提升 web 应用的性能和用户体验。什么是 ReactPHPReactPHP 是基于 PHP 的事件驱动的异步解决方案,它使用非阻塞 I/O 和事件循环,将 PHP
发表于:2024-04-14 浏览:344 TAG: