亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

RESTful API URI 設計: 判斷資源是否存在?

2019-11-17 02:12:25
字體:
來源:轉載
供稿:網友

RESTful API URI 設計: 判斷資源是否存在?

相關的一篇文章:RESTful API URI 設計的一些總結。

問題場景:判斷一個資源(Resources)是否存在,URI 該如何設計?

應用示例:判斷 id 為 1 用戶下,名稱為 windows 10 的產品是否存在?

如果這個問題出現在 MVC 項目中,我想我們一般會這樣設計:

public class PRoductService{    public async Task<bool> IsExist(int userId, string productName)    {        ....    }}

看來沒什么問題,的確也沒什么問題,那如果把這部分代碼搬到 asp.net WebAPI 項目中實現,會是怎樣呢?我們來看一下:

public class ProductsController : ApiController{    [HttpGet]    [Route("api/products/isexist/{userId}/{productName}")]    public async Task<bool> IsExist(int userId, string productName)    {        ...    }}

我想你應該發現一些問題了,這種寫法完全是 MVC 的方式,但并不適用于 WebAPI,主要有三個問題:

  • Route 定義混亂,完全違背 REST API URI 的一些設計原則。
  • Action 命名不恰當。
  • bool 返回值不合適。

對于上面的三個問題,我們分別來探討下。

1. URI 設計

首先,我們知道在 REST API 中,URI 代表的是一種資源,它的設計要滿足兩個基本要求,第一名詞而非動詞,第二要能清晰表達出資源的含義,換句話說就是,從一個 URI 中,你可以很直接明了的知道訪問的資源是什么,我們再來看我們設計的 URI:

api/products/isExist/{userId}/{productName}

這是什么鬼???這種設計完全違背 URI 原則,首先,我們先梳理一下,我們想要請求的資源是什么?沒錯,是產品(Products),但這個產品是某一個用戶下的,所以用戶和產品有一個上下級關系,訪問產品首先得訪問用戶,這一點要在 URI 中進行體現,其次,我們是獲取產品?還是判斷產品是否存在?這個概念是不同的,產品的唯一標識和用戶一樣,都是 id,在 URI 的一般設計中,如果要訪問某一唯一標識下的資源(比如 id 為 1 的 product),會這樣進行設計:api/products/{id},HttpClient 請求中會用 HttpGet 方法(api/products/1),這樣我們就可以獲得一個 id 為 1 的 product,但現在的場景是,獲取產品不通過唯一標識,而是通過產品名稱,難道我們要這樣設計:

api/products/{productName}

咋看之下,這樣好像設計也沒什么問題,但總覺得有些不對勁,比如如果再加一個產品大小,難道要改成這樣:api/products/{productName}/{productSize},這種設計完全是不恰當的,上面說到,URI 代表的是一種資源,通過 URI 獲取資源的唯一方式是通過資源的唯一標識,除此之外的獲取都可以看作是對資源的查詢(Query),所以,針對我們的應用場景,URI 的設計應該是這樣(正確):

api/users/{userId}/products: api/users/1/products?productName=windows 10

上面的 URI 清晰明了的含義:查詢 id 為 1 用戶下名稱為 windows 10 的產品。

2. Action 命名

對于 IsExist 的命名,如果沒有很強的強迫癥,其實也是可以接受的,因為 WebAPI 的 URI 并不會像 MVC 的 Route 設計那樣,在訪問的時候,URL 一般會默認 Action 的名字,所以,在 WebAPI Action 設計的時候,會在 Action 前面加一個 Route 屬性,用來配置 URI,也就是說每一個 Action 操作會對應一個 URI 請求操作,這個請求操作也就是 HTTP 的常用方法。

如果我們想把 IsExist 改掉,那用什么命名會好些呢?先回憶一下,我們在使用 Visual Studio 創建 ASP.NET WebAPI 項目的時候,VS 會自動創建一些示例 Action,我們看看能不能從那里得到一些線索:

public class ValuesController : ApiController{    // GET api/values    public IEnumerable<string> Get()    {        return new string[] { "value1", "value2" };    }    // GET api/values/5    public string Get(int id)    {        return "value";    }    // POST api/values    public void Post([FromBody]string value)    {    }    // PUT api/values/5    public void Put(int id, [FromBody]string value)    {    }    // DELETE api/values/5    public void Delete(int id)    {    }}

上面是 Values 資源的一些 Action 實現,我們可以看到,Action 的命名和 HTTP 方法一樣,比如 Get 就是 Get,而不是 GetById,Get 是動詞,表示它對資源的一種操作,具體是通過什么進行操作?在參數中可以很直觀的進行反應,一般會在 HelpPage 中進行注釋說明。

IsExist 的含義還是判斷資源是否存在,其本質上來說就是去獲取一個資源,也就是 Get 操作,所以,在 WebAPI Action 中對此的命名,我們直接使用 Get 會好一下,或者使用 Exist。

3. 請求返回

bool 一般是用在項目方法中的返回值,如果用在 HTTP 請求中,就不是很恰當了,我先貼出幾篇文章:

  • REST API Design - Resource Modeling(重點看下
  • REST API 404: Bad URI, or Missing Resource?
  • Designing REST API for checking if a username exists.
  • Proper route for checking resource existence in a RESTful API
  • When to use HTTP status code 404 in an API(重點看下

上面除去第一篇文章,其他文章都是在討論:檢查一個資源是否存在,REST API 該如何設計(HTTP status code)?客戶端獲取服務的響應不是通過 bool,而是通過 HTTP 狀態碼,主要設計三個:404、204 和 200:

  • 404 is correct since the resource "/users/{username}" was Not Found.
  • If the resource exists but it is empty (as in "null") then you should return 204.
  • If the resource exists and contains any data then you should return 200.

204 和 404 有所不同的是,204 表示資源存在,但是為空,404 代表的是原始資源本身就不存在,并且通過唯一標識查詢不到,而 204 更多的是表示,在一定條件下的資源不存在,但可以通過唯一標識查詢到,所以如果資源不存在返回 204 不恰當,wikipedia 中 200 和 404 詳細說明:

  • 200 OK - ... The actual response will depend on the request method used. In a GET request, the response will contain an entity corresponding to the requested resource.
  • 404 Not Found - The requested resource could not be found but may be available again in the future. Subsequent requests by the client are permissible.

HTTP status code 簡要說明:

  • 2xx codes Tell a UA that it did the right thing, the request worked. It can keep doing this in the future.(請求成功)
  • 3xx codes Tell a UA what you asked probably used to work, but that thing is now elsewhere. In future the UA might consider just going to the redirect.(請求很可能成功)
  • 4xx codes Tell a UA it did something wrong, the request it constructed isn't proper and shouldn't try it again, without at least some modification.(請求失?。?/li>
  • 5xx codes Tell a UA the server is broken somehow. But hey that query could work in the future, so there is no reason not to try it again. (except for 501, which is more of a 400 issue).(請求錯誤)

在上面文章中,有一段很有意思的對話(請略過翻譯):

  • Alien: Computer, please tell me all planets that humans inhabit.(電腦,請告訴我所有適宜人類居住的星球。)Computer: 1 result found. Earth(查詢到一個結果,地球)
  • Alien: Computer, please tell me about Earth.(電腦,請告訴我地球的信息。)Computer: Earth - Mostly Harmless.(地球-無害。)
  • Alien: Computer, please tell me about all planets humans inhabit, outside the asteroid belt.(電腦,請告訴我小行星帶以外,所有適宜人類居住的星球。)Computer: 0 results found.(沒有查詢到結果。)
  • Alien: Computer, please destroy Earth.(電話,請毀滅地球。)Computer: 200 OK.(毀滅成功。)
  • Alien: Computer, please tell me about Earth.(電腦,請告訴我地球的信息。)Computer: 404 - Not Found(沒有找到。)
  • Alien: Computer, please tell me all planets that humans inhabit.(電腦,請告訴我所有適宜人類居住的星球。)Computer: 0 results found.(沒有找到。)
  • Alien: Victory for the mighty Irken Empire!(看不懂啥意思)

搜刮到的一張 HTTP status code 示意圖(點擊查看大圖):

4. 最終代碼

針對一開始的應用問題,最終完善代碼:

public class ProductsController : ApiController{    [HttpGet]    [Route("api/users/{userId}/products")]    public async Task<HttpResponseMessage> Get(int userId, string productName)    {        if (true)        {            return Request.CreateResponse(HttpStatusCode.OK);        }        else        {            return Request.CreateResponse(HttpStatusCode.NotFound);        }    }}public class WebApiTest{    [Fact]    public async Task Exists_Product_ByProductName()    {        using (var client = new HttpClient())        {            client.BaseAddress = new System.Uri(Base_Address);            var response = await client.GetAsync("/api/users/1/products?productName=windows 10");            //var requestMessage = new HttpRequestMessage(HttpMethod.Head, "/api/users/1/products?productName=windows 10");            //var response = await client.SendAsync(requestMessage);//更好的調用方式,只請求HEAD。            Console.WriteLine(response.StatusCode);            Assert.True(response.IsSuccessStatusCode);        }    }}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲人成电影网站色| 日本亚洲欧洲色α| 久久五月天综合| 福利视频导航一区| 欧美黑人xxxⅹ高潮交| 精品国产福利在线| 一区国产精品视频| 久久综合网hezyo| 亚洲第一区第二区| 国产成人在线精品| 欧美日韩亚洲视频一区| 亚洲黄在线观看| 亚洲欧美另类在线观看| 精品久久久久久久久久| 亚洲系列中文字幕| 亚洲精品suv精品一区二区| 日韩激情av在线播放| 91九色国产视频| 91精品视频一区| 亚洲一区二区三区乱码aⅴ| 日韩一级黄色av| 亚洲第一偷拍网| 亚洲999一在线观看www| 91沈先生作品| 日韩av电影在线播放| 欧美高清视频免费观看| 欧美精品免费播放| 国产精品色视频| 欧美激情视频在线观看| 久久精品成人一区二区三区| 日本精品视频在线| 久久久久北条麻妃免费看| 国产精品永久免费视频| 在线亚洲欧美视频| 精品久久久香蕉免费精品视频| 亚洲视频在线免费观看| 伊人青青综合网站| 国产精品男女猛烈高潮激情| 国语对白做受69| 欧美在线国产精品| 精品国内产的精品视频在线观看| 亚洲成人精品视频在线观看| 久久久久久久激情视频| 国内精品久久久久久影视8| 日韩精品一区二区三区第95| 欧美精品情趣视频| 1769国内精品视频在线播放| 亚洲无线码在线一区观看| 国产成人啪精品视频免费网| 亚洲精品在线不卡| 日韩视频―中文字幕| 国产精品福利在线| 91精品国产91久久久久久不卡| 久久国产精品久久久久| 91热精品视频| 精品欧美一区二区三区| 国产成人一区二区在线| 欧美成aaa人片免费看| 日韩av电影手机在线观看| 97精品久久久中文字幕免费| 中文字幕视频在线免费欧美日韩综合在线看| 国产精品网站大全| 亚洲激情在线视频| 欧美电影在线观看网站| 欧美一区二区三区免费观看| 国产在线视频欧美| 亚洲级视频在线观看免费1级| 久久夜色精品国产亚洲aⅴ| 精品亚洲男同gayvideo网站| 亚洲综合日韩中文字幕v在线| 国产欧美日韩亚洲精品| 成人在线激情视频| 亚洲男人天堂古典| 成人免费网站在线看| 国产主播喷水一区二区| 国产日韩欧美91| 日韩av片电影专区| 在线视频一区二区| 欧美一级大片在线免费观看| 日本不卡高字幕在线2019| 亚洲最大福利网| 色综合天天综合网国产成人网| 亚洲女人初尝黑人巨大| 久久精品小视频| 91精品国产沙发| 日本精品久久久久久久| 欧美精品免费看| 亚洲天堂男人天堂| 亚洲精品在线不卡| 亚洲美女又黄又爽在线观看| 中文字幕日韩欧美精品在线观看| 国产欧美日韩视频| 国产精品福利小视频| 国产中文字幕日韩| 亚洲国产成人精品一区二区| 久久九九有精品国产23| 欧美日韩成人黄色| 亚洲xxx视频| 亚洲午夜未满十八勿入免费观看全集| 久久久久久久97| 97av在线视频免费播放| 国产主播精品在线| 91精品国产综合久久久久久久久| 国产精品欧美在线| 国产精品普通话| 欧美裸体xxxx极品少妇软件| 一本色道久久88综合亚洲精品ⅰ| 国产精品自产拍在线观| 欧美性猛交xxxx富婆| 亚洲国产91精品在线观看| 成人看片人aa| 久久国产精品99国产精| 国产精品www色诱视频| 色综合久久天天综线观看| 尤物九九久久国产精品的特点| 亚洲欧美在线免费| 97视频在线观看亚洲| 亚洲国产成人一区| 国产视频精品久久久| 国产精品稀缺呦系列在线| 在线看福利67194| 91久久精品美女| 91爱爱小视频k| 精品国内产的精品视频在线观看| 国产亚洲精品综合一区91| 亚洲成人动漫在线播放| 欧美高清在线播放| 亚洲激情 国产| 亚洲天堂视频在线观看| 亚洲欧美国内爽妇网| 夜夜嗨av一区二区三区免费区| 国产精品扒开腿爽爽爽视频| 青草热久免费精品视频| 日韩中文字幕欧美| 亚洲午夜未满十八勿入免费观看全集| 欧美成人第一页| 亚洲第一区在线观看| 成人黄色免费在线观看| 亚洲自拍在线观看| 成人国产精品一区二区| 亚洲小视频在线| 日韩专区中文字幕| 精品亚洲一区二区三区在线播放| 亚洲成人a**站| 欧美日韩国产精品一区二区三区四区| 亚洲国产精彩中文乱码av在线播放| 久久久亚洲福利精品午夜| 亚洲欧美一区二区三区久久| 亚洲男人av电影| 欧美精品免费在线观看| 97精品视频在线播放| 国产精品a久久久久久| 日日狠狠久久偷偷四色综合免费| 久久精品国产精品| 日韩在线不卡视频| 中文亚洲视频在线| 欧美激情va永久在线播放| 欧美伦理91i| 国产精品亚洲аv天堂网| 亚洲男人天堂久| 欧美国产欧美亚洲国产日韩mv天天看完整| 91系列在线播放| 国产精品白嫩美女在线观看| 国语自产精品视频在线看一大j8|