使用Restful api进行设计
基本原则一:URI
- 应该将 api 部署在专用域名之下。
- URL 中尽量不用大写。
- URI 中不应该出现动词,动词应该使用 HTTP 方法表示但是如果无法表示,也可使用动词,例如:search 没有对应的 HTTP 方法,可以在路径中使用 search,更加直观。
- URI 中的名词表示资源集合,使用复数形式。
- URI 可以包含 queryString,避免层级过深。
基本原则二:HTTP 动词
对于资源的具体操作类型,由 HTTP 动词表示,常用的 HTTP 动词有下面五个:
-
GET:从服务器取出资源(一项或多项)。
-
POST:在服务器新建一个资源。
-
PUT:在服务器更新资源(客户端提供改变后的完整资源)。
-
PATCH:在服务器更新资源(客户端提供改变的属性)。
-
DELETE:从服务器删除资源。
还有两个不常用的 HTTP 动词: -
HEAD:获取资源的元数据。
-
OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。
用户管理模块:
1. [POST] http://lou.springboot.tech/users // 新增
2. [GET] http://lou.springboot.tech/users?page=1&rows=10 // 列表查询
3. [PUT] http://lou.springboot.tech/users/12 // 修改
4. [DELETE] http://lou.springboot.tech/users/12 // 删除
基本原则三:状态码(Status Codes)
处理请求后,服务端需向客户端返回的状态码和提示信息。
常见状态码(状态码可自行设计,只需开发者约定好规范即可):
- 200:SUCCESS 请求成功。
- 401:Unauthorized 无权限。
- 403:Forbidden 禁止访问。
- 410:Gone 无此资源。
- 500:INTERNAL SERVER ERROR 服务器发生错误。 …
基本原则四:错误处理
如果服务器发生错误或者资源不可达,应该向用户返回出错信息。
基本原则五:服务端数据返回
后端的返回结果最好使用 JSON 格式,且格式统一
为了达到这一点,对于后端的返回信息进行统一的封装,其中包括返回的状态码,返回信息和实际的数据
package com.lou.springboot.common;
import java.io.Serializable;
public class Result<T> implements Serializable {
private static final long serialVersionUID = 1L;
//业务码,比如成功、失败、权限不足等 code,可自行定义
private int resultCode;
//返回信息,后端在进行业务处理后返回给前端一个提示信息,可自行定义
private String message;
//数据结果,泛型,可以是列表、单个对象、数字、布尔值等
private T data;
public Result() {
}
public Result(int resultCode, String message) {
this.resultCode = resultCode;
this.message = message;
}
// 省略部分代码
}
前端得到的json数据的统一格式
{
"resultCode": 200,
"message": "SUCCESS",
"data": [{
"id": 2,
"name": "user1",
"password": "123456"
}, {
"id": 1,
"name": "13",
"password": "12345"
}]
}
基本原则六:版本控制
规范的 api 应该包含版本信息,在 RESTful api 中,最简单的包含版本的方法是将版本信息放到 url 中,如:
[GET] http://lou.springboot.tech/v1/users?page=1&rows=10
[PUT] http://lou.springboot.tech/v1/users/12
使用Ajax技术
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML),它是一种用于创建快速动态网页的技术,通过浏览器与服务器进行少量数据交换,Ajax 可以使网页实现异步更新,这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新,传统的网页如果需要更新内容,必须要进行跳转并重新加载整个网页。
Ajax 技术使得网站与用户间有了更友好的交互效果,比较常见的借助 Ajax 技术实现的功能有列表上拉加载分页数据、省市区三级联动、进度条更新等等,这些都是借助 Ajax 技术在当前页面即可完成的功能,即使有数据交互也不会跳转页面,整体交互效果有了很大的提升。
Ajax 的整个工作流程如上图所示,用户在进行页面上进行操作时会执行 js 方法,js 方法中通过 Ajax 异步与后端进行数据交互。首先会创建 XMLHttpRequest 对象,XMLHttpRequest 是 AJAX 的基础,之后会根据页面内容将参数封装到请求体中或者放到请求 URL 中,然后向后端服务器发送请求,请求成功后根据后端返回的数据进行解析和部分逻辑处理,最终在不刷新页面的情况下对页面进行局部更新。
使用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>lou.SpringBoot | Ajax 请求测试</title>
</head>
<body class="hold-transition login-page">
<div style="width:720px;margin:7% auto">
<div class="content">
<div class="container-fluid">
<div class="row">
<div class="col-lg-6">
<div class="card">
<div class="card-header">
<h5 class="m-0">接口测试1</h5>
</div>
<div class="card-body">
<input type="text" id="info" class="form-control" placeholder="请输入info值">
<h6 class="card-title">接口1返回数据如下:</h6>
<p class="card-text" id="test1"></p>
<a href="#" class="btn btn-primary" onclick="requestTest1()">发送请求1</a>
</div>
</div>
<br>
<div class="card card-primary card-outline">
<div class="card-header">
<h5 class="m-0">接口测试2</h5>
</div>
<div class="card-body">
<h6 class="card-title">接口2返回数据如下:</h6>
<p class="card-text" id="test2"></p>
<a href="#" class="btn btn-primary" onclick="requestTest2()">发送请求2</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
<!-- 引入jQuery -->
<script src="https://cdn.staticfile.org/jquery/1.12.0/jquery.min.js"></script>
<!-- 定义两个点击事件并实现 Ajax 调用逻辑 -->
<script type="text/javascript">
function requestTest1() {
var info = $("#info").val();
$.ajax({
type: "GET",//方法类型
dataType: "text",//预期服务器返回的数据类型
url: "api/test1?info=" + info,//请求地址
contentType: "application/json; charset=utf-8",
success: function (result) {//请求成功后回调
$("#test1").html(JSON.stringify(result));
},
error: function () {//请求失败后回调
$("#test1").html("接口异常,请联系管理员!");
}
});
}
function requestTest2() {
$.ajax({
type: "GET",//方法类型
dataType: "json",//预期服务器返回的数据类型
url: "api/test2",
contentType: "application/json; charset=utf-8",
success: function (result) {
$("#test2").html(JSON.stringify(result));
},
error: function () {
$("#test2").html("接口异常,请联系管理员!");
}
});
}
</script>