DEV Community

Cover image for วิธีทดสอบ API อัปโหลดไฟล์ (multipart/form-data) ใน Apidog
Thanawat Wongchai
Thanawat Wongchai

Posted on • Originally published at apidog.com

วิธีทดสอบ API อัปโหลดไฟล์ (multipart/form-data) ใน Apidog

คุณได้สร้างเอนด์พอยต์ที่รับไฟล์ เช่น ผู้ใช้อัปโหลดรูปโปรไฟล์ไปยัง POST /avatars หรือแอปพุช PDF ที่ลงนามแล้วไปยัง POST /documents ขั้นตอนถัดไปคือพิสูจน์ว่าเอนด์พอยต์ทำงานผ่าน HTTP จริง: เลือกไฟล์ แนบกับฟอร์ม ส่งคำขอ และตรวจสอบการตอบกลับ

ลองใช้ Apidog วันนี้

การอัปโหลดไฟล์ใช้ multipart/form-data ไม่ใช่ JSON จึงไม่สามารถวาง JSON ลงใน Body แล้วกดส่งได้ คุณต้องใช้ตัวสร้างคำขอที่รองรับฟิลด์ไฟล์ และเมื่อต้องรันทดสอบภายหลังผ่าน Runner หรือ CLI ระบบต้องหาไฟล์นั้นเจอด้วย Apidog ช่วยจัดการทั้งสองส่วน บทความนี้จะพาคุณตั้งแต่การส่งไฟล์เดียว การส่งไฟล์พร้อม JSON การยืนยันผลลัพธ์ ไปจนถึงการแก้ปัญหาไฟล์หายเมื่อต้องรันแบบ headless

หากต้องการทบทวนพื้นฐานก่อน อ่านเรื่อง การอัปโหลดไฟล์ใน API และดู FormData ของ MDN สำหรับการใช้งานฝั่งเบราว์เซอร์

multipart/form-data คืออะไร และเหตุใดการอัปโหลดจึงต้องใช้

ใน Apidog คุณสามารถเลือก Body ได้หลายรูปแบบ เช่น form-data, x-www-form-urlencoded, JSON, XML, raw และ binary แม้ JSON จะเป็นค่าเริ่มต้นที่ใช้บ่อย แต่ไฟล์เป็นข้อยกเว้น

เมื่อเลือก form-data คำขอจะใช้เฮดเดอร์:

Content-Type: multipart/form-data
Enter fullscreen mode Exit fullscreen mode

Body จะถูกแบ่งเป็นหลายส่วน แต่ละส่วนมีชื่อและข้อมูลของตัวเอง ตัวอย่างเช่น:

  • ส่วน title เป็นข้อความ
  • ส่วน avatar เป็นไบต์ของไฟล์รูปภาพ
  • ส่วน metadata เป็นสตริง JSON

จึงส่งไฟล์และข้อมูลประกอบในคำขอเดียวกันได้

อย่าสับสนกับ x-www-form-urlencoded แม้ทั้งคู่จะแสดงเป็นคู่คีย์-ค่า แต่รูปแบบนี้เหมาะกับฟอร์มที่มีเฉพาะค่าสเกลาร์สั้น ๆ และไม่มีไฟล์ หากเอนด์พอยต์รับรูปภาพ, PDF หรือไฟล์ใด ๆ ให้ใช้ form-data

ใน Apidog ทุกพารามิเตอร์ของ form-data มีประเภท เช่น string, integer หรือ file จุดสำคัญคือเปลี่ยนฟิลด์ที่ต้องแนบไฟล์ให้เป็น file เพื่อให้ Apidog อ่านไฟล์จากพาธ แทนที่จะส่งพาธนั้นเป็นข้อความ

ส่งไฟล์อัปโหลดเดียวและยืนยันการตอบกลับ

สมมติว่า POST /avatars รับไฟล์รูปภาพในฟิลด์ avatar และคืนค่า URL ของไฟล์ที่จัดเก็บแล้ว

1. ตั้งค่า Body เป็น form-data

สร้างหรือเปิดคำขอ แล้วกำหนด:

POST /avatars
Enter fullscreen mode Exit fullscreen mode

จากนั้นไปที่แท็บ Body และเลือก form-data Apidog จะจัดการ Content-Type: multipart/form-data ให้

2. เพิ่มฟิลด์ไฟล์

เพิ่มพารามิเตอร์ดังนี้:

Key Type Value
avatar file เลือกไฟล์

เปลี่ยนประเภทของ avatar จาก string เป็น file ช่องค่าจะเปลี่ยนเป็นตัวเลือกไฟล์

3. เลือกไฟล์จากเครื่อง

คลิก Upload ในแถว avatar แล้วเลือกไฟล์ เช่น:

jane-profile.png
Enter fullscreen mode Exit fullscreen mode

Apidog จะบันทึกพาธของไฟล์ในเครื่องไว้

4. ส่งคำขอ

กด Send Apidog จะอ่านไฟล์จากพาธ สร้าง multipart body และส่งไปยัง API

ตัวอย่างการตอบกลับที่สำเร็จ:

{
  "id": "usr_8842",
  "avatarUrl": "https://cdn.example.com/avatars/usr_8842.png",
  "sizeBytes": 48210,
  "contentType": "image/png"
}
Enter fullscreen mode Exit fullscreen mode

Apidog ส่งไฟล์ไปกับคำขอ แต่ไม่ได้อัปโหลดหรือเก็บไบต์ของไฟล์ไว้ในคลาวด์ โดยจะบันทึกเฉพาะพาธในเครื่องเท่านั้น ประเด็นนี้สำคัญมากเมื่อรันผ่าน Runner หรือ CLI

5. เพิ่ม assertions

สถานะ 200 เพียงอย่างเดียวไม่เพียงพอสำหรับการทดสอบ เพิ่ม assertions เพื่อตรวจสอบว่า API ตอบข้อมูลที่ถูกต้อง:

status code == 200
$.avatarUrl exists
$.contentType == "image/png"
Enter fullscreen mode Exit fullscreen mode

Assertions เหล่านี้ตรวจสอบ:

  1. API ตอบกลับสำเร็จ
  2. มี URL ของไฟล์ใน response
  3. ประเภทไฟล์ที่ API ประมวลผลตรงกับที่คาดไว้

ดูโอเปอเรเตอร์และการใช้งาน JSONPath เพิ่มเติมได้จากคู่มือ การยืนยัน API

หากต้องการตรวจสอบพฤติกรรมเดียวกันผ่าน curl:

curl -X POST https://api.example.com/avatars \
  -F "avatar=@jane-profile.png"
Enter fullscreen mode Exit fullscreen mode

แฟล็ก -F สร้าง multipart form และ @ บอก curl ให้อ่านเนื้อหาไฟล์ ซึ่งเทียบเท่ากับการเลือกประเภท file ใน Apidog

ส่งไฟล์และ JSON พร้อมกัน

เอนด์พอยต์จริงมักต้องการเมทาดาตาควบคู่กับไฟล์ เช่น POST /documents อาจรับ PDF พร้อมชื่อ หมวดหมู่ และแท็ก

ส่งฟิลด์สเกลาร์

เพิ่มฟิลด์ form-data หลายรายการ:

Key Type ตัวอย่างค่า
file file q3-invoice.pdf
title string Q3 Invoice
category string billing

ทุกฟิลด์จะถูกส่งใน multipart request เดียวกัน

ส่ง metadata ที่มีโครงสร้างเป็น JSON

หากเมทาดาตามีออบเจกต์ซ้อนหรืออาร์เรย์ ให้เพิ่มฟิลด์ metadata แบบ string แล้วใส่ JSON ลงไปโดยตรง:

{
  "title": "Q3 Invoice",
  "category": "billing",
  "tags": ["invoice", "2026", "paid"]
}
Enter fullscreen mode Exit fullscreen mode

คำขอจะมีอย่างน้อยสองส่วน:

  • file ประเภท file สำหรับ q3-invoice.pdf
  • metadata ประเภท string ที่มี JSON

ฝั่งเซิร์ฟเวอร์จึงอ่านไฟล์จากส่วนหนึ่ง และ parse JSON จากอีกส่วนหนึ่ง รูปแบบนี้พบได้ใน API จริง เช่น เอกสารการอัปโหลดไฟล์ของ Stripe

หากกำลังย้ายจาก Postman โปรดดูบทความ การอัปโหลดไฟล์และข้อมูล JSON ใน Postman

แนบหลายไฟล์

หาก API ต้องการไฟล์หลักและภาพย่อ ให้เพิ่มฟิลด์ file สองรายการ:

Key Type
file file
thumbnail file

แต่ละแถวมีปุ่ม Upload ของตัวเอง ไม่ต้องเปิดโหมดพิเศษสำหรับหลายไฟล์

เปลี่ยนคำขอให้เป็นสถานการณ์ทดสอบที่ทำซ้ำได้

การส่งคำขอครั้งเดียวพิสูจน์ว่า API ทำงานในขณะนั้น แต่สถานการณ์ทดสอบช่วยให้ตรวจสอบ regression ได้

ตัวอย่าง flow:

  1. เรียก POST /avatars
  2. บันทึกค่า id จาก response
  3. เรียก GET /users/{id}
  4. ยืนยันว่า URL ของ avatar ยังคงอยู่

เริ่มจากสร้างคำขออัปโหลดตามขั้นตอนก่อนหน้า แล้วบันทึกเป็นขั้นตอนใน scenario จากนั้นส่งค่าระหว่างขั้นตอน เช่น id ที่ได้จากการอัปโหลด

อ่านเพิ่มเติมได้ที่:

การทำงานทั้งหมดนี้จะผ่านบนเครื่องของคุณ เพราะไฟล์อยู่บนเครื่องเดียวกัน ปัญหาจะเกิดขึ้นเมื่อย้าย scenario ไปทำงานที่อื่น

กับดัก: การอัปโหลดที่ทำงานในเครื่อง แต่พังบน Runner หรือ CLI

Apidog เก็บ พาธไฟล์ ไม่ได้เก็บไฟล์จริง

บนเครื่องของคุณ พาธอาจเป็น:

/Users/jane/pics/jane-profile.png
Enter fullscreen mode Exit fullscreen mode

พาธนี้ใช้ได้เฉพาะเมื่อไฟล์อยู่ในตำแหน่งนั้นจริง เมื่อเพื่อนร่วมทีมหรือ Runner เปิดคำขอเดียวกัน พาธดังกล่าวจะไม่ชี้ไปยังไฟล์ที่ใช้ได้

ปัญหานี้พบได้บ่อยในสองกรณี

การทำงานร่วมกันในทีม

เพื่อนร่วมทีมเห็นฟิลด์ avatar และพาธที่คุณเลือกได้ แต่ไม่สามารถส่งคำขอได้ เพราะไฟล์อยู่บนดิสก์ของคุณ

วิธีแก้คือให้แต่ละคนมีไฟล์บนเครื่องของตนเอง แล้วกำหนดพาธของตัวเอง หรือใช้ตัวแปร environment สำหรับพาธไฟล์

การรันผ่าน Runner และ CLI

Scenario อาจผ่านบนเครื่อง local แต่ล้มเหลวใน Runner หรือ CI เพราะโฮสต์นั้นไม่มีไฟล์ตามพาธที่บันทึกไว้

หลักการแก้ไขคือ:

  1. ทำให้ไฟล์มีอยู่บนเครื่องที่ใช้รัน
  2. กำหนดพาธในขั้นตอนให้ชี้ไปยังไฟล์บนเครื่องนั้น

สำหรับ Runner

Runner อ่านไฟล์จากไดเรกทอรีโฮสต์ที่ mount เข้า volume ด้วยแฟล็ก -v

  1. คัดลอกไฟล์ไปยังไดเรกทอรีที่ mount แล้ว
  2. เปิดรายละเอียดขั้นตอนอัปโหลดใน scenario
  3. คลิก Batch Edit
  4. เปลี่ยนค่าฟิลด์ไฟล์เป็นพาธที่ Runner เข้าถึงได้

ตัวอย่าง:

/opt/runner/jane-profile.png
Enter fullscreen mode Exit fullscreen mode

สำหรับ CLI

ให้วางไฟล์ไว้บนเครื่องที่รัน CLI แล้วเปลี่ยนพาธของขั้นตอน เช่น:

/opt/apidog/runner/jane-profile.png
Enter fullscreen mode Exit fullscreen mode

ใช้ตัวแปรแทนการ hard-code พาธ

วิธีที่ดูแลง่ายกว่าคือกำหนดพาธผ่านตัวแปร environment

ตัวอย่าง:

{{avatar_file_path}}
Enter fullscreen mode Exit fullscreen mode

กำหนดค่าแต่ละ environment เป็น:

# Local
/Users/jane/pics/jane-profile.png

# Runner
/opt/runner/jane-profile.png
Enter fullscreen mode Exit fullscreen mode

Scenario เดิมจึงทำงานได้ทั้งบน local, Runner และ CI โดยไม่ต้องแก้ไขแต่ละขั้นตอน

Runner จะเข้าถึงได้เฉพาะไฟล์ใต้ไดเรกทอรีที่ mount ด้วย -v ตอน deploy เท่านั้น หากไฟล์อยู่นอก mount point จะไม่มีพาธใดทำให้ Runner อ่านไฟล์ได้

ดูรายละเอียดการ mount และ Batch Edit จาก เอกสาร Apidog เกี่ยวกับคำขออัปโหลดไฟล์

ทำงานเวิร์กโฟลว์อัตโนมัติด้วย Apidog CLI

หลังบันทึก scenario แล้ว คุณสามารถรันแบบ headless ใน CI ได้

ติดตั้ง CLI และยืนยันตัวตน:

npm install -g apidog-cli
apidog login --with-token <YOUR_ACCESS_TOKEN>
Enter fullscreen mode Exit fullscreen mode

รัน scenario ที่บันทึกไว้โดยระบุ scenario ID และ environment ID:

apidog run --access-token $APIDOG_ACCESS_TOKEN -t <scenario_id> -e <env_id> -r cli
Enter fullscreen mode Exit fullscreen mode

ความหมายของพารามิเตอร์:

  • -t คือ ID ของสถานการณ์ทดสอบ
  • -e คือ ID ของ environment
  • -r คือ reporter เช่น cli, html หรือ junit

CLI จะรัน scenario จากโปรเจกต์คลาวด์และคืนรหัส exit ตามผลผ่าน/ล้มเหลว จึงนำไปควบคุม pipeline ได้

อ่านการตั้งค่าเพิ่มได้จาก คู่มือการติดตั้ง Apidog CLI

สำหรับ scenario ที่มีการอัปโหลดไฟล์ อย่าลืมว่าไฟล์ต้องอยู่บนเครื่องที่รัน CLI และพาธต้องชี้ไปยังตำแหน่งนั้น ใช้ Batch Edit หรือ environment variable เพื่อจัดการพาธก่อนรัน

หากต้องการส่งข้อมูลทดสอบแบบหลายแถว ดู การทดสอบที่ขับเคลื่อนด้วยข้อมูลด้วย Apidog CLI

คำถามที่พบบ่อย

เหตุใดเพื่อนร่วมทีมจึงส่งคำขออัปโหลดไฟล์ของฉันไม่ได้?

Apidog เก็บพาธในเครื่อง ไม่ได้เก็บหรืออัปโหลดไฟล์ไปยังคลาวด์ พาธของคุณชี้ไปยังไฟล์บนดิสก์ของคุณเท่านั้น ให้เพื่อนร่วมทีมคัดลอกไฟล์ลงเครื่องของตนและตั้งค่าพาธใหม่ หรือใช้ตัวแปร environment

หลักการเดียวกันนี้ใช้กับ การทดสอบตามกำหนดเวลา และงาน Runner ด้วย

ฉันจะส่ง JSON พร้อมไฟล์ในคำขอเดียวกันได้อย่างไร?

ใช้ form-data เพิ่มฟิลด์ไฟล์ประเภท file แล้วเพิ่มฟิลด์อีกตัวประเภท string สำหรับ JSON เช่น metadata เซิร์ฟเวอร์จะได้รับไฟล์และ JSON เป็นคนละส่วนของ multipart request เดียวกัน

ฉันควรใช้พาธใดสำหรับไฟล์ใน Runner?

ใช้พาธภายในไดเรกทอรีที่ mount เข้า Runner ผ่านแฟล็ก -v เช่น:

/opt/runner/yourfile.jpg
Enter fullscreen mode Exit fullscreen mode

คัดลอกไฟล์ไว้ในไดเรกทอรีที่ mount แล้วใช้ Batch Edit เปลี่ยนฟิลด์ไฟล์ให้ชี้ไปยังพาธดังกล่าว สำหรับ CLI ตัวอย่างพาธคือ:

/opt/apidog/runner/yourfile.jpg
Enter fullscreen mode Exit fullscreen mode

Apidog จำกัดขนาดหรือประเภทไฟล์หรือไม่?

ข้อจำกัดจริงมาจาก API ที่กำลังทดสอบ Apidog มีหน้าที่สร้างคำขอและอ่านไฟล์จากพาธ ดังนั้นควรตรวจสอบ validation ของเซิร์ฟเวอร์สำหรับขนาดไฟล์และ MIME type พร้อมเขียน assertions สำหรับ response กรณีไฟล์ถูกปฏิเสธ

ควรใช้ form-data หรือ x-www-form-urlencoded สำหรับการอัปโหลด?

ใช้ form-data เพราะแมปกับ multipart/form-data และออกแบบมาสำหรับไฟล์ ส่วน x-www-form-urlencoded ใช้กับฟอร์มข้อมูลสเกลาร์ที่ไม่มีไฟล์

สรุป

การทดสอบ file upload มีสองส่วนหลัก:

  1. สร้าง multipart request ให้ถูกต้อง
  2. ทำให้ไฟล์เข้าถึงได้บนทุกเครื่องที่รันการทดสอบ

ใน Apidog ให้ตั้งค่า Body เป็น form-data เปลี่ยนฟิลด์ไฟล์เป็น file เลือกไฟล์ด้วย Upload เพิ่ม JSON เป็นฟิลด์ string แล้วส่งพร้อม assertions

เมื่อย้าย scenario ไปยัง Runner หรือ CLI ให้เตรียมไฟล์ไว้บนโฮสต์นั้น และเปลี่ยนพาธด้วย Batch Edit หรือ environment variables เพื่อให้การรันอัตโนมัติทำงานเหมือนบนเครื่อง local

ต้องการลองกับเอนด์พอยต์ของคุณเอง? ดาวน์โหลด Apidog แล้วสร้างคำขอ form-data ไปยังเส้นทางอัปโหลดของคุณ เริ่มต้นได้ฟรีโดยไม่ต้องใช้บัตรเครดิต

Top comments (0)