簡(jiǎn)介
REST:英文representational state transfer直譯為表現(xiàn)層狀態(tài)轉(zhuǎn)移陈瘦,或者表述性狀態(tài)轉(zhuǎn)移胸梆;Rest是web服務(wù)的一種架構(gòu)風(fēng)格计维,一種設(shè)計(jì)風(fēng)格龄章,是一種思想吃谣;同時(shí)Rest不是針對(duì)某一種編程語(yǔ)言的。
以webService為例通俗解釋做裙。
非Rest設(shè)計(jì)岗憋,以往我們都會(huì)這么寫(xiě):
http://localhost:8080/admin/getUser (查詢(xún)用戶(hù))
http://localhost:8080/admin/addUser (新增用戶(hù))
http://localhost:8080/admin/updateUser (更新用戶(hù))
http://localhost:8080/admin/deleteUser (刪除用戶(hù))
總結(jié):以不同的URL(主要為使用動(dòng)詞)進(jìn)行不同的操作。
Rest架構(gòu):
GET http://localhost:8080/admin/user (查詢(xún)用戶(hù))
POST http://localhost:8080/admin/user (新增用戶(hù))
PUT http://localhost:8080/admin/user (更新用戶(hù))
DELETE http://localhost:8080/admin/user (刪除用戶(hù))
總結(jié):URL只指定資源锚贱,以HTTP方法動(dòng)詞進(jìn)行不同的操作仔戈。用HTTP STATUS/CODE定義操作結(jié)果。
Restful:遵守了rest風(fēng)格的web服務(wù)便可稱(chēng)為Restful拧廊。
為什么需要Restful监徘?
URL具有很強(qiáng)可讀性的,具有自描述性
規(guī)范化請(qǐng)求過(guò)程和返回結(jié)果
資源描述與視圖的松耦合
可提供OpenAPI吧碾,便于第三方系統(tǒng)集成凰盔,提高互操作性
提供無(wú)狀態(tài)的服務(wù)接口,降低復(fù)雜度滤港,可提高應(yīng)用的水平擴(kuò)展性
/版本號(hào)/資源路徑
/v1/tags/{tag_id}
/v1/users?[&keyword=xxx][&enable=1][&offset=0][&limit=20]
1、版本號(hào)
命名版本號(hào)可以解決版本不兼容問(wèn)題趴拧,在設(shè)計(jì) RESTful API 的一種實(shí)用的做法是使用版本號(hào)溅漾。一般情況下,我們會(huì)在 url 中保留舊版本號(hào)著榴,并同時(shí)兼容多個(gè)版本
【GET】 /v1/users/{user_id} // 版本 v1 的查詢(xún)用戶(hù)列表的 API 接口
【GET】 /v2/users/{user_id} // 版本 v2 的查詢(xún)用戶(hù)列表的 API 接口
2添履、資源路徑
URI 不能包含動(dòng)詞,只能是名詞(命名名詞的時(shí)候脑又,要使用小寫(xiě)暮胧、數(shù)字及下劃線來(lái)區(qū)分多個(gè)單詞)锐借。
資源的路徑應(yīng)該從根到子依次如下:
/{resources}/{resource_id}/{sub_resources}/{sub_resource_id}/{sub_resource_property}
【POST】 /v1/users/{user_id}/roles/{role_id} // 添加用戶(hù)的角色
有的時(shí)候,當(dāng)一個(gè)資源變化難以使用標(biāo)準(zhǔn)的 RESTful API 來(lái)命名往衷,可以考慮使用一些特殊的 actions 命名钞翔。
/{resources}/{resource_id}/actions/{action}
【PUT】 /v1/users/{user_id}/password/actions/modify // 密碼修改
3、請(qǐng)求方式
【GET】 /users # 查詢(xún)用戶(hù)信息列表
【GET】 /users/1001 # 查看某個(gè)用戶(hù)信息
【POST】 /users # 新建用戶(hù)信息
【PUT】 /users/1001 # 更新用戶(hù)信息(全部字段)
【PATCH】 /users/1001 # 更新用戶(hù)信息(部分字段)
【DELETE】 /users/1001 # 刪除用戶(hù)信息
【PATCH】一般不用席舍,用【PUT】
4布轿、查詢(xún)參數(shù)
RESTful API 接口應(yīng)該提供參數(shù),過(guò)濾返回結(jié)果来颤。
【GET】 /{version}/{resources}/{resource_id}?offset=0&limit=20
5汰扭、響應(yīng)參數(shù)
JSON格式(code、data福铅、msg)
6萝毛、狀態(tài)碼
使用適合的狀態(tài)碼很重要,而不應(yīng)該全部都返回狀態(tài)碼 200
狀態(tài)碼滑黔,可根據(jù)以下標(biāo)準(zhǔn)按照項(xiàng)目擴(kuò)展自身狀態(tài)碼:
200~299段 表示操作成功:
200 操作成功笆包,正常返回
201 操作成功,已經(jīng)正在處理該請(qǐng)求
300~399段 表示參數(shù)方面的異常
300 參數(shù)類(lèi)型錯(cuò)誤
301 參數(shù)格式錯(cuò)誤
302 參數(shù)超出正常取值范圍
303 token過(guò)期
304 token無(wú)效
400~499段 表示請(qǐng)求地址方面的異常:
400 找不到地址
500~599段 表示內(nèi)部代碼異常:
500 服務(wù)器代碼異常
7拷沸、完整事例
UserController.java
@RestController(/v1)
@API(tag=”用戶(hù)相關(guān)接口”)
public class UserController {
@Autowired
private UserJPARepository userJPARepository;
/**
* 查詢(xún)用戶(hù)列表
* @return
*/
@GetMapping(value = "/user")
public List<User> findUserList(){
return userJPARepository.findAll();
}
/**
* 根據(jù)Id查詢(xún)一個(gè)用戶(hù)
* @param id
* @return
*/
@GetMapping(value = "/user/query/{id}")
public User findUserOne(@PathVariable("id") Integer id){
return userJPARepository.findOne(id);
}
/**
* 添加用戶(hù)
* @param name
* @param age
* @param country
* @return
*/
@PostMapping(value = "/user")
public User addUser(@RequestParam("name") String name, @RequestParam("age") int age,
@RequestParam("country") String country){
User user = new User();
user.setName(name);
user.setAge(age);
user.setCountry(country);
return userJPARepository.save(user);
}
/**
* 刪除用戶(hù)
* @param id 用戶(hù)編號(hào)
* @return
*/
@DeleteMapping(value = "/user/{id}")
public List<User> deleteUser(@PathVariable("id") Integer id){
userJPARepository.delete(id);
return userJPARepository.findAll();
}
/**
* 更新用戶(hù)
* @param id
* @param name
* @param age
* @param country
* @return
*/
@PutMapping(value = "/user/{id}")
public User updateUser(@PathVariable("id") Integer id, @RequestParam("name") String name,
@RequestParam("age") int age, @RequestParam("country") String country){
User user = userJPARepository.findById(id);
user.setName(name);
user.setAge(age);
user.setCountry(country);
return userJPARepository.save(user);
}
/**
* 根據(jù)國(guó)家查詢(xún)用戶(hù)
* @param country
* @return
*/
@GetMapping(value = "/user/{country}")
public List<User> findByCountry(@PathVariable("country") String country){
return userJPARepository.findByCountry(country);
}
}