粗谈RESTFul API接口-认识
一、背景
随着互联网和移动设备得发展,人们对Web应用的使用需求也增加,传统的动态页面由于低效率而渐渐被HTML+JavaScript(Ajax)的前后端分离所取代!所以一套结构清晰、符合标准、易于理解、扩展方便让大部分人都能够理解接受的接口风格就显得越来越重要,而RESTful风格的接口(RESTful API)刚好有以上特点,就逐渐被实践应用而变得流行起来
二、介绍
有位大佬总结了一句话,用URL定位资源,用Http请求描述操作!-我认为就是RESTFul的精华。
主要特点:
- 以资源为基础
- 统一接口:对资源的操作包括获取、创建、修改和删除,这些操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法
HTTP请求
- GET 从服务器取出资源(一项或多项)。
- POST 在服务器新建一个资源。
- PUT 在服务器更新资源(客户端提供完整资源数据)。
- PATCH 在服务器更新资源(客户端提供需要修改的资源数据)。
- DELETE 从服务器删除资源。
HTTP Method | 安全性 | 幂等性 | 备注 |
---|---|---|---|
GET | 安全 | 幂等 | 读操作安全,查询一次多次结果一致 |
POST | 非安全 | 非幂等 | 写操作非安全,每多插入一次都会出现新结果 |
GET | 安全 | 幂等 | 写操作非安全,一次和多次更新结果一致 |
GET | 安全 | 幂等 | 写操作非安全,一次和多次删除结果一致 |
RESTFul和非RESTFul比较
主要用于前后端分离,前端拿到数据只负责展示和渲染,不对数据做任何处理,后端处理数据并以JSON格式传输出去,定义这样一套统一风格的接口,可以叫做RestFul接口。说白了只是一种设计风格!
URL
URL:统一资源定位符
HTTP/1.1:
- 引入了持久连接,即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive。
- 加入了管道机制,在同一个TCP连接里,允许多个请求同时发送,增加了并发性,进一步改善了HTTP协议的效率
- 新增了请求方式PUT、PATCH、OPTIONS、DELETE等。
状态码
- ✅200 OK - 客户端请求成功 [GET]
- ✅201 CREATED 用户新建或修改数据成功 [POST/PUT/PATCH]
- ✅202 Accepted 表示一个请求已经进入后台排队(异步任务) [*]
- ✅204 Accepted 用户删除数据成功 [DELETE]
- ✅301 - 资源(网页等)被永久转移到其它URL
- ✅302 - 临时跳转
- ✅400 Bad Request - 客户端请求有语法错误,不能被服务器所理解 [POST/PUT/PATCH]
- ✅401 Unauthorized - 请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用 表示用户没有权限(令牌、用户名、密码错误)
- ✅403 表示用户得到授权(与401错误相对),但是访问是被禁止
- ✅404 NOT FOUND - 请求资源不存在,可能是输入了错误的URL
- ✅500 - 服务器内部发生了不可预期的错误
- ✅503 Server Unavailable - 服务器当前不能处理客户端的请求,一段时间后可能恢复正常。
三、示例代码
RESTFul API 示例,基于SpringBoot MyBatis MySQL
1. 搞一个表
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user_login
-- ----------------------------
DROP TABLE IF EXISTS `user_login`;
CREATE TABLE `user_login` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
`username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NULL DEFAULT NULL COMMENT '用户名',
`password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NULL DEFAULT NULL COMMENT '密码',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_520_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user_login
-- ----------------------------
INSERT INTO `user_login` VALUES (1, 'admin', '123456');
INSERT INTO `user_login` VALUES (8, 'tom', 'root');
SET FOREIGN_KEY_CHECKS = 1;
2. controller
@RestController
public class MyRestController {
@Resource
private UserLoginService userLoginService;
@GetMapping("/users")
public List<UserLogin> queryAll() {
return userLoginService.queryAll();
}
@GetMapping("/users/{id}")
public UserLogin queryById(@PathVariable("id") Integer id) {
return userLoginService.queryById(id);
}
@PostMapping("/users")
public int add(UserLogin userLogin) {
return userLoginService.add(userLogin);
}
@PutMapping("/users/{id}")
public int update(@PathVariable("id") Integer id,
@RequestParam("username") String username,
@RequestParam("password") String password) {
UserLogin user = userLoginService.queryById(id);
user.setUsername(username);
user.setPassword(password);
return userLoginService.update(user);
}
@DeleteMapping("/users/{id}")
public int delete(@PathVariable("id") Integer id) {
return userLoginService.deletebyId(id);
}
}
3. mapper
public interface UserLoginMapper {
public List<UserLogin> queryAll();
public int add(UserLogin userLogin);
public UserLogin queryByName(String username);
UserLogin queryById(Integer userId);
int update(UserLogin userLogin);
int deleteById(Integer userId);
}
4. xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.centanet.common.mapper.UserLoginMapper">
<select id="queryAll" resultType="com.centanet.common.pojo.UserLogin">
select * from mybatis.user_login
</select>
<insert id="add" parameterType="com.centanet.common.pojo.UserLogin">
insert into mybatis.user_login(username, password)
values (#{username}, #{password})
</insert>
<update id="update" parameterType="com.centanet.common.pojo.UserLogin">
update mybatis.user_login
set username = #{username},
password = #{password}
where id = #{id}
</update>
<select id="queryByName" resultType="com.centanet.common.pojo.UserLogin">
select *
from mybatis.user_login
where username = #{username}
</select>
<select id="queryById" resultType="com.centanet.common.pojo.UserLogin">
select *
from mybatis.user_login
where id = #{id}
</select>
<delete id="deleteById" parameterType="java.lang.Integer">
delete
from mybatis.user_login
where id = #{id}
</delete>
</mapper>