何謂 Omni-Channel Retail 全通路零售 (全渠道零售):https://21st.each1.net/2018/07/omni-channel-retail.html
已經進入SaaS / PaaS / IaaS 時代已久,還在用舊時代想法規劃網站嗎?
「 以Google為例,透過 GoogleMapAPI,第三方開發者可以輕易的使用 Google Map 所提供的套件,串接Google的地圖資料,並鑲嵌在自己的網路。Twitter 利用 WebAPI 分享他們龐大會員的資訊。Amazon 則提供了一個代管主機的應用介面;微軟更是把傳統的Office變成了雲端服務的Office365 」
從上述案例來看,以雲端服務為導向的商業模式,正在這幾年蓬勃發展。但並非是透過網路就是所謂的雲端服務,從雲端機房到WebAPI,其中的學問可是大不相同,雲端服務的類型如下:
傳統方式:
過去的網路公司,主要都是以傳統方式建置產品和服務,不管是從Server硬體、網路、作業系統、機房等等,都由公司一手包辦。而為因應產品的類型,是否用多少頻寬的網路、作業系統、是否使用虛擬主機VM等...都會影響到產品的效能,這樣的建置方式不僅需要對每個技術環節,都有相當程度的了解和考究,投入的時間和人力成本也更是一大考量。
IaaS(Infrastructure as a Service),基礎建設即服務 :
將網路建置及server硬體採買、是否虛擬化過程交給廠商管理,而公司本身只要針對硬體設施以外的項目如作業系統、硬體上所需執行的服務及應用程式即可,或是我們可以解釋成僅和外部廠商租賃雲端機房、伺服器、網路環境等等,而不用像過去需要在公司內部自行建置機房,而大部分提供雲端機房的環境亦提供恆溫、24小時監控外、機房本身又具備高規格的防震等級,可以有效負擔掉企業內部機房的維運成本。
PaaS(Platform as a Service), 平台即服務:
除IaaS的項目之外,更把作業系統、開發程式環境都交給廠商管理,這樣公司只要專注在資料處理及服務(應用程式)的開發項目,就像Microsoft Azure所提供的Paas服務,像IaaS一樣提供包括基礎架構服務器,存儲和網路,而且還包括開發環境、開發工具,商業智能(BI)服務,數據庫管理系統等。以微軟Azure而言,PaaS旨在支援完整的Web應用程序生命週期:構建,測試,部署,管理和更新,並於Paas項目上提供更完善的維護及管理。
SaaS(Software as a Service),軟體即服務:
透過提供已經產品化的軟體服務是近年來營利的一大趨勢,使用者不再需要負擔自己的開發成本,只需要向廠商訂購該服務,就可以替企業省下大筆的資金。舉Google為例,它提供免費的電子郵件、日曆等服務給大眾使用外,還針對企業推出服務層級協定(SLA)較高的付費網路郵件服務,企業不需要另外採購應用電子郵件的軟體和硬體設備,只要訂購Google的Gmail服務,就能取代自建的電子郵件系統。
像Google Analysis & Adobe Sitecatalyst,也屬於SaaS的一種,提供以監控平台作為服務,透過Web方式登入並提供資料挖掘和商業數據分析。像是社群網站Facebook也可以算是SaaS的一種囉! (常見的SaaS例如 Gmail郵件、Zendesk線上客服、Codepen 線上程式編輯器)
補充說明:
這邊的SaaS與在網站開發CSS style 進階技術的Sass唸起來是一模一樣。
如果這口語上聽到這個詞必須要依照內容情境來推論對方在講什麼,商業上多半是講SaaS,網站開發規格則比較可能是Sass。
「從SaaS談到API,進入雲端產品的新世代」
以雲端產品為代表的新時代即將到來,大型企業在軟體上的開發、維護與消費上都出現了重大轉變,更代表著程式設計師在未來可以賦予產品上更高的服務價值,AWS,Facebook,Google,Twitter和數千家其他網路公司,都透過提供WebAPI的方式大打經濟戰,而服務與服務之間的互動,也從過去SaaS的接口,轉移到WebAPI身上,那API是什麼呢?
API全名叫做應用程式介面(英語:Application Programming Interface,簡稱:API),主要的概念就是把各家或是各種軟體系統的「服務」,做成一種可以「互相溝通」的一種介面,透過服務呼叫、串接的方式來進行產品與產品之間的合作與溝通,重點就在「服務」與「互相溝通」這兩個關鍵字上。
補充說明:
其實很多網路公司在內部討論的時候不用 WebAPI,而直接使用API來稱呼網路服務接口,但API 的全名 Application program interface 只是代表應用程式的使用介面/接口,遠在網際網路還不純熟的時代就已經存在,無論是C語言系列的header檔,到製作成動態函式庫,都可以使用這個名稱。因此本文以WebAPI來表達一般網站所提供的外部程式接口。
我們舉例來說吧
當我們要去大賣場買鞋子的時候,找到了心儀的鞋子卻找不到適合的尺寸,這時該怎麼作呢?
當然我們可以翻箱倒櫃的在賣場中去尋尋覓覓,但這通常不是一般人會做出的直覺選擇吧,其中花費的時間與體力都是無形中的一種成本,還未必可以找到想要的東西,所以我們通常都會選擇「請店員來協助我們」做為我們找鞋子的方式吧!
當你在呼喚了店員請他們協助時,無形中就是對「服務」的一種呼叫,而呼叫店員的這動作就是「API」,他提供的是一種服務,透過呼叫的方式來和另外一支服務「協助找尺寸」去做串接。
1.想找到想要的鞋子尺寸:服務的目的
2.呼叫店員請店員協助:與「協助找尺寸」 的服務進行呼叫與溝通
3.跟店員表示自己要的鞋子和尺寸:提出呼叫服務的需求與規格-我要什麼東西
4.拿到鞋子:完成你需要的服務
當然,主要透過Web作為介面的,就是WebAPI囉!
舉一個實際上在網站上的例子吧!
像 Uber 中使用 GoogleAPI 來當作地圖和導航的介面,不僅可以減少 Uber 團隊開發自己圖台及精算最佳路徑的成本,更可以把團隊的精力投注在優化產品服務及使用者體驗的項目上,無疑是對產品的一大助力。
而在一般我們看到的APP裡面,所有的動態資訊也都是透過WebAPI和後台DB去進行服務串接的,例如:連鎖咖啡店的會員APP,當你希望使用「檢視優惠」的服務時,就會透過WebAPI的方式,把APP後台上架的這些優惠活動、折扣等等,進行串接,而優惠活動更是動態且持續更新的,總不能每次都版本更新之後才把活動進行上架吧,光是 iOS 上架的那些繁瑣程序就會讓你心力交瘁了。
透過上述的例子,我們可以發現,一項集所有服務於一身的大型產品,不僅本身維運上的成本難以想象,其中對於所提供服務的彈性上更是較難突破,不如把服務切分成各種的WebAPI來做串接,不僅可以分散維護風險外,還可以透過「服務」來創造商機,例如以產品做接口來說,「電商網站」和「社群網站」就沒有達到有效的連想,但如果把電商網站的「搜索商品」、「推薦商品」做成一隻對外接口的廣告服務WebAPI,和Facebook的廣告WebAPI做對接,這樣不僅可以在瀏覽動態時做置入性行銷,透過社群間的串接後面產生的經濟效益,更是無法預期。
而一項項服務維護的費用,肯定比維護產品來的少許多,也許在產品草創的初期,有效的運用核心資源,把一些不必要的工作外包給這些雲端服務,並把軟體產品的功能「外包」給WebAPI,讓團隊專注在更快地創建和發布新的業務模式,來保持公司的業務彈性與競爭力,也許這也是快速開發的重要法則。
RESTful Web API
在HTTP協定中,定義了多種不同的method做為服務的請求方法,近年來由於行動裝置的普及化,越來越多的產品及網站,都提供了WebAPI服務,因此身為程式設計師的我們,在設計API為主的Web服務時,對於HTTP請求方式的認知,更是相當重要。
最常見的method,五種如下:
GET
POST
PUT
PATCH
DELETE
所有的字看起來既熟悉又陌生,因為在Http的協定下,每一種呼叫方式都會有一種他專屬的特殊定義,對於寫過網站的人來說,GET和POST絕對毫不陌生。
當Web service使用Web API進行介面介接時,每一串我們設計的URL,就會是一個專屬的服務『窗口』。
舉例來說,像是讀取及上傳的動作,就屬於完全不同的業務,所以當然也會用不同的呼叫方式來設計。
簡單說,不同的Method就是對同一件事情做不同的操作。
以搭買鞋子為例子做衍生吧!
GET:取得型錄,了解想要找的鞋子、型號、規格等。
POST/PUT:呼叫店員協助幫忙找鞋子,並買到想要的鞋子。
PATCH:結帳後向店員更換尺寸或加價購買其他配件如鞋帶、襪子等。
DELETE:跟店員說我不要了。
用生活化的例子講解完後,改以程式的角度來說明
GET:取得(想要的服務)的資料或是狀態。(safe & idempotent)
POST:新增一項資料。
PUT:利用更新的方式於"指定位置"新增一項資料。 (idempotent)
PATCH:在現有的資料欄位中,增加或部分更新一筆新的資料。
DELETE:指定資料刪除。 (idempotent)
這裡突然出現了兩個名詞 safe & idempotent,這兩個是HTTP狀態描述的專有名詞。
「safe」是指該操作不會改變原本的資源狀態,並且同樣的結果是可以被快取(Cache)的。
例如: 查看訂單是不會改變訂單本身紀錄。
「idempotent」是指該操作不管做1遍、2遍或多遍,都會得到同樣的資源狀態結果。
例如: 同一筆資料被DELETE了2次,雖然都是一樣的結果,但第二次發送會因為資料已經被刪除而失敗喔!
GET / POST 我們用得很多所以沒什麼問題,DELETE與字意上相符所以不難理解。
其中讓人困擾的是 PATCH & PUT,要解釋它們必須參考定義 (RFC 5789)。
https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5
依照 RFC 5789,
POST/PUT 都可以用來新增,
PATCH/PUT 都可以用來修改,
但其中的差別在哪裡呢?
POST的定義上屬於將原先沒有的資料去做一筆新增的動作,
PATCH就是一般常見的修改,
所以真的有問題的其實是PUT。
PUT在定義上(idempotent)無論做多少次,回傳結果都會一樣。
以POST來說,我要一雙鞋,我就會得到一雙鞋;
但是如果再用POST發一次我要一雙鞋,會出現兩種可能;
一種是我"再"得到一雙鞋,而且這雙鞋跟上一雙是不一樣的(以資料庫來說,就是ID不一樣);
或是我只能有一雙鞋,所以他會跟我說"錯誤"!! 我已經得到一雙鞋了。
但以PUT來說,無論我發多少次,他都會回我,我有一雙鞋,而我並不會變成兩雙鞋;
當然如果商店沒鞋,則變成我沒有鞋。
這點在很多程式框架裡面都有不完全正確,像 Ruby On Rails 的 PUT 與 PATCH 看起來是一件事(當然你可以自己修正)。
定義是絕對的,但應用是彈性的,所以你可以說這些框架做的與 RFC5789 不一樣,但或許這樣比較好用。
這就看個人取捨,當然,考試的時候通常需要寫 RFC5789 的定義。
另外,PUT 除新增外亦可以做更新請求,假設使用 PUT 做更新,不管是既有的資料或是覆蓋原先的資料,都會利用覆蓋的方式去更新,但假如你的資料裡面有圖檔的話,每 PUT 一次,圖檔就必須要再重新上傳一次,是相當耗費資源的。
而 PATCH 則可以針對已經存在的資料欄位去做部分更新,例如:我們在更新履歷表時,使用PATCH 就可以僅更新裡面的資料,如年齡、工作經歷等欄位,而 PUT 就像是把整份改好的履歷表重新上傳。
PATCH 也可以更新本身一開始 PUT 資料內沒有的欄位,故 PATCH 是非屬於 idempotent 的操作。
所以如果我們以電腦操作檔案來譬喻,建立一個新檔案是POST,修改檔案是PATCH,從別的地方複製檔案貼上就是PUT (無論你貼上幾次都是同一個檔案)。
當然Web API沒有一定要照著上面的定義敘述建立,但如果你符合的話,你可以將它稱作Restful API
(Rest化 = Restful,如果常常不知道講述的時候該用 Rest 或是 Restful 可以這樣去記,被轉化成 Rest架構 的 Web API = Restful API)
REST全名 Resource Representational State Transfer ,可譯為具象狀態傳輸,若是把各個單字拆開來解釋的話即如下:
Resource:資源。
Representational:表現形式,如 JSON,XML...
State Transfer:狀態變化。即上述講到的可利用HTTP動詞們來做呼叫。
簡單的說,就是一個單從發出的HTTP要求裡面所包含的資訊,就可以直接預期這要求會收到怎樣類型的資料。再更白話一點,就是人眼看得懂。
REST指的是網路中Client端和Server端的一種呼叫服務形式,透過既定的規則,滿足約束條件和原則的應用程式設計,對資源的操作包括獲取、創建、修改和刪除資源,這些操作就是依照我們前面所提到的HTTP Method: GET、POST、PUT、PATCH和DELETE。這正好會對應到資料庫基本操作CRUD。
CRUD 為 Create(新增)、Read(讀取)、Update(更新)與Delete(刪除)的縮寫。
接著我們繼續舉例來說,如果我們正在寫一隻商品的WebAPI,讓工程師隨便寫可能會有以下方式來作interface:
獲得商品資料 GET /getAllItems
獲得商品資料 GET /getItem/11
新增商品資料 POST /createItem
更新商品資料 POST /updateItem/
刪除商品資料 POST /deleteItem/
若是以使用 RESTful API 開發的話:
獲取商品資料 /GET /items
獲取商品資料 /GET /items/1
新增商品資料 /POST /items
更新商品資料 /PATCH /items/1
刪除商品資料 /DELETE /items/1
PUT 則是比較特別一點,其實它並不直接對應CRUD裡面的任何一項。
在這樣的風格中最有名的,應該就是 Ruby on Rails了吧!
透過 HTTP 為基礎來設計 RESTful API,不僅可行,更可以更簡單扼要呢!
最後要提醒大家,我們沒辦法直接在 HTML的<form>裡面使用GET 與 POST以外的Method,因為瀏覽器都還不支援,如果想要發送 Restful request 一般都要後台程式的支援,而且必須要在<form>裡面藏一個<input name="_method" value="你的HTTP Request方法"> 才有辦法送出去。
資料來源:
https://progressbar.tw/posts/51
https://progressbar.tw/posts/53

