RPC(Remote Procedure Call),遠端過程呼叫),這種RPC形式的API組織形態是類和方法的形式。所以API的請求往往是一個動詞用來標識介面的意思,比如 https://xxxx/GetStudent?id=1 和 https://xxxx/AddStudent 這種風格,並且往往沒有規範需要我們去檢視介面定義檔案。HTTP方法基本只用GET和POST,沒有使用HTTP的其它謂詞設計比較簡單。
Rest:按照Http的語意來使用HTTP協定的一種風格,Rest全稱Representational State Transfer(表現層狀態轉換)。他是一種規範或者設計風格而不是特別的技術。REST形式的API組織形態是資源和實體,請求的路由可以看出對資源的存取,規範統一介面自解釋。
比如 https://xxxx/Student/1 用Get方法呼叫就是獲取編號為1的學生。 https://xxxx/Student/1 用Delete呼叫就是刪除編號為1的學生,用delete呼叫就是刪除該學生。
在HTTP中這些呼叫方法GET、POST、PUT、PATCH、DELETE 即HTTP謂詞。GET用來獲取資源,POST用來新建資源,PUT用來更新指定資源,PATCH用來批次更新資源,DELETE用來刪除資源,通過謂詞來表示請求動作或者意圖,通過url定位資源。
在請求中GET、PUT、DELETE 請求是冪等的,也就是說可以重試請求。而POST不是冪等,因為POST意思是新增資料。
在Rest風格中使用狀態碼來標識返回結果,其中常用200、201、400、401、404、410、500等。
在ASP.NET WebAPI中我們也能看到Rest的風格,理想很豐滿,顯示很骨幹。如果我們嚴格的按照Rest風格設計介面的話,需要對技術人員有很高的要求,需要去劃分不同業務不同的資源定位,而且有些業務也找不到準確的謂詞去定義,響應狀態碼有限無法表達準確的意思,或者是時間上來不及等等原因。
而且這種方式更符合國外語言表達的方式,不太適合我國寶寶體質。
所以我們在設計介面的時候不用非要用Rest風格,我們可以靠近或者在特定的更適合使用Rest介面系統中使用。
本篇我們結合Rest看下介面如何設計和互動。
{code:1,msg:"成功"}
或者{code:0,msg:"失敗"}
。在上一篇中遺留的這個問題 .net 溫故知新【11】:Asp.Net Core WebAPI 入門使用及介紹
所以我們在Controller中Route設定為[Controller]則不管方法介面名稱是什麼,仍然以Rest的方式存取。
[Route("[controller]")]
[ApiController]
public class RestCutController : ControllerBase
{
[HttpGet]
public IEnumerable<string> GetStudents()
{
//獲取所有學生
return new string[] { "student1", "student2" };
}
[HttpGet("{id}")]
public string GetStudent(int id)
{
//獲取id的學生
return "student"+id;
}
[HttpPost]
public void PostStudent([FromBody] string value)
{
//新增
}
[HttpPut("{id}")]
public void PutStudent(int id, [FromBody] string value)
{
//修改
}
[HttpDelete("{id}")]
public void DeleteStudent(int id)
{
//刪除id學生
}
}
當我們修改Rout按照RPC方式,[Route("[controller]/[action]")]
執行後發現swagger展示的介面方式就改變了。並且保留了引數URL的方式。
關於返回狀態碼的問題可以有兩種方式,一種是直接在ControllerBase.Response
響應中指定返回狀態碼。
[HttpDelete("{id}")]
public string DeleteStudent(int id)
{
//刪除id學生
if (id == 1)
{
return "刪除成功";
}
else {
Response.StatusCode = 404;
return "未找到!";
}
}
另外一種方式就是返回泛型ActionResult<string>
,其中OK
和NotFound
是繼承自ActionResult
然後隱式轉換到泛型,也可以直接返回IActionResult或者ActionResult但是型別不確定這樣swagger檔案就不會解析出返回值,所以我們用ActionResult泛型。
[HttpDelete("{id}")]
public ActionResult<string> DeleteStudent(int id)
{
//刪除id學生
if (id == 1)
{
return Ok("刪除成功");
}
else
{
return NotFound("未找到!");
}
}
[HttpDelete("{id}")]
public ActionResult DeleteStudent(int id) //返回ActionResult
{
//刪除id學生
if (id == 1)
{
return Ok("刪除成功");
}
else
{
return NotFound("未找到!");
}
}
最後我們在總結下關於API引數獲取的方式,在 [HttpGet("{id}")]
中我們看到有{id}
,這個就是預留位置,從RUL中獲取,不光可以設定預留位置還可以設定路徑的其它值,甚至可以隨意組織,只要我們的引數明和預留位置相同就行。
[HttpDelete("number/{id}/Name/{name}")] //自己組織的URL
public ActionResult<string> DeleteStudent(int id,string name)
{
//刪除id學生
if (id == 1)
{
return Ok("刪除成功");
}
else
{
return NotFound("未找到!");
}
}
當然也可以使用[FromRoute]
從route獲取,另外我們還有一些Attribute用於從不同的地方獲取引數,比如從QueryString獲取。那麼我的請求URL就應該是/RestCut/DeleteStudent?id=1
[HttpDelete]
public ActionResult<string> DeleteStudent([FromQuery] int id)
{
//刪除id學生
if (id == 1)
{
return Ok("刪除成功");
}
else
{
return NotFound("未找到!");
}
}
最後還有[FromHeader]
、[FromForm]
、[FromBody]
這些獲取引數的方式,不清楚的使用的時候查詢就行了。
作者:孫泉
出處:https://www.cnblogs.com/SunSpring/p/17546572.html
如果你喜歡文章歡迎點選推薦,你的鼓勵對我很有用!
本文版權歸作者所有,轉載需在文章頁面明顯位置給出原文連結。