這裡有幾個問題要問你:你如何使用 Google、Apple 或 Microsoft 帳戶登錄應用程式?Paystack 或 PayPal 的在線支付是如何運作的?像 Facebook 和 Instagram 這樣的應用程式如何共享資訊和通知?

答案是:它們使用 API。這些是推動行動和網頁開發以及各種應用程式(包括雲端服務、物聯網設備、桌面軟體等)的強大工具。

API 使應用程式之間能夠進行溝通,促進數據的交換和驗證。

在這篇文章中,你將學習有關 API 的所有知識:不同類型、它們的架構,以及不同架構之間的權衡。

我們將涵蓋以下內容:

本文適合網站和移動應用程式開發新手以及尋求對 API 以及其功能有簡潔了解的開發者。

什麼是 API?

API 意為應用程式介面,它是一組讓不同軟體系統彼此通訊的規則和協定。API 定義了應用程式如何請求服務並交換資料,充當客戶端和伺服器之間明確的合約。

API 簡化了複雜的程式碼為簡單的命令,讓開發者可以連接系統並使用內建功能,而不需要了解所有內部運作。

API 如何運作?

想像一家餐廳:顧客(客戶端)透過服務生(API)點餐,服務生再將訂單傳達給廚房(伺服器)。廚房準備餐點並透過服務生送回給顧客。就像服務生一樣,API 處理請求和回應,讓顧客享受美食而不需要了解廚房的運作細節。

一個更實際的例子是當您在線購買訂閱時,您的付款資訊被安全地發送到 Paystack 通過其支付 API。API 是一個中間人,接受您的請求,驗證並處理您的付款詳細資料與銀行,然後返回確認給網站,而不直接暴露敏感資料。

從技術上講,客戶端發起針對伺服器的請求,指定數據檢索或程序執行。當API接收到並驗證此請求後,將執行所需的操作。然後,API向客戶端發送回應,包括請求的結果(成功或失敗)以及任何請求的數據元素。

為什麼API很重要?

API在軟體開發中至關重要,因為它們使不同應用程式和服務之間的連接變得更容易。它們讓您在不從頭開始構建所有功能的情況下集成外部功能,通過標準化的命令節省時間並減少複雜性。

對於用戶而言,API還增強了安全性和用戶體驗。它們作為安全的閘道,過濾應用程式與外部服務之間的數據交換,保護敏感信息,同時確保流暢和可靠的互動。

API的類型

API類型主要根據其可訪問性和使用情況進行分類。API主要有四種類型,即:

  1. 開放(公共)API

  2. 夥伴API

  3. 內部(私有)API

  4. 復合API

開放API

開放API是向公眾提供的API。這鼓勵開發者、組織和其他人使用它們來開發應用程式、將其集成到服務中並進行改進。開放API提供對互聯網上數據或服務的標準化訪問。

一些非常有用的開放式API包括:

合作夥伴API

合作夥伴API是與特定商業合作夥伴共享的,通常需要身份驗證和協議。它們為企業和應用程序執行必要的功能。

例如,像 Paystack 這樣的支付 API 直接與服務提供商和銀行平台進行通信,以處理產品和服務的支付。

內部 API

內部 API 用於組織內部的通信。它們能夠整合並簡化內部流程。內部團隊使用 API 在其應用程序之間訪問和共享數據。該 API 不對外公開,確保敏感的業務邏輯保持安全。

一個例子是一家公司的內部 API,將其人力資源、薪資和項目管理系統連接起來。

復合 API

復合 API 將多個 API 調用組合成單個請求。它們在微服務架構中非常重要,因為單個操作可能需要來自多個服務的數據。一次 API 調用觸發對多個底層 API 的請求,然後復合 API 將響應組合並返回統一的結果。

例如,一個電子商務平台可能會使用復合 API 一次性獲取產品詳細信息、定價和庫存資訊,從而減少延遲並簡化整合過程。

API 架構類型

API 的結構根據用例、可擴展性、安全性和可訪問性而有所不同。API 的結構方式有多種,但我們將僅關注在 Web 開發中最常見的架構風格。它們包括:

  1. REST

  2. SOAP

  3. GraphQL

  4. gRPC

REST API

表現層狀態轉移(REST)是一種架構風格,使用 HTTP 方法(POST、GET、PUT、DELETE)對基於資源的 URI 執行 CRUD(創建、讀取、更新、刪除)操作。

REST API 通常使用像 Express.js(Node.js)、Django/Flask(Python)和 Spring Boot(Java)等框架構建。

關鍵組件

  1. 資源和端點:

    • API 所暴露的實體可以包括任何東西:用戶、產品、文檔等等。

    • 每個資源由唯一的 URI(統一資源標識符)來識別。

  1. HTTP 方法:

    • GET:檢索資源。

    • POST:創建一個新資源。

    • PUT:更新現有資源。

    • DELETE:刪除資源。

    • PATCH:部分更新現有資源。

  1. 資料表示:

    • 資源可以有多個表示形式(例如 JSON、XML)。

    • API 會回應請求的表示形式,使資料易於結構化和解析。

  1. HTTP 標頭和查詢參數:

    • HTTP 標頭提供有關請求或回應的其他資訊。

    • 它們可用於身分驗證、內容協商和其他用途。

  1. 無狀態性:

    • 客戶端到伺服器的每個請求必須包含所有必要的信息,以便理解和處理該請求。

    • 伺服器不會在請求之間存儲任何客戶端狀態。

其他值得注意的組件包括可快取性、HTTP狀態和HATEOAS。這些組件一起定義了RESTful系統的結構和行為,實現了客戶端和伺服器之間無縫高效的通信。

操作概述

REST API通過唯一的URI公開資源,並允許客戶端使用HTTP方法(如GET、POST、PUT、DELETE和PATCH)執行操作。客戶端可以以JSON或XML等各種格式請求數據,並通過HTTP標頭和查詢參數包含其他詳細信息。

每個請求都是無狀態的,並包含了處理所需的所有信息,而不依賴於存儲的客戶端數據。API還使用HTTP狀態碼、可快取性和HATEOAS來管理響應並引導進一步的交互,確保客戶端和伺服器之間無縫高效的通信框架。

實際範例和真實應用案例

為了說明REST API在實踐中的運作方式,讓我們考慮一個書籍API,該API允許用戶管理一組書籍。我們的範例API是使用NodeJSExpressJS框架創建的。我不會在這裡解釋這些框架的實際工作原理,因為這超出了本文的範圍。因此,如果您不了解下面代碼中的語法,請不要擔心 – 只需專注於請求響應邏輯。

該API遵循REST原則,使用標準的HTTP方法執行CRUD(創建、讀取、更新、刪除)操作:

const express = require("express"); const bodyParser = require("body-parser");
const app = express(); app.use(bodyParser.json());

const app = express();
app.use(bodyParser.json());

// 虛擬數據庫
let books = [
  { id: 1, title: "The Pragmatic Programmer", author: "Andy Hunt" },
  { id: 2, title: "Clean Code", author: "Robert C. Martin" },
];

// 獲取所有書籍(客戶端請求,伺服器響應)
app.get("/books", (req, res) => res.json(books));

// 按ID獲取單個書籍
app.get("/books/:id", (req, res) => {
  const book = books.find((b) => b.id === parseInt(req.params.id));
  book ? res.json(book) : res.status(404).json({ message: "Not found" });
});

// 發布新書籍(客戶端發送數據,伺服器更新數據庫)
app.post("/books", (req, res) => {
  const newBook = { id: books.length + 1, ...req.body };
  books.push(newBook);
  res.status(201).json(newBook);
});

// 更新書籍
app.put("/books/:id", (req, res) => {
  const book = books.find((b) => b.id === parseInt(req.params.id));
  if (book) {
    Object.assign(book, req.body);
    res.json(book);
  } else {
    res.status(404).json({ message: "Not found" });
  }
});

// 刪除書籍
app.delete("/books/:id", (req, res) => {
  const index = books.findIndex((b) => b.id === parseInt(req.params.id));
  if (index !== -1) {
    books.splice(index, 1);
    res.json({ message: "Deleted" });
  } else {
    res.status(404).json({ message: "Not found" });
  }
});

app.listen(3000, () => console.log("API running on port 3000"));

以下是這段代碼中正在發生的事情:

  • 客戶端發送請求:用戶(或前端應用程序)使用GET、POST、PUT或DELETE等HTTP方法請求數據。例如:GET /books 請求所有書籍或POST /books 將新書籍發布到數據庫。

  • 伺服器處理請求:伺服器接收請求,查找數據(例如,從資料庫或內存陣列中),並進行處理。

  • 伺服器發送響應:伺服器返回包含請求數據或確認消息的 JSON 響應。這是一個示例:

[
  { "id": 1, "title": "The Pragmatic Programmer", "author": "Andy Hunt" },
  { "id": 2, "title": "Clean Code", "author": "Robert C. Martin" }
]
  • 客戶接收並使用數據:前端或其他服務消費 API 響應並相應地顯示或處理它。

團隊利用 REST API 進行網絡服務、移動應用和雲整合。社交媒體平台獲取帖子,而電子商務網站檢索產品詳情。支付網關處理交易,氣象應用訪問實時預報。REST 的簡單性和可擴展性使其成為公共和內部 API 的首選。

SOAP API

簡單物件存取協定(SOAP)使用 XML 進行消息傳遞,並包含內建的安全性、交易和錯誤處理標準。其正式契約由 WSDL(網絡服務描述語言)定義。

此架構透過如 WS-Security 和交易管理等功能優先考慮安全性和可靠性,使其適合需要嚴格標準和強大錯誤處理的複雜企業應用程序。

SOAP API 使用如 Apache CXF、.NET WCF 和 JAX-WS(Java)等框架或工具創建。

關鍵組件

  1. SOAP 信封:

    • 這是 SOAP 消息的根元素,定義了 XML 文檔的整體結構。

    • 它包含 SOAP 標頭和 SOAP 主體。

  1. SOAP 主體:

    • 此部分包含客戶端和服務器之間實際交換的數據。

    • 它包括請求或響應消息,這些消息通常結構為 XML 元素。

  1. WSDL(Web服务描述语言):

    • 这是描述Web服务的XML文档,包括其操作、消息格式和数据类型。

    • 它充当客户端和服务器之间的合同,概述如何与API进行交互。

  1. SOAP处理器:

    • 这是处理SOAP消息的软件组件。

    • 它解析XML文档,提取相关数据,并执行请求的操作。

SOAP 端點是可以訪問 SOAP 服務的 URL,XML 架構(XSD)定義了 SOAP 消息的 XML 中使用的結構和數據類型。

操作概述

SOAP API 通過將數據封裝在由 SOAP 信封定義的基於 XML 的結構中運作,該信封包含用於元數據的標頭和用於實際請求或響應信息的主體。主體攜帶交換數據,而 WSDL 文檔則作為詳細說明服務操作、消息格式和數據類型的合同。

然後,SOAP 處理器解析 XML,提取相關數據,並根據伴隨的 XML 架構(XSD)定義的規則執行請求的操作。與服務的通信通過特定的 SOAP 端點進行,確保了網絡服務互動的標準化和可互操作的框架。

實用示例和實際用例

為了說明 SOAP API 及其實際工作原理,讓我們考慮一個基於 SOAP 的銀行服務 API,該 API 提供安全的帳戶和交易管理操作。SOAP API 使用 XML 消息確保系統之間安全且結構化的通信。創建 SOAP API 和 XML 消息超出了本文的範疇,因此我們將僅專注於請求和響應邏輯。

如何運作:

  • 檢索帳戶信息:客戶端發送 XML 請求以獲取用戶的帳戶詳細信息:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:bank="http://example.com/bank">
   <soapenv:Header/>
   <soapenv:Body>
      <bank:GetAccountDetails>
         <bank:AccountNumber>123456789</bank:AccountNumber>
      </bank:GetAccountDetails>
   </soapenv:Body>
</soapenv:Envelope>

服務器響應一條包含帳戶詳細信息的 XML 消息:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <GetAccountDetailsResponse>
         <AccountNumber>123456789</AccountNumber>
         <Balance>5000.00</Balance>
         <Currency>USD</Currency>
      </GetAccountDetailsResponse>
   </soapenv:Body>
</soapenv:Envelope>
  • 處理匯款: 客戶提交帶有驗證細節的匯款請求:

      <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                        xmlns:bank="http://example.com/bank">
         <soapenv:Header/>
         <soapenv:Body>
            <bank:TransferFunds>
               <bank:FromAccount>123456789</bank:FromAccount>
               <bank:ToAccount>987654321</bank:ToAccount>
               <bank:Amount>100.00</bank:Amount>
               <bank:Currency>USD</bank:Currency>
            </bank:TransferFunds>
         </soapenv:Body>
      </soapenv:Envelope>
    

    如果成功,伺服器將返回確認響應:

      <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
         <soapenv:Body>
            <TransferFundsResponse>
               <Status>Success</Status>
               <TransactionID>TXN987654</TransactionID>
            </TransferFundsResponse>
         </soapenv:Body>
      </soapenv:Envelope>
    

銀行、醫療提供者和政府機構使用SOAP進行安全、可靠的API。金融機構在嚴格的身份驗證下處理交易,而醫療系統則根據合規法規交換病人數據。航空公司依賴SOAP進行訂票和票務,確保系統之間的一致數據完整性。

GraphQL API

GraphQL是由Facebook開發的API查詢語言和運行時。它允許客戶在單一請求中準確請求所需的數據,減少過度獲取和不足獲取的情況。

關鍵組件

  1. 架構:這是GraphQL API的核心。它定義了數據的結構,包括對象的類型、字段及其關係。它作為客戶端和伺服器之間的合約,指定可以查詢的數據。
  1. 類型:這些定義了數據中對象的結構。它們指定每個對象的字段及這些字段的數據類型。
  1. 字段:這些是可以在對象上查詢的單個數據片段。
  1. 查詢:這些是客戶端用來檢索數據的請求。它們指定客戶端希望恢復的字段。
  1. 變更:這些是客戶端用來修改數據(創建、更新或刪除)的請求。
  1. 解析器:這些是為模式中的每個字段提取數據的函數。它們將GraphQL模式連接到底層數據源。
  1. 訂閱:這些使得實時更新成為可能。客戶端可以訂閱特定事件,伺服器將在事件發生時推送更新。

操作概述

GraphQL定義了一個指定可用數據類型及其關係的模式。然後客戶端構建查詢或突變,精確地請求所需的數據字段。GraphQL伺服器處理這些請求,使用解析器從後端數據源提取數據。

伺服器根據模式驗證請求,執行解析器,並返回僅包含所請求數據的JSON響應。客戶端可以建立訂閱以進行實時更新,使伺服器能夠在其出現時推送數據更改。這種方法最大程度地減少了過度提取和不足提取,提高了數據檢索的效率和靈活性。

實際示例和實際用例

通過考慮由GraphQL提供動力的電子商務API,讓我們探索GraphQL API如何實際運作。此API可以有效地提取產品詳細信息、評論和庫存可用性。伺服器是使用NodeJS和創建的。創建伺服器超出了本文的範圍,因此我們將專注於模式(關係數據庫的結構和視覺呈現)以及請求響應邏輯。

  1. 模式:
# 模式(schema.graphql)

type Product {
  id: ID!
  name: String!
  description: String
  price: Float!
  inventory: Int!
  category: String!
}

type Query {
  product(id: ID!): Product
  products(category: String): [Product!]!
}

type Mutation {
  createProduct(name: String!, description: String, price: Float!, inventory: Int!, category: String!): Product!
  updateProductInventory(id: ID!, inventory: Int!): Product!
}

模式定义了数据类型(ProductQueryMutation),并指定了可用的查询(productproducts)和突变(createProductupdateProductInventory)。它使用了GraphQL类型系统(String,Int,Float,ID,[ ],!)

  1. 請求和回應

    • 獲取產品數據 – 客戶請求特定產品字段(例如,名稱,價格和描述):

        查詢 {
          產品(id: "123") {
            名稱
            價格
            描述
          }
        }
      

      如果成功,服務器將只回應請求的數據:

        {
          "data": {
            "product": {
              "name": "無線耳機",
              "price": 99.99,
              "inStock": true
            }
          }
        }
      
    • 創建新產品:

        突變 {
          創建產品(名稱: "滑鼠", 價格: 30, 庫存: 100, 類別: "電子") {
            id
            名稱
            價格
          }
        }
      
    • 更新產品信息:

        突變 {
          更新產品(id: "123", 價格: 89.99) {
            名稱
            價格
          }
        }
      

      如果成功,服務器將返回更新後的詳細信息:

        {
          "data": {
            "updateProduct": {
              "名稱": "無線耳機",
              "價格": 89.99
            }
          }
        }
      

像 Facebook 和 Shopify 這樣的公司使用 GraphQL 來實現高效且靈活的 API。電子商務和社交應用僅提取所需的資料,減少過度提取。行動應用優化性能,而分析工具則無縫地匯總複雜的數據。

gRPC API

遠程過程調用(gRPC)是一個高性能的 RPC 框架,使用 HTTP/2 和 Protocol Buffers 對結構化數據進行序列化。它支持同步和異步通信,並具備流媒體等特性。

HTTP/2 是 HTTP 的最新演進,設計上具備二進制幀、複用、標頭壓縮和伺服器推送等令人興奮的功能,以提升性能並減少延遲。gRPC 充分利用這些能力,使快速、高效和同時的通信成為可能,這使它非常適合微服務和實時應用。

關鍵組件

  1. 服務定義:這在 .proto 文件中定義。它指定提供的服務和可用的 RPC 方法,作為客戶端和伺服器之間的合約。

  2. 消息是使用 Protocol Buffers 定義的數據結構,能有效地在系統之間進行數據的序列化和反序列化。

  3. 存根:自动生成的客户端和服务器端代码,使客户端可以调用远程方法,就像它们是本地的一样,并使服务器能够实现服务逻辑。

  4. 通道:这些管理客户端和服务器之间的连接,处理底层网络通信。

  5. RPC 方法:gRPC支持不同类型的调用,包括一元(单个请求-响应)、客户端流式传输、服务器端流式传输和双向流式传输,每种类型适用于不同的用例。

  6. 拦截器和元数据:这些提供机制来添加额外功能,如身份验证、日志记录和错误处理,通过将元数据附加到RPC调用中。

操作概述

gRPC 使開發者能夠在 .proto 檔案中定義服務合約和訊息類型,並以 Protocol Buffers 作為可用 RPC 方法的藍圖。代碼生成器會產生客戶端和伺服器的存根,允許遠端程序像本地函數一樣被調用,而通道則管理基於 HTTP/2 的網路通信。

它支持單一請求、客戶端串流、伺服器串流和雙向串流,以適應不同的數據交換模式。此外,還可以整合攔截器和元數據來執行身份驗證和日誌記錄等任務,使系統保持穩健、安全和高效。

實用範例和實際案例

讓我們考慮一個使用 gRPC 進行客戶端(行動應用程式)與後端服務之間快速通信的共乘應用程式。gRPC 使用透過協議緩衝區(Protobuf)的二進制序列化,而不是像 JSON 或 XML 這樣的基於文本的格式。這使得網路通信顯著更快且更有效率。

  1. .proto 檔案定義了 API 結構:
syntax = "proto3";

service RideService {
  rpc RequestRide(RideRequest) returns (RideResponse);
  rpc StreamRideUpdates(RideUpdateRequest) returns (stream RideUpdate);
}

message RideRequest {
  string user_id = 1;
  string pickup_location = 2;
  string destination = 3;
}

message RideResponse {
  string ride_id = 1;
  string driver_name = 2;
  string car_model = 3;
}

message RideUpdate {
  string ride_id = 1;
  string status = 2;
  string driver_location = 3;
}

message RideUpdateRequest {
  string ride_id = 1;
}

當客戶端發送一個 RideRequest 時,它會使用 Protobuf 被序列化為緊湊的二進制格式。這樣可以減少有效載荷大小,加快傳輸速度,並提高效率。伺服器在處理之前會將其反序列化回結構化的物件。

  1. 請求和響應:

    • 乘車請求:客戶按下按鈕發送乘車請求,包括:

        {
          "user_id": "U123",
          "pickup_location": "中央公園",
          "destination": "時代廣場"
        }
      

      伺服器回應駕駛員詳細信息:

        {
          "ride_id": "R456",
          "driver_name": "約翰·道",
          "car_model": "豐田普魯斯"
        }
      

      您一定會好奇為什麼請求和響應以 JSON 顯示,因為 gRPC 不使用像 JSON 和 XML 這樣的基於文本的格式。 gRPC 中使用的壓縮二進制流不像 JSON 那樣可讀。 它是一種緊湊、高效的編碼格式,需要在幕後進行 Protobuf 反序列化才能理解。 在壓縮二進制流格式中,請求或響應會如下所示:

        08 D2 04 12 0D 43 65 6E 74 72 61 6C 20 50 61 72 6B 1A 0B 54 69 6D 65 73 20 53 71 75 61 72 65
      
    • 即時乘車更新流:一旦分配了乘車,伺服器即向客戶流式傳送實時更新:

        {
          "ride_id": "R456",
          "status": "司機在路上",
          "driver_location": "第五大道"
        }
      

公司使用 gRPC 來滿足高效能、實時應用程序對高效服務通信的需求。像 Google、Netflix 和 Dropbox 等科技巨頭利用 gRPC 來實現可擴展的微服務。共乘應用程式實時串流司機位置,而金融科技平台則管理安全、低延遲的交易。物聯網系統和人工智慧應用依賴 gRPC 進行實時數據交換和高效互動。

如何選擇 API 架構

選擇 API 架構涉及平衡多種因素,包括性能、可擴展性、易用性和安全性,根據您項目的具體需求進行調整。

REST 以其簡單性和無狀態設計而聞名,這有助於可擴展性和易用性,但其安全性主要依賴於 HTTPS 和適當的身份驗證機制等外部措施。

SOAP 雖然更為複雜,但提供穩健的內建安全標準(如 WS-Security)和可靠的事務支持,適合企業環境。

GraphQL 透過允許客戶端僅請求所需的數據來提供高效的數據獲取和高性能。但它可能需要額外的安全措施,例如查詢深度限制和伺服器端的適當身份驗證。

gRPC 提供卓越的性能,特別適合具有實時數據需求的微服務。它利用 HTTP/2 和 TLS 進行安全、高效的通信,儘管學習曲線較陡。

以下表格總結了這些架構之間的特徵和權衡:

特徵 REST SOAP GraphQL gRPC
表現 中等(可能存在過度提取數據的問題)
擴展性 中等 非常高(適用於微服務和實時數據)
易用性 簡單且廣泛採用 複雜 對客戶直觀(服務端複雜度可能增加) 陡峭的學習曲線
安全性 依賴外部機制(HTTPS、OAuth等) 通過WS-Security和正式協議具有強大的內建安全性 需要額外的措施(查詢驗證、速率限制) 具有內建TLS支持和強大的身份驗證協議的高安全性

API已成為現代軟件開發中的支柱,促進不同應用程序之間的無縫通信和數據交換。它們的影響是不可否認的,從推動創新的公共API到簡化內部流程的私有API。

了解各種API架構,如REST、SOAP、GraphQL和gRPC,有助於開發人員選擇適合其特定需求的最佳方法,平衡性能、擴展性和易用性。

展望未來,API 生態系統將迎來令人興奮的變化。隨著人工智慧驅動的 API、去中心化架構和改進的安全措施,我們將看到構建和與軟體互動的新方式。API 標準的持續演變以及低代碼/無代碼平台的增長使得 API 開發對每個人來說變得更加可及。