激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

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

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品视频免费网站 | 少妇一级淫片免费看 | 久久精品高清 | 国产在线一级视频 | 久久久久国产一区二区三区不卡 | www.狠狠插.com | 久久成年人视频 | 亚洲第一视频 | 久久久免费观看完整版 | 国产精品久久久久久久久久尿 | 国产精品免费观在线 | gogo全球大胆高清人露出91 | 视频一区二区三区视频 | 污黄视频在线观看 | av电影在线观看网站 | 日本在线不卡一区二区 | 免费男女乱淫真视频 | 2021国产精品视频 | 日本黄色一级视频 | 毛片免费试看 | 国产精品热 | 国产精品久久久久久久久久iiiii | 91伊人久久 | 草草视频免费 | 免费激情视频网站 | 免费一级欧美大片视频在线 | 欧美中文日韩 | 在线成人免费视频 | 国产69久久精品成人看 | 欧美久久久久久久久 | 国内免费视频成人精品 | 蜜桃久久一区二区三区 | 欧美精品电影一区 | 7777网站 | 黄色网址你懂的 | 亚洲视频在线观看免费视频 | 国产妇女乱码一区二区三区 | av电影免费在线 | 精品国产欧美一区二区 | 久久精品女人天堂av | 久久国产精品免费视频 |