2026年10月6日 星期二

HTTP 與 REST API|Pico 2 W

Pico 2 W × Thonny|第 4 次課程

HTTP 與 REST API

前三次課程讓 Pico 2 W 控制硬體、連上 Wi-Fi,並提供自己的網頁服務。本篇把角色反過來:Pico 成為 HTTP Client,主動向 Internet 上的 API 取得資料,或把感測資料送到遠端服務。

作者:施朝斌

一、從 Web Server 走向 API Client

使用 Pico Web Server 時,手機或電腦的瀏覽器主動連進 Pico;使用遠端 API 時,則是 Pico 主動連到 API Server。API(應用程式介面)提供一組約定好的網址與資料格式,讓程式可以透過網路交換資訊。

HTTP ClientPico 發出要求,等待遠端服務回應。
API Server接收要求、處理資料,再回覆結果。
URL指出要存取的服務或資源位置。
JSON常見的資料格式,能以欄位名稱與值描述資料。

二、GET 與 POST:讀取資料和送出資料

GET 通常用來讀取某個資源,例如查詢天氣或取得感測器資料。POST 通常用來送出資料,例如把 Pico 讀到的感測值傳到伺服器。實際 API 會規定可用的方法、網址、欄位與驗證方式,因此呼叫前要先閱讀服務文件。

  • GET:向 API 詢問資料,常見形式是 GET /api/data。
  • POST:將資料送給 API,常見形式是 POST /api/telemetry。
  • Header:提供內容類型、授權資訊等要求或回應的附加資料。
  • Body:HTTP 要求或回應承載的內容;POST 常把 JSON 放在 Body。

GET 和 POST 是常見用途,不代表每個服務都完全相同。API 文件才是判斷端點、欄位、授權與資料格式的依據。

三、HTTP 狀態碼:先看請求結果

伺服器回應時會提供狀態碼,告訴 Client 這次要求大致如何處理。程式不能只假設回應一定成功,應先檢查狀態碼,再決定要解析回應資料或顯示錯誤。

200 OK要求成功,通常可讀取回傳內容。
201 Created伺服器成功建立了資源。
400 Bad Request要求格式或內容不符合服務規則。
404 Not Found指定的資源或路徑不存在。
500 Server Error伺服器處理時發生錯誤。

狀態碼是診斷線索:例如 404 可先檢查 URL 路徑,400 可檢查送出的欄位與 JSON 格式,5xx 則可能需要稍後重試或聯絡服務提供者。

四、Pico 使用 HTTP POST 傳送資料

投影片以 urequests 示範 HTTP Client。以下資料只是格式示範,不是實際養殖或場域量測值。請將 URL 換成教師提供且允許測試的 API 端點,並依服務文件調整欄位。

import urequests

url = "https://api.example.org/telemetry"

data = {
    "device_id": "pico-demo-01",
    "temperature": 28.3,
    "humidity": 71.2
}

response = None

try:
    response = urequests.post(url, json=data)
    print("Status:", response.status_code)
    print("Response:", response.text)
except Exception as error:
    print("Request failed:", error)
finally:
    if response is not None:
        response.close()

urequests.post(url, json=data)會把 Python 字典轉成 JSON 格式送出。伺服器回應後,程式讀取 status_code與回應文字;不論成功或失敗,都在 finally區塊關閉 Response,釋放網路資源。

端點提醒:api.example.org是示意網址,不能當成真實課程 API 使用。需替換成已確認可用、且允許 POST 測試的服務。不同 MicroPython 韌體可能需要另外安裝或提供 urequests模組。

五、Pico 使用 HTTP GET 讀取資料

GET 的流程相似,只是呼叫方式改為 urequests.get()。若 API 回傳 JSON,可以使用 response.json()將內容轉為 Python 資料結構,再取出需要的欄位。

import urequests

url = "https://api.example.org/data"
response = None

try:
    response = urequests.get(url)
    print("Status:", response.status_code)

    if response.status_code == 200:
        result = response.json()
        print("Returned data:", result)
    else:
        print("Server returned an error")
except Exception as error:
    print("Request failed:", error)
finally:
    if response is not None:
        response.close()

若回應不是合法 JSON,或伺服器回傳錯誤頁面,response.json()可能無法解析。因此先檢查狀態碼,再讀取資料,是比較可靠的順序。

六、一次完整的資料交換流程

  1. 確認 Pico 已連上 Wi-Fi,並能使用目標網路服務。
  2. 閱讀 API 文件,確認 URL、HTTP 方法、必要欄位與授權方式。
  3. 整理感測資料;送出前確認欄位名稱、資料型態與單位。
  4. 發出 GET 或 POST 要求,等待伺服器回應。
  5. 先檢查狀態碼,再解析回應內容。
  6. 關閉 Response,並記錄成功或錯誤訊息。

以 IoT 遙測為例,資料由感測器進入 Pico,程式整理成 JSON,再透過 HTTP POST 傳到 API Server。重點是理解資料如何跨網路移動,而不是記住某一家 API 的名稱。

七、網路程式的三個陷阱

  • Timeout:伺服器可能很慢或暫時沒有回應,程式不應無限等待。
  • Disconnect:Wi-Fi 可能中斷;需要辨認連線失敗,並依課程設計決定是否重新連線。
  • Memory:回應內容可能很大;微控制器記憶體有限,避免不加判斷地讀取大型資料。

建立「逾時、例外處理、有限次重試、關閉 Response」的習慣,能讓網路程式更容易除錯。重試也要有限次數,並避免在服務故障時快速重複送出大量請求。

八、實作任務

  • GET 一個課堂指定、可公開讀取的測試 API。
  • 列印狀態碼,並從 JSON 回應中取出一個指定欄位。
  • 使用測試資料 POST 到教師指定的測試端點。
  • 在 Shell 顯示狀態碼與伺服器回應。
  • 挑戰:遇到連線失敗時,有限次重試並印出清楚的錯誤原因。
API 金鑰與個人資料:若服務要求 Token 或 API Key,不要將它貼在公開投影片、部落格或 Git 儲存庫中。練習應使用教師核准的測試憑證與測試資料。

本篇重點回顧

  • Pico 可以當 HTTP Client,主動向遠端 API 讀取或傳送資料。
  • GET 常用於取得資料,POST 常用於送出資料;實際格式依 API 文件為準。
  • 狀態碼提供伺服器處理結果,應先檢查再解析回應。
  • 使用 JSON 傳遞感測資料時,要留意欄位、型態與單位。
  • 網路程式要處理逾時、斷線、錯誤與記憶體限制,並關閉 Response。

下一篇將把感測資料整理成一致的 JSON 格式,進一步理解資料欄位、時間戳記與錯誤資料處理。

沒有留言:

張貼留言