設計 API 時經過 POST 獲取數據須要注意哪些問題

現代網站愈來愈多的使用先後端分離架構,先用前端 MVC 框架快速堆砌出 SPA,再用 API 獲取動態數據也已經成爲平常的開發內容;而用來鏈接先後端的 API,其重要性也天然言而喻。作爲一個前端碼農,認識後端的 API 設計方式也是很重要的,今天讓咱們針對 API 設計來一探究竟。html

HTTP 方法

畢竟是網站的先後端,其中間的通信終究仍是要依賴 HTTP 這個無狀態的協議;在 HTTP 規範中定義了一系列的請求方法,其中較經常使用的以下:前端

  • GET:獲取資源
  • HEAD:與 GET 同爲獲取資源,但只取回 Header
  • POST:提交資源
  • PUT:替換指定的資源
  • PATCH:修改指定的資源
  • DELETE:刪除指定的資源
  • OPTION:詢問與指定資源的溝通方法

在規範中也提到,不一樣的方法指的是對同一件事作不一樣的操做,並經過語意化的方法,讓不一樣的操做獲得預期的結果。程序員

你們對 GETPOST 都不陌生,這是 HTML 的<form action="..."> 所支持的兩個方法;GET 是使用最頻繁的,不管是獲取得頁面仍是數據,通常都會用 GET,而 POST 則經常使用在新增資源上,但因爲 HTML <form action="..."> 不支持其餘方法,在傳統網站中可能會用 POST 處裏除了獲取數據以外的全部事情。面試

PUTPATCH 一般都用在更新資源上,二者的差別是 PUT 的行爲是取代整個資源,而 PATCH 則是更新部分資源;把二者對應到平常生活中的話,就比如在餐廳吃飯,整桌菜從新點是 PUT,另外加菜是 PATCHsegmentfault

DELETE 一般用在刪除資源;HEADGET 相似,但只取回 Header,一般用在測試資源是否存在上;OPTION 是詢問這個資源應該要怎樣獲取,一般用在發送 CORS 的預檢(preflight)請求。後端

目前講的都是在規範中提到且建議的通常用法,實際服務器的 API 怎麼開發依然是看實現的人;但經過語意化的方法去設計 API,絕對可讓 API 對開發者更加友好。瀏覽器

RESTFul API

前面所說只是規範,並且只涉及到了 HTTP 方法;有沒有更完整的實現方法呢?緩存

固然有,這就是你們耳熟能詳的 RESTFul API;它由 Roy Fieldin 在 IEFT 開發HTTP 標準的六年間持續研究、驗證的,並在 2000 年在他的博士論文 《Architectural Styles and the Design of Network-based Software Architectures》 中所提出,是一種網絡程序的設計風格;所謂的 REST 是 表現層狀態轉換(Resource Representational State Transfer) 的縮寫,簡單說就是經過動詞(HTTP 方法)、名詞(URI/URL,表明目標資源)、內容型態(響應的內容,如 HTML、XML、JSON 等),讓無狀態的網絡通訊能經過 REST 的語意化設計,攜帶全部的狀態進行通訊,下降對網絡的重複請求而形成的資源消耗。bash

例如假設有一個視頻網站:myku.com,它的的 API 有可能就會是這樣:服務器

[GET] http://myku.com/v1/videos/ -> 獲取 video 列表
[POST] http://myku.com/v1/videos/-> 新增 video
[GET] http://myku.com/v1/videos/MgphHyGgeQU -> 獲取指定 ID 的 video
[PUT] http://myku.com/v1/videos/MgphHyGgeQU -> 修改指定 ID 的 video
[DELETE] http://myku.com/v1/videos/MgphHyGgeQU -> 刪除指定 ID 的 video
除了所使用的方法以外,也要注意表明資源的 URL 的編寫方式,不是 HTTP 方法與實際動做相符合就算是 RESTful API !

一樣的,RESTFul API 只是設計風格而不是 HTTP 的規範,頗有可能在設計時基於 RESTful 的精神,但實際開發的結果卻徹底不是 RESTful 的風格;但不能否認的是經過 RESTful API 的設計風格,每一個資源都會獲得一個到對應的位置(URL),並能經過 HTTP 語意化的方法,對指定的資源作相對應的互動,總體資源管理會變得很是有語意化而且清晰,這確實是一個優秀的 API 設計方式。

規範與實現

在 HTTP 規範中提到要如何正確使用方法,若是咱們沒有按照規範實現,會形成必定的影響。

緩存

瀏覽器默認會對 GETHEAD 這兩個方法作緩存,若是經過 POST 而不是 GET 獲取資源的話,瀏覽器及中間的代理服務器通常都不會實現緩存機制,這時就必須由先後端開發自行經過其餘方式設置緩存。

在規範中雖然也提到了 POST 在 Header 合適的狀況下也能夠緩存,但因爲實際上一般把 POST 用在新增操做上,作緩存的話反而會形成不可預期的後果,大部分瀏覽器也都沒有實現針對 POST 的緩存機制。

SEO

當搜索引擎的爬蟲在掃網站時,若是發現須要經過 POST 獲取的資源,爲了不形成意外的行爲或反作用,一般不會嘗試爬取 POST 響應的結果。

GraphQL

雖然 RESTful API 的設計風格優勢不少,但也有一些難以免的缺點。

例如在查找存在依賴關係的嵌套數據時,頗有可能必需要通過屢次請求想要才能找到想要的結果;而隨着項目架構逐漸擴張,同一頁面的資料也會愈來愈複雜,可能須要多個來源的資料才能堆砌出頁面,這時候 RESTful API 須要說明每一個資源位置的特性,就會使 RESTful API 顯得不太好用;也由於如今移動設備很是普及,一個後端服務器可能須要服務於 PC 版網頁、手機 APP 等多設備的需求,須要的數據可能不同,RESTful API 也就必需要實現出多個功能相似的接口,API 會逐漸變得龐大並且龐雜,相對難以管理。

有需求就會有解決的方法。這時 GraphQL 就應運而生了,這是由 Facebook 提出的開源語言標準,經過 Schema 定義資料,再依靠與 JSON 格式高度相似的查詢語句取得查詢的結果,它的主要特色是:

  • 強類型
  • 查詢語句即文件
  • 查詢語句即響應的數據結構,不會有冗餘的內容
  • 統一的對外入口
  • 能夠多查詢合併,一塊兒返回

這些特性有效的解決了 RESTful API 在複雜架構下的問題,使 GraphQL 充滿彈性、很是好用,社區也已經有了龐大的的生態系統支持,例如 Apollo GraphQL 能夠與三大框架深度整合,再加上多查詢合併的特性,讓 GraphQL 與現代框架中組件的概念完美契合。

缺點大概就是必需要把全部複雜的數據拼接邏輯都實如今後端,對於習慣於 RESTful API 的開發者來講,須要付出很多學習成本。

值得注意的是 GraphQL 發出的所有都是 POST 請求,緩存機制必須仰賴開發者或是框架實現;例如在 Apollo Client 中,開發者必須按照應用場景,調整 fetchPolicy 的設置,避免快取形成的意外結果。

後記

本文的標題是我一位朋友去面試某大廠後端時的一道面試題,由這個題目引伸出 HTTP 方法及主流的 RESTful API 設計風格,並對 GraphQL 作了簡短的介紹,但願以上內容可以幫到你。

173382ede7319973.gif


本文首發微信公衆號:前端先鋒

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎繼續閱讀本專欄其它高贊文章:


相關文章
相關標籤/搜索