結構化 RESTful API 模組與功能 大大提升程式碼的易讀性!


日常工作中,常常需要與後端串接 RESTful API,然而 API 網址常常很難管理與統一路口,今天這篇文章,想與大家分享在公司的經驗,一起規範出一整套 RESTful API 串接的體系與模組。今天這篇文章需要大家搭配源碼閱讀。讓我們開始吧!

要點內容

  1. 統一 API 底層入口,利用泛型來解決所有 JSON Data to Model 轉換
  2. 規範 API Function 結構,不再讓 URL 散落一地
  3. 統一的錯誤獲取,讓 debug 不再頭大
  4. 結合 PromiseKit 與 Alamofire,製作屬於你的非同步 API 網路應用

準備工作

這邊我們需要快速建立一個 UI 程式碼。為了聚焦重點,就不詳細說明 UI 的組裝過程了。

首先,我們需要先建立一個新專案,進行 pod init,並且編輯 Podfile加入必要組件如下:

編輯完成後就可以執行 pod install。然後,讓我們開啟 .xcworkspace 檔案,開始我們的 Coding之旅!

我們需要加入兩個 UIViewController,一個 UITableViewController

  1. LoginViewController – 登入頁面範例
  2. SignUpViewController – 註冊頁面範例
  3. ProductsViewController – 獲取產品頁面範例

另外加入一個 UITabBarController,命名為 MainTabBarController。參考程式碼如下:

另外,修改 AppDelegate 文件,讓我們的 window 連接到剛剛做好的 MainTabBarController

完成後就可以編譯和執行,你現在應該可以看到 UI 組件正常工作了!如果當中遇到困難的話,請參考源碼

到目前為止,我們的準備工作就完成了,讓我們進入主題吧!

註冊頁面 SignUpViewController

首先,我們需要先建立一個註冊頁面,模擬用戶註冊真實狀況。在頁面中,我們會需要幾個欄位,來配合 API 介面。

註冊 API 文件說明

POST
https://yasuoyuhao-restfulapi.herokuapp.com/api/account/signup

參數
字段 類型 描述

  • name String 使用者名稱
  • email String 使用者 email(登入帳號)
  • password String 使用者密碼
  • emailContext String 註冊成功 email 內容
    參數範例:

Response (example):
HTTP/1.1 200 註冊成功

Response (example):
HTTP/1.1 200 重複註冊

註冊頁面 UI 組件 Layout

我們查看 API 文檔中,發現需要輸入四個欄位。因此,我們需要在 SignUpViewController 建立四個 UITextField 和一個按鈕UIButton

首先,讓我們製作 UI 組件,並命名五個組件變數:

然後,在 viewDidLoad()layout 我們的組件:

完成後,應該可以看到以下畫面!

sign-up-page

建置 API Services

有畫面之後,我們就可以開始重頭戲了:串接我們的 API

首先,我們需要建立 BaseAPIServicesBaseAPIServices 是我們 API 最底層打包請求的服務,當中有兩個關鍵的重要方法:

  1. requestGenerator:負責生成我們的 Http 請求
  2. setupResponse:讀取生成的 Http 請求、發送請求、並解析 json data to model

你會注意到,setupResponse 是允許 Codable 泛型的,也就是說我們可以把model 丟進來讓它負責解析。

接下來,建立模組化的 URL 資源位置 APIServicesURLProtocol。我們先建立兩個 Protocol

再建立一個 Struct 存放基本路徑。請注意,如果有不同環境的路徑處理,也通常會在這邊處理,比如生產環境跟開發環境,baseurl 要做切換。

然後,我們建立授權模組的URL

如此一來,我們的模組化資源路徑就算完成了!

接下來,讓我們建立 AccountsAPIServices 負責 AuthAPIURL 的資源動作:

我們的流程有幾個步驟:

  1. 建立 Promise
  2. 組合 Post 參數
  3. 生成 Request
  4. 發送 Request
  5. 接收 Response (由 Base層解析 json)
  6. 處理已經解析好的資訊(商業邏輯)
  7. 完成流程 / 錯誤處理

只此為止,我們已經達成了規範 API Function 結構,資料解析、錯誤獲取、生成請求通一入口了。

串接頁面

我們完成了註冊需要的 API Services 之後,就可以來 Controller 層介接資料了。

讓我們來實作 handleSignUp 吧:

在上面的程式碼中,我們先打印出輸入的欄位訊息,並在驗證欄位呼叫我們剛剛做好的註冊服務層。

現在我們可以進行測試了!(建議帳號密碼要記下來,等下登入會用到)

首先,像這樣輸入欄位資料:

restful-api-test-1

然後,按下註冊按鈕,並查看控制台訊息

control-panel-2

太好了!我們完成了註冊頁面的製作與 API 的串接囉!接下來,讓我們處理登入頁面。

登入頁面 LoginViewController

登入 API 文件說明

User – 使用者登入
POST
https://yasuoyuhao-restfulapi.herokuapp.com/api/account/login

參數
字段 類型 描述

  • email String 使用者 EMail(登入帳號)
  • password String 使用者密碼

Response (example):
HTTP/1.1 200 登入成功

Response (example):
HTTP/1.1 200 登入失敗

登入頁面 UI 組件 Layout

我們查看 API 文檔中,發現需要輸入兩個欄位。因此,我們需要在 LoginViewController 建立兩個 UITextField,和一個登入按鈕UIButton

我們需要先建立 UI 組件。首先,命名三個組件變數:

接下來,在 viewDidLoad()layout 我們的組件:

完成後,你應該會看到這個畫面:

restful-api-test-2

建置登入的 API Services

下一步,我們需要到 AccountsAPIServices 加入登入方法:

完成了註冊需要的 API Services 之後,我們就可以來 Controller 層介接資料了。

先如此實作 handleLogin

然後,輸入剛剛成功註冊的帳號密碼來進行測試:

restful-api-test-3

接著,來查看控制台訊息:

control-panel-3

成功了!我們完成了註冊與登入的 API 串接,並且發現模組化規範 API 之後,我們串接的速度越來越快了!

進階:商品頁面 ProductsViewController

這邊是針對更接近實戰演練的串接,我們會先登入,並且帶入 Token 獲取商品列表。有興趣的讀者可以先自己實作看看,再來參考以下步驟。

取得產品 API 文件

Product – 取得產品
GET
https://yasuoyuhao-restfulapi.herokuapp.com/api/products
允許: Authorization 

Header
字段 類型 描述
authorization String Authorization value.

Response (example):
HTTP/1.1 200 成功

Response (example):
HTTP/1.1 200 查詢失敗


首先,建立AuthToken 加入變數 token。這樣我們進行請求時,就可以帶入 Token

接下來,調整修改 requestGenerator 方法,把 token 加入 Http Header 中:

注意:請注意,對於 headers 參數,我們當然可以再抽出 function 參數作為傳入值;但這邊先不深入探討這一點,有興趣的讀者可以自行優化。

然後,修改登入與註冊,以暫存 token:

下一步,讓我們逐一建立 Products ModelProductAPIURL、和 ProductsAPIServices

  • Products Model

ProductAPIURLProductsAPIServices 是用於存放獲取產品後的資料。

  • ProductAPIURL
  • ProductsAPIServices

我們已經自定義了資料型別,並且放入 self.setupResponse 自動解析。現在,我們可以來測試看看了!

讓我們在 ProductsViewController 中加入下列程式碼:

然後,執行並查看控制台(別忘了先到登入頁登入):

成功了!我們加入了 token 驗證機制,並且成功取得資料。

最後,讓我們在 ProductsViewController 完善 UI

讓我們來看看成果吧:

restful-api-demo

總結

在本篇教學中,我們透過抽離 API Services 層,來分化我們與後端串接的耦合性。實戰中還會有一層 Services 負責 View Model 的轉換,我們並不會直接使用後端來的 model,而是透過自定義錯誤處理,分離商業邏輯錯誤與系統錯誤。而且,我們也引入了 Promise 來幫助我們細分流程與非同步編程。這樣,不但大大優化了程式碼的易讀性,也單一職責化了各個服務,可以說是大規模的 App 中不可或缺的一部分。

恭喜!至此整個文章與概念已完全交付!強烈建議整個過程搭配源碼消化服用,祝你有個美好的 Coding 夜晚,我們下次見。

yasuoyuhao,自認為終身學習者,對多領域都有濃厚興趣,喜歡探討各種事物。目前專職軟體開發,系統架構設計,企業解決方案。最喜歡 iOS with Swift。

此文章為客座或轉載文章,由作者授權刊登,AppCoda編輯團隊編輯。有關文章詳情,請參考文首或文末的簡介。

blog comments powered by Disqus
訂閲電子報

訂閲電子報

AppCoda致力於發佈優質iOS程式教學,你不必每天上站,輸入你的電子郵件地址訂閱網站的最新教學文章。每當有新文章發佈,我們會使用電子郵件通知你。

已收你的指示。請你檢查你的電郵,我們已寄出一封認證信,點擊信中鏈結才算完成訂閱。

Shares
Share This