2026年8月16日 星期日

[水井村USR] HTTP+JSON+REST API

HTTP+JSON+REST API

從「水井三寶智慧互動展覽系統」看懂ESP32如何把資料送到Django

HTTP Request × Header × JSON Body × REST Endpoint × Django API × Response

當ESP32已經能連上Internet,下一個問題就是:它到底如何把「烏龜故事被播放」這件事送到Django?答案不是單靠Wi-Fi,而是透過HTTP、JSON與REST API三個重要概念協同工作。這篇文章就用水井三寶Layer 4的資料流,帶學生看懂一筆匿名事件如何從ESP32送到雲端。

一、先從一筆事件開始

{
  "event_uuid":"SHUIJING-001-0000000062",
  "event_type":"STORY_START",
  "story":"002",
  "source":"web",
  "duration_ms":0,
  "completed":null,
  "network_status":"online",
  "metadata":{
    "firmware":"Layer4-V1.7",
    "jq_confirmed":true
  }
}

這段資料本身還沒有「送上網」。它只是ESP32中的一個JSON字串。接下來才輪到HTTP與REST API登場。

二、HTTP是什麼?

HTTP可以理解成Client與Server之間溝通的規則。水井三寶同時用到GET與POST:

Method水井三寶例子用途
GET/play?track=2手機要求ESP32播放烏龜故事
POST/api/exhibition/events/ESP32把匿名事件送到Django
一句話記:GET常用來取得資源或提出查詢;POST常用來把資料送給Server處理。

三、一個HTTP Request有哪三個部分?

Request Line POST /api/exhibition/events/ HTTP/1.1 Headers Content-Type: application/json X-Device-ID: SHUIJING-001 X-Device-Key: ******** Body { "event_type":"STORY_START", "story":"002" }
部分作用
Request Line使用什麼Method、要去哪一個Path
Headers提供內容格式、裝置識別、驗證資訊
Body真正要送給Server的資料

四、JSON是什麼?

JSON是一種文字格式,適合不同系統之間交換結構化資料。

{
  "story":"002",
  "source":"web",
  "completed":true
}
KeyValue意義
story"002"烏龜故事
source"web"由Edge Web啟動
completedtrue故事完整播放
JSON的價值:ESP32、JavaScript、Python、Django等平台都可以很容易解析,因此非常適合IoT與Web API。

五、為什麼要寫 Content-Type?

Content-Type: application/json

這一行是在告訴Django:「這次HTTP Body裡裝的是JSON。」如果Server不知道資料格式,就無法正確解析內容。

六、REST API是什麼?

REST API是一種設計Web服務的方式:把系統功能整理成清楚的URL Endpoint,再搭配HTTP Method進行操作。

https://shuijingtreasures.pythonanywhere.com/api/exhibition/events/
https:// 安全的HTTP通訊 shuijingtreasures.pythonanywhere.com Domain / Server /api/exhibition/events/ REST API Endpoint
Endpoint可以理解成「API的入口地址」。

七、為什麼ESP32不能直接呼叫Django函式?

ESP32和Django位於不同設備、不同執行環境,因此ESP32不能直接執行Server上的Python函式,只能透過網路把Request送到URL,再由Django URL Router找到對應View。

ESP32 ↓ HTTP POST /api/exhibition/events/ ↓ Django URL Router ↓ api_event() ↓ Database

八、Device ID與API Key放在哪裡?

X-Device-ID: SHUIJING-001
X-Device-Key: ********

它們放在HTTP Header,讓Django知道是哪一台設備,以及這台設備是否有權限傳送資料。

正式API Key不應公開放在部落格、簡報或公開GitHub倉庫。教材只示範格式即可。

九、ESP32端的HTTP POST概念

WiFiClientSecure client;
HTTPClient https;

https.begin(
  client,
  "https://shuijingtreasures.pythonanywhere.com/api/exhibition/events/"
);

https.addHeader(
  "Content-Type",
  "application/json"
);

https.addHeader(
  "X-Device-ID",
  DEVICE_ID
);

https.addHeader(
  "X-Device-Key",
  DEVICE_KEY
);

int code = https.POST(jsonBody);
建立HTTPS Client ↓ 指定REST API URL ↓ 加入Headers ↓ 放入JSON Body ↓ POST ↓ 等待HTTP Response

十、Server如何告訴ESP32成功或失敗?

Status Code常見意義
200Request成功
201資料建立成功
400Request內容有問題
401驗證失敗
404API路徑不存在
500Server內部錯誤

水井三寶Cloud Test成功時,可看到:

Cloud HTTP = 201
Response = {"ok":true,...}
CLOUD POST OK

這代表DNS、HTTPS、API URL、裝置驗證與Django資料接收都已經成功。

十一、為什麼 Cloud HTTP = -1 不是Django回的狀態碼?

實作過程中曾出現:

Cloud HTTP = -1

後來追查發現問題發生在DNS解析階段,也就是HTTP Request根本還沒到Django。

DNS失敗 ↓ 找不到Server IP ↓ 無法建立TCP/TLS連線 ↓ HTTP Request沒有到Django ↓ 自然也不會有401 / 404 / 500
除錯原則:Cloud失敗時,不要第一時間就修改Django;先確認Wi-Fi、DNS、TLS與HTTP是否真的走到Server。

十二、為什麼採用 Local First, Cloud Later?

如果每次故事一開始就同步做HTTPS POST,可能讓JQ6500播放、Edge Web與網路傳輸互相干擾。因此系統採取:

故事播放 ↓ 建立JSON Event ↓ 先存LittleFS Queue ↓ 播放完成 ↓ 系統空閒 ↓ HTTP POST ↓ Django
設計原則:現場互動優先;雲端同步延後。

十三、HTTP、JSON、REST API怎麼分工?

技術主要工作水井三寶角色
HTTP規定Client與Server怎麼請求與回應ESP32 POST事件到Django
JSON描述資料格式故事、來源、完成狀態等事件內容
REST API定義Server提供的URL服務入口/api/exhibition/events/
一句話記:HTTP是「怎麼送」,JSON是「送什麼」,REST API是「送到哪個功能入口」。

十四、一筆「烏龜故事」事件的完整旅程

使用者按「002 烏龜故事」 ↓ ESP32 Edge Web ↓ JQ6500開始播放 ↓ 建立 JSON ↓ LittleFS Queue ↓ ESP32 STA ↓ DNS找到PythonAnywhere ↓ HTTPS ↓ POST /api/exhibition/events/ ↓ Headers:Device ID / API Key ↓ JSON Body ↓ Django View ↓ Database ↓ HTTP 201 Response ↓ Dashboard

十五、和水井三寶五層架構的關係

層級HTTP / JSON / REST API的角色
Layer 2 智慧互動層產生故事與感測事件
Layer 3 Edge Web層本地HTTP GET控制ESP32
Layer 4 Digital Twin / Data層HTTP POST+JSON+REST API送到Django
Layer 5 文化知識層未來可透過API提供文化內容與AI/RAG服務

十六、真正理解API,要能回答七個問題

Client是誰? ESP32 Server是誰? Django Protocol? HTTPS Endpoint? /api/exhibition/events/ Method? POST 資料格式? JSON 成功如何判斷? HTTP Status + Response Body

十七、課堂思考題

問題一:如果JSON格式正確,但API URL打錯,可能得到哪一類HTTP狀態?
問題二:為什麼Device ID與API Key適合放Header,而故事內容放Body?
問題三:GET與POST都能帶資料,為什麼事件上傳通常選POST?
問題四:如果Django已回201,但Dashboard沒有資料,問題可能已經移到哪一層?

十八、結語:REST API是Edge與Cloud之間的橋

水井三寶的ESP32負責感測、故事播放與現場控制,Django負責跨場次資料、Dashboard與後續分析。兩邊位於不同設備、使用不同語言,卻能透過HTTP+JSON+REST API協同工作。

因此,REST API真正重要的地方,不只是讓ESP32「可以傳資料」,而是建立清楚的系統邊界:Edge負責即時互動,Cloud負責資料服務。HTTP定義溝通方式,JSON定義資料語言,而REST API定義雙方合作的入口。

HTTP GET POST JSON REST API Endpoint Header HTTPS ESP32 Django

沒有留言:

張貼留言