一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 淺談Spring Boot 開發REST接口最佳實踐

淺談Spring Boot 開發REST接口最佳實踐

2021-03-18 12:26固安李慶海 Java教程

這篇文章主要介紹了淺談Spring Boot 開發REST接口最佳實踐,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

本文介紹了Spring Boot 開發REST接口最佳實踐,分享給大家,具體如下:

HTTP動詞與SQL命令對應

GET

?
1
2
3
4
5
從服務器獲取資源,可一個或者多個,對應SQL命令中的SELECT
GET /users
獲取服務器上的所有的用戶信息
GET /users/ID
獲取指定ID的用戶信息

POST

?
1
2
3
在服務器上創建一個新資源,對應SQL命令中的CREATE
POST /users
創建一個新的用戶

PUT

?
1
2
3
在服務器上更新一個資源,客戶端提供改變后的完整資源,對應SQL命令中的UPDATE
PUT /users/ID
更新指定ID的用戶的全部信息

DELETE

?
1
2
3
從服務器上刪除一個資源,對應SQL命令中的DELETE
DELETE /users/ID
刪除指定ID的用戶信息

PATCH

?
1
2
3
在服務器更新一個資源的部分屬性,對應SQL命令中的UPDATE
PATCH /users/ID
更新指定ID的用戶的某個屬性

URL中的約定

URL中名詞使用復數形式

URL中的名稱是使用單數還是使用復數的問題,爭議由來已久。URL中的名詞一般對應數據庫中的表,表中存儲的是同類數據, 在實踐中我是強制使用復數形式 ,看上去更舒服些。

?
1
2
3
4
/users
/users/1
/roles
/roles/1

至于一些不規則的、不可數的名詞就見仁見智吧。

?
1
2
3
4
5
6
7
8
/heroes
/heroes/1
/people
/people/1
/foots
/foots/1
/feet
/feet/1

版本

講版本號加入到URL中以應對不兼容的和破壞性的更改。發布新API時,客戶端可以自如的遷移到新API,不會因調用完全不同的新API而陷入窘境。使用直觀的“V”前綴來表示后面的數字是版本號,不需要次級版本號,不應該頻繁的發布API版本。

?
1
2
/edu/v1/users
/edu/v1/roles

對可選的、復雜的參數使用查詢字符串

為了讓URL更小、更簡潔,為資源設置一個基本URL,講可選的、復雜的參數用查詢字符串表示。

?
1
/edu/v1/users?enabled=1&roleid=1

提供分頁信息

一次性返回數據庫中的所有的資源不是一個好主意,因此需要提供分頁機制。通常使用數據庫中眾所周知的參數offset和limit

?
1
/edu/v1/users?enabled=1&offset=1&limit=15

如果客戶端沒有傳遞這些參數,則應使用默認值,通常offset=0,limit=10。

非資源請求使用動詞

有時API調用并不涉及資源,在這種情況下,服務器執行一個操作病將結果返回給客戶端。

?
1
/edu/v1/calc?p=100

考慮特定資源和跨資源搜索

提供對特定止緣的搜索很容易,只需要使用相應的資源集合,并將搜索字符串附加到查詢參數中即可。

?
1
/edu/v1/users?username=李慶海

如果需要對所有資源提供全局搜索,則需要使用其他方法。

?
1
/edu/v1/search?key=李慶海

響應結果

使用小駝峰命名法作為屬性標識符

通常,RESTful Web服務將被JavaScript編寫的客戶端使用。客戶端會將JSON響應轉換為JavaScript對象,然后調用其屬性。因此,最好遵循JavaScript代碼通用規范。

?
1
2
3
person.year_of_birth // 不推薦,違反JavaScript代碼通用規范
person.YearOfBirth // 不推薦,JavaScript構造方法命名
person.yearOfBirth // 推薦

提供分頁信息

返回結果比較多時,應提供分頁信息。

?
1
2
3
4
5
6
7
8
{
 "page": 0,
 "size": 10,
 "total": 3465,
 "obj": [
  
 ]
}

Spring MVC開發REST接口

常用注解

@RestController

@RestController是@ResponseBody和@Controller的組合注解。

@RequestMapping

此注解即可以作用在控制器的某個方法上,也可以作用在此控制器類上。當控制器在類級別上添加@RequestMapping注解時,這個注解會應用到控制器的所有處理器方法上。處理器方法上的@RequestMapping注解會對類級別上的@RequestMapping的聲明進行補充。

@PostMapping

組合注解,是@RequestMapping(method =RequestMethod.POST)的縮寫。

@PutMapping

組合注解,是@RequestMapping(method = RequestMethod.PUT)的縮寫。

@PatchMapping

組合注解,是@RequestMapping(method = RequestMethod.PATCH)的縮寫。

@DeleteMapping

組合注解,是@RequestMapping(method = RequestMethod.DELETE)的縮寫。

@GetMapping

組合注解,是@RequestMapping(method = RequestMethod.GET)的縮寫。

@PathVariable

獲取url中的數據。

@RequestParam

獲取請求參數的值。

REST接口及Swagger 編寫API文檔示例

關于Swagger的使用可參考Spring Boot 項目中使用Swagger2 。方法體中的代碼不重要,重要的是方法的簽名以及與HTTP動詞的映射。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import java.util.Date;
import javax.persistence.EntityNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import cn.com.infcn.jianshu.Service.UserService;
import cn.com.infcn.jianshu.exception.BizException;
import cn.com.infcn.jianshu.exception.LoginNameOrPasswordErrorException;
import cn.com.infcn.jianshu.exception.ResourceExistsException;
import cn.com.infcn.jianshu.model.User;
import cn.com.infcn.jianshu.util.JsonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
 
/**
 * 系統用戶Controller
 *
 * @author 李慶海
 *
 */
@Api(value = "系統用戶接口", tags = "系統管理")
@RestController
@RequestMapping("/v3/edu/users")
public class UserController {
 
 @Autowired
 private UserService userService;
 
 /**
  * 添加用戶,注冊
  *
  * @param loginName
  *   登錄賬號
  * @param userName
  *   用戶名稱
  * @param password
  *   登錄密碼
  * @param roleId
  *   用戶角色
  * @return
  * @throws ResourceExistsException
  */
 @ApiOperation(value = "添加用戶")
 @PostMapping("/")
 public JsonResult create(
   @ApiParam(name = "loginName", value = "登錄賬號", required = true) @RequestParam(required = true) @RequestBody String loginName,
   @ApiParam(name = "userName", value = "用戶名稱", required = true) @RequestParam(required = true) @RequestBody String userName,
   @ApiParam(name = "password", value = "登錄密碼", required = true) @RequestParam(required = true) @RequestBody String password,
   @ApiParam(name = "roleId", value = "用戶角色編號", required = true) @RequestParam(required = true) @RequestBody String roleId)
   throws ResourceExistsException {
  boolean exists = this.userService.exists(loginName);
  if (exists) {
   throw new ResourceExistsException(loginName);
  }
  User user = userService.create(loginName, password, userName, roleId);
  return JsonResult.success(user);
 }
 
 /**
  * 用戶憑借登錄賬號和登錄密碼進行登錄
  *
  * @param loginName
  *   登錄賬號
  * @param password
  *   登錄密碼
  * @throws EntityNotFoundException
  */
 @ApiOperation(value = "根據用戶編號查詢用戶信息")
 @GetMapping("/login")
 public JsonResult login(
   @ApiParam(name = "loginName", value = "登錄賬號", required = true) @RequestParam(required = true) String loginName,
   @ApiParam(name = "password", value = "登錄密碼", required = true) @RequestParam(required = true) String password)
   throws LoginNameOrPasswordErrorException {
  User user = this.userService.login(loginName, password);
  if (null == user) {
   throw new LoginNameOrPasswordErrorException();
  }
  return JsonResult.success(user);
 }
 
 /**
  * 根據用戶編號查詢用戶信息
  *
  * @param id
  *   用戶編號
  * @throws EntityNotFoundException
  */
 @ApiOperation(value = "根據用戶編號查詢用戶信息")
 @GetMapping("/{id}")
 public JsonResult read(
   @ApiParam(name = "id", value = "用戶編號,主鍵", required = true) @PathVariable(required = true) String id)
   throws EntityNotFoundException {
  User user = this.userService.getOne(id);
  return JsonResult.success(user);
 }
 
 /**
  * 賬戶注銷,不刪除用戶的數據
  *
  * @param userId
  *   用戶編號
  * @return
  */
 @ApiOperation(value = "注銷賬戶")
 @PatchMapping("/{id}")
 public JsonResult cancel(
   @ApiParam(name = "id", value = "用戶編號,主鍵", required = true) @PathVariable(required = true) String id)
   throws EntityNotFoundException {
  this.userService.cancel(id);
  return JsonResult.success();
 }
 
 /**
  * 重置密碼
  *
  * @param id
  *   用戶編號
  * @param password
  *   新登錄密碼
  * @return
  */
 @ApiOperation(value = "重置密碼")
 @PatchMapping("/")
 public JsonResult updatePassword(
   @ApiParam(name = "id", value = "用戶編號,主鍵", required = true) @RequestParam(required = true) String id,
   @ApiParam(name = "password", value = "新登錄密碼", required = true) @RequestParam(required = true) String password) {
  this.userService.updatePassword(id, password);
  return JsonResult.success();
 }
 
 /**
  * 多條件組合查詢
  *
  * @param userName
  *   用戶名稱
  * @param roleId
  *   用戶角色
  * @param start
  *   開始日期
  * @param end
  *   結束日期
  * @param page
  *   分頁,從0開始
  * @param size
  *   每頁的行數,默認10
  * @return
  * @throws BizException
  */
 @ApiOperation(value = "用戶信息查詢")
 @GetMapping("/")
 public JsonResult query(
   @ApiParam(name = "userName", value = "用戶名稱,查詢關鍵詞", required = false) @RequestParam(required = false) String userName,
   @ApiParam(name = "roleId", value = "用戶角色編號", required = false) @RequestParam(required = false) String roleId,
   @ApiParam(name = "start", value = "用戶角色編號", required = false) @RequestParam(required = false) Date start,
   @ApiParam(name = "end", value = "用戶角色編號", required = false) @RequestParam(required = false) Date end,
   @ApiParam(name = "page", value = "分頁,第幾頁,從1開始", defaultValue = "1", required = true) @RequestParam(defaultValue = "1", required = true) int page,
   @ApiParam(name = "size", value = "每頁的行數,正整數", defaultValue = "10", required = true) @RequestParam(defaultValue = "10", required = true) int size)
   throws BizException {
  Page<User> datas = this.userService.findDatas(userName, roleId, start, end, page, size);
  if (null == datas || null == datas.getContent() || datas.getContent().isEmpty()) {
   throw new BizException("用戶不存在");
  }
  return JsonResult.success(datas);
 }
 
}

Swagger2接口文檔效果圖

淺談Spring Boot 開發REST接口最佳實踐

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://www.jianshu.com/p/1dbb71f78104

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 任我行视频在线观看国语 | 3d动漫美女物被遭强视频 | 欧美日韩人成在线观看 | 成人资源影音先锋久久资源网 | 亚洲成人国产精品 | 日韩在线免费播放 | 无限在线观看视频大全免费高清 | 国产精品久久久精品视频 | 我与岳乱短篇小说 | 日本一区视频在线 | 天天操天天射天天爽 | 日本人妖网站 | 亚洲成人aa| 日韩毛片在线 | 久久这里只有精品无码3D | 四虎永久免费地址 | 国产99精品成人免费视频 | 欧美日韩精彩视频 | 日本大片在线 | 九九精品免费视频 | 亚洲精品私拍国产福利在线 | 国产高清精品自在久久 | 奇米影视在线视频8888 | 免费高清在线视频色yeye | 亚洲男人的天堂网站 | 国产播放器一区 | 四虎影院久久久 | 办公室强行丝袜秘书啪啪 | ts人妖系列在线专区 | 亚洲国产无线码在线观看 | 免费看又黄又爽又猛的视频软件- | chinese老头和老太交hd | 久久精品在现线观看免费15 | 日本无吗免费一二区 | 高清麻生希在线 | 精品视频手机在线观看免费 | 国产高清小视频 | 国产精品亚洲精品青青青 | 国产综合久久 | 小鸟酱在线看 | 非洲黑人bbwbbwbbw|