วิธีสร้าง API
การสร้าง API เกี่ยวข้องกับการเขียนโค้ดฝั่งเซิร์ฟเวอร์มากกว่านั้น — เป็นกระบวนการที่ครอบคลุมซึ่งประกอบด้วยหลายขั้นตอน แต่ละขั้นตอนมีขั้นตอนที่สำคัญ และการกำหนดมาตรฐานเวิร์กโฟลว์จะช่วยเพิ่มทั้งประสบการณ์การพัฒนาและความสอดคล้องกันโดยรวม การเตรียมการ การออกแบบ การพัฒนา การส่งมอบ การวิเคราะห์
การเตรียมการ
ขั้นตอนการเตรียมการคือจุดเริ่มต้นสำหรับการสร้าง API โดยมุ่งเน้นที่การทำความเข้าใจความต้องการทางธุรกิจ การกำหนดแนวคิดและคำศัพท์หลักให้ชัดเจน และการตัดสินใจเลือกสถาปัตยกรรมที่จะนำมาใช้ (เช่น REST, GraphQL หรือ gRPC) ในขณะเดียวกัน สิ่งสำคัญคือการกำหนดข้อตกลงการออกแบบสำหรับการตั้งชื่อเอนด์พอยต์ รหัสสถานะ การกำหนดเวอร์ชัน และอื่นๆ เพื่อวางรากฐานที่สอดคล้องกันสำหรับขั้นตอนการออกแบบและการพัฒนาที่จะมาถึง
1 การวิเคราะห์ความต้องการทางธุรกิจ ▼
ขั้นตอนแรกในการสร้าง API คือการทำความเข้าใจปัญหาที่ต้องการแก้ไข ซึ่งเกี่ยวข้องกับการสื่อสารอย่างใกล้ชิดกับผู้จัดการผลิตภัณฑ์และผู้มีส่วนได้ส่วนเสียทางธุรกิจ — โดยเฉพาะอย่างยิ่งผ่านการประชุมทบทวน — เพื่อชี้แจงความต้องการหลัก: API นี้มีวัตถุประสงค์อะไร? ควรสนับสนุนเป้าหมายทางธุรกิจใดบ้าง? ผู้ใช้ที่ตั้งใจไว้คือใคร? พวกเขาจะใช้ในสถานการณ์ใดบ้าง? คุณต้องค้นหาทั้งหมดนี้ก่อนที่จะเข้าสู่ขั้นตอนการออกแบบ
เมื่อรวบรวมความต้องการได้แล้ว อย่ารีบนำไปใช้ทั้งหมดในคราวเดียว เริ่มต้นด้วยการจัดลำดับความสำคัญ: ระบุคุณสมบัติที่สำคัญที่สุดและจำเป็นที่สุด — ผลิตภัณฑ์ที่สามารถใช้งานได้ขั้นต่ำ (MVP) — และสร้างสิ่งเหล่านั้นก่อน คุณสมบัติเพิ่มเติมสามารถเพิ่มได้ทีละน้อยในภายหลัง ซึ่งช่วยให้ทีมมุ่งเน้นไปที่การส่งมอบคุณค่าสูงสุดและกำหนดเส้นทางที่ชัดเจนสำหรับการทำซ้ำในอนาคต
2 กำหนดความหมายของโดเมน ▼
การทำความเข้าใจ "แนวคิด" หลักภายในธุรกิจเป็นสิ่งสำคัญสำหรับการออกแบบ API ที่ดี ตัวอย่างเช่น ในระบบอีคอมเมิร์ซ เราจำเป็นต้องชี้แจงว่าคำว่า "ผู้ใช้" "ผลิตภัณฑ์" และ "คำสั่งซื้อ" หมายถึงอะไรจริง ๆ นี่คือเวลาที่จะสื่อสารบ่อยครั้งกับผู้มีส่วนได้ส่วนเสียทางธุรกิจและผู้จัดการผลิตภัณฑ์เพื่อให้แน่ใจว่าทีมเทคนิคเข้าใจความหมายและตรรกะพื้นฐานของแนวคิดเหล่านี้อย่างถ่องแท้
ถัดไป เรากำหนดมาตรฐานคำศัพท์โดยการสร้าง "อภิธานศัพท์ทางธุรกิจ" เพื่อให้แน่ใจว่าทุกคนอ้างถึงสิ่งเดียวกัน ตัวอย่างเช่น "สถานะคำสั่งซื้อ" ที่เป็นไปได้คืออะไร? แต่ละสถานะหมายถึงอะไร? การทำความเข้าใจสิ่งนี้ล่วงหน้าช่วยหลีกเลี่ยงความเข้าใจผิดและรับประกันความร่วมมือที่ราบรื่นยิ่งขึ้นในอนาคต
3 ประเมินสถาปัตยกรรมทางเทคนิค ▼
การเลือกรูปแบบสถาปัตยกรรม API และโปรโตคอลการสื่อสารที่เหมาะสมเป็นสิ่งสำคัญในการจัดแนวทางแก้ไขปัญหาทางเทคนิคให้สอดคล้องกับความต้องการทางธุรกิจ — ซึ่งเป็นขั้นตอนสำคัญที่สามารถสร้างหรือทำลายความสำเร็จของโครงการทั้งหมดได้
เราต้องตัดสินใจว่าจะใช้รูปแบบสถาปัตยกรรมใดสำหรับ API เราควรใช้ REST, GraphQL หรือ gRPC? แต่ละตัวเลือกมีจุดแข็งและจุดอ่อนของตัวเอง การตัดสินใจควรขึ้นอยู่กับความต้องการที่แท้จริงของโครงการ เช่น:
- ทีมฟรอนต์เอนด์ต้องการใช้งาน API อย่างไร?
- ระบบมีข้อกำหนดด้านประสิทธิภาพเฉพาะหรือไม่?
- ทีมคุ้นเคยกับเทคโนโลยีที่เลือกหรือไม่?
- คาดว่าจะมีการขยายขนาดในอนาคตหรือไม่?
การตัดสินใจด้านสถาปัตยกรรมไม่ควรขึ้นอยู่กับทฤษฎีเพียงอย่างเดียว สิ่งสำคัญคือต้องพิจารณาว่ามีชุมชนที่กระตือรือร้นอยู่เบื้องหลังเทคโนโลยีหรือไม่ และมีเครื่องมือที่พร้อมใช้งานหรือไม่ เพื่อที่คุณจะได้ไม่ต้องสร้างสิ่งใหม่ตั้งแต่ต้น เมื่อตัดสินใจได้แล้ว ขอแนะนำให้เขียน "บันทึกการตัดสินใจทางสถาปัตยกรรม" (ADR) เพื่ออธิบายว่าทำไมจึงเลือกแนวทางนี้ ซึ่งช่วยให้สมาชิกในทีมปัจจุบันเข้าใจเหตุผลและทำให้ผู้ดูแลในอนาคตเข้าใจได้อย่างรวดเร็ว
รูปแบบสถาปัตยกรรม API / โปรโตคอลการสื่อสารทั่วไป ได้แก่:
4 กำหนดมาตรฐานและแนวทางปฏิบัติ ▼
วัตถุประสงค์ของการกำหนดมาตรฐานการออกแบบ API คือเพื่อให้แน่ใจว่าทุกคนปฏิบัติตามชุดกฎที่สอดคล้องกันเมื่อสร้างอินเทอร์เฟซ เพื่อหลีกเลี่ยงการนำไปใช้ที่กระจัดกระจายหรือไม่สอดคล้องกัน
ด้วยแนวทางที่เป็นหนึ่งเดียวกัน การพัฒนาจะมีประสิทธิภาพมากขึ้นและง่ายต่อการบำรุงรักษา ตัวอย่างเช่น:
- การตั้งชื่อควรเป็นมาตรฐานอย่างไร? ชื่อทรัพยากรควรเป็นพหูพจน์หรือเอกพจน์? ชื่อฟิลด์ควรใช้ camelCase (เช่น
camelCase
) หรือ snake_case (เช่นsnake_case
)? - ควรออกแบบ URL อย่างไร? อนุญาตให้มีระดับการซ้อนได้กี่ระดับ? ควรจัดโครงสร้างพารามิเตอร์การสืบค้นอย่างไร?
- ควรใช้วิธีการ HTTP อย่างไร? เราควรปฏิบัติตามข้อตกลง RESTful อย่างเคร่งครัด หรือส่งคำขอทั้งหมดผ่าน
POST
? - ควรจัดการข้อผิดพลาดอย่างไร? ควรมีรูปแบบการตอบกลับข้อผิดพลาดที่เป็นมาตรฐานพร้อมรหัสข้อผิดพลาดที่สอดคล้องกันหรือไม่?
- ......
เมื่อมีมาตรฐานเหล่านี้แล้ว นักพัฒนาสามารถเขียน API ตามแนวทางที่เป็นหนึ่งเดียวกัน — ลดข้อผิดพลาดและปรับปรุงการทำงานร่วมกันระหว่างทีมฟรอนต์เอนด์และแบ็กเอนด์ มาตรฐานเหล่านี้ไม่ได้ตายตัว; สามารถพัฒนาไปตามกาลเวลาเมื่อทีมได้รับประสบการณ์และปรับปรุงแนวทางปฏิบัติที่ดีที่สุดให้เป็น "แนวทางการออกแบบ API" ที่ใช้ร่วมกัน
การใช้ Apidog เพื่อจัดการมาตรฐานการออกแบบ API แบบรวมศูนย์ ไม่เพียงแต่ช่วยปรับปรุงการทำงานร่วมกันของทีม แต่ยังช่วยให้มั่นใจว่ามาตรฐานเหล่านี้ถูกบังคับใช้ผ่านเครื่องมือ ทำให้เกิดการพัฒนาและการปฏิบัติตามอย่างต่อเนื่อง

การออกแบบ
ขั้นตอนการออกแบบเกี่ยวข้องกับการแปลความต้องการทางธุรกิจให้เป็นโครงสร้าง API ที่เป็นรูปธรรม — การกำหนดว่าจำเป็นต้องมีทรัพยากรใดบ้าง และการดำเนินการใดที่ทรัพยากรแต่ละรายการควรเปิดเผย ในขั้นตอนนี้ เรายังสร้างต้นแบบอินเทอร์เฟซเพื่อให้ทีมสามารถตรวจสอบและสัมผัสประสบการณ์การออกแบบได้ตั้งแต่เนิ่นๆ ด้วยการรวบรวมความคิดเห็นอย่างต่อเนื่องและการทำซ้ำอย่างรวดเร็ว เรามั่นใจว่าการออกแบบนั้นใช้งานง่าย เข้าใจง่าย และวางรากฐานที่ชัดเจนสำหรับการพัฒนา
1 การออกแบบโมเดลทรัพยากร ▼
การออกแบบโมเดลทรัพยากรเกี่ยวข้องกับการแปลแนวคิดทางธุรกิจให้เป็นโครงสร้างข้อมูลที่จะเปิดเผยผ่าน API โดยหลักแล้ว มันคือการเปลี่ยน "อ็อบเจกต์ + ความสัมพันธ์" ในโดเมนธุรกิจให้เป็นไดอะแกรมที่ชัดเจน — คล้ายกับไดอะแกรม Entity-Relationship (ER) ในการออกแบบฐานข้อมูล — แต่เน้นที่โครงสร้างที่ตั้งใจจะเปิดเผยผ่าน API
ตัวอย่างเช่น ในระบบอีคอมเมิร์ซ คุณมักจะมีเอนทิตีพื้นฐาน เช่น "ผู้ใช้" "ผลิตภัณฑ์" และ "คำสั่งซื้อ" ซึ่งสิ่งเหล่านี้เรียกว่าทรัพยากร แต่ละทรัพยากรควรมีฟิลด์ที่กำหนดไว้อย่างชัดเจนด้วย: ตัวอย่างเช่น ผู้ใช้อาจมีชื่อผู้ใช้และอีเมล ในขณะที่คำสั่งซื้ออาจมีสถานะและราคารวม ฟิลด์น้อยเกินไปอาจไม่ตรงตามข้อกำหนด ในขณะที่มากเกินไปอาจทำให้อินเทอร์เฟซซับซ้อน — การหาสมดุลที่เหมาะสมเป็นสิ่งสำคัญ
ความสัมพันธ์ระหว่างทรัพยากรก็ต้องกำหนดให้ชัดเจนด้วย ตัวอย่างเช่น คุณจะแสดงว่าผู้ใช้หนึ่งคนมีหลายคำสั่งซื้อได้อย่างไร? คุณสามารถแสดงความสัมพันธ์นี้ในโครงสร้าง URL เป็น /users/{id}/orders
หรือโดยการเพิ่มฟิลด์ user_id
ภายในข้อมูลคำสั่งซื้อ การเลือกการออกแบบส่งผลต่อวิธีการเรียกใช้ API และความสามารถในการบำรุงรักษาในอนาคต ดังนั้นการตัดสินใจควรขึ้นอยู่กับความต้องการทางธุรกิจที่แท้จริง
คุณสามารถใช้เครื่องมือภาพ เช่น Draw.io, Whimsical, หรือ Figma เพื่อสร้างไดอะแกรมโมเดลทรัพยากร เครื่องมือเหล่านี้มีอินเทอร์เฟซแบบลากและวาง และเหมาะสำหรับการแสดงโครงสร้างและความสัมพันธ์อย่างรวดเร็วระหว่างการอภิปรายของทีม อีกทางหนึ่ง นักพัฒนาที่คุ้นเคยกับภาษาแบ็กเอนด์สามารถกำหนดโมเดลด้วยตนเองโดยใช้คลาสหรือการกำหนดประเภทโดยตรงในโค้ด
หรือคุณสามารถใช้โมดูล Data Schema ใน Apidog ซึ่งช่วยให้คุณสามารถกำหนดทรัพยากรเป็นอ็อบเจกต์ข้อมูลที่มีโครงสร้างซึ่งสามารถนำกลับมาใช้ใหม่ได้ในหลาย API เมื่อสร้างแล้ว โมเดลเหล่านี้ยังสามารถสร้างคำอธิบายฟิลด์และค่าตัวอย่างโดยอัตโนมัติโดยใช้ AI

2 การวางแผนเอนด์พอยต์ API ▼
เมื่อมีโมเดลทรัพยากรแล้ว ขั้นตอนต่อไปคือการออกแบบเอนด์พอยต์ API ที่เกี่ยวข้องเพื่อให้สามารถเข้าถึงและจัดการทรัพยากรเหล่านี้ได้
ยกตัวอย่างสถาปัตยกรรม REST เอนด์พอยต์พื้นฐานมักจะแมปกับการดำเนินการ CRUD (สร้าง, อ่าน, อัปเดต, ลบ) บนทรัพยากร ตัวอย่างเช่น:
GET /products
– รับรายการผลิตภัณฑ์POST /products
– สร้างผลิตภัณฑ์ใหม่GET /products/{id}
– รับรายละเอียดผลิตภัณฑ์PUT /products/{id}
– อัปเดตผลิตภัณฑ์DELETE /products/{id}
– ลบผลิตภัณฑ์
ขอแนะนำให้ปฏิบัติตามหลักการออกแบบ RESTful และใช้ประโยชน์จากเมธอด HTTP และโครงสร้าง URL ที่ชัดเจน อย่างไรก็ตาม บางทีมเลือกที่จะใช้ POST
สำหรับคำขอทั้งหมดเพื่อลดความซับซ้อนของตรรกะแบ็กเอนด์ แม้ว่าวิธีนี้อาจลดความซับซ้อนในการนำไปใช้ แต่ก็แลกมาด้วยความชัดเจนและความสามารถในการอ่าน ใช้แนวทางนี้ด้วยความระมัดระวังและพิจารณาข้อดีข้อเสียอย่างรอบคอบ
นอกจากการดำเนินการมาตรฐานแล้ว สถานการณ์ทางธุรกิจในโลกแห่งความเป็นจริงมักเกี่ยวข้องกับการดำเนินการพิเศษ เช่น การเข้าสู่ระบบ การรีเซ็ตรหัสผ่าน หรือการเริ่มต้นการคืนเงิน ในกรณีเช่นนี้ คุณสามารถเลือกระหว่าง:
- การดำเนินการกับทรัพยากรย่อย:
POST /users/{id}/reset-password
- การดำเนินการแบบสแตนด์อโลน:
POST /password-resets
การเลือกขึ้นอยู่กับว่าการดำเนินการนั้นเกี่ยวข้องอย่างใกล้ชิดกับทรัพยากรเฉพาะหรือไม่ และเป็นวัตถุประสงค์ทั่วไปเพียงใด
นอกจากนี้ กรณีการใช้งานจำนวนมากยังต้องการ การดำเนินการแบบกลุ่ม เพื่อประสิทธิภาพ — เช่น การสร้างหรือลบแบบกลุ่ม คุณสามารถออกแบบเอนด์พอยต์เช่น POST /products/batch-create
หรือ DELETE /products?ids=1,2,3
พร้อมทั้งให้ความสนใจกับตรรกะการจัดการข้อผิดพลาดที่เหมาะสมด้วย
3 การเขียนเอกสาร API ▼
หลังจากออกแบบ API แล้ว สิ่งสำคัญคือการจัดทำเอกสารอย่างชัดเจนว่าแต่ละอินเทอร์เฟซทำงานอย่างไร — ทำให้ง่ายขึ้นสำหรับนักพัฒนาฟรอนต์เอนด์ในการรวมเข้าด้วยกันและสำหรับการบำรุงรักษาในอนาคต
เราขอแนะนำให้ใช้รูปแบบมาตรฐานเช่น OpenAPI (Swagger)
ซึ่งอธิบาย URL, วิธีการร้องขอ, พารามิเตอร์, โครงสร้างการตอบกลับ และรหัสสถานะของ API แต่ละรายการอย่างครบถ้วน สิ่งนี้ไม่เพียงช่วยปรับปรุงความสามารถในการอ่าน แต่ยังช่วยให้สามารถสร้างเอกสารแบบโต้ตอบและแม้แต่โค้ดที่สร้างขึ้นโดยอัตโนมัติ
API แต่ละรายการควรรวมตัวอย่างคำขอและการตอบกลับ ครอบคลุมสถานการณ์ที่สำเร็จและล้มเหลว ซึ่งช่วยให้นักพัฒนาฟรอนต์เอนด์รวมเข้าด้วยกันได้เร็วขึ้นและทำให้การดีบักแบ็กเอนด์ราบรื่นขึ้น
นอกเหนือจากรายละเอียดทางเทคนิค การเพิ่มคำอธิบายทางธุรกิจตามบริบท — เช่น API ถูกใช้ที่ใดใน UI หรือทำงานร่วมกับ API อื่นใด — สามารถช่วยให้สมาชิกในทีมใหม่เข้าใจได้อย่างรวดเร็ว
หากคุณใช้ Apidog เอกสารจะถูกสร้างขึ้นโดยอัตโนมัติเมื่อการออกแบบ API เสร็จสมบูรณ์ ส่งผลให้มีรูปแบบที่สะอาดและมีโครงสร้างที่ดีโดยไม่จำเป็นต้องทำงานซ้ำด้วยตนเอง

4 การตั้งค่าบริการ Mock ▼
เมื่อเอกสาร API พร้อมแล้ว คุณสามารถตั้งค่าบริการ mock เพื่อจำลองพฤติกรรมของ API ของคุณ — โดยไม่ต้องเขียนตรรกะแบ็กเอนด์จริงใดๆ ตราบใดที่คุณกำหนดข้อมูลการตอบกลับที่คาดหวังในเอกสาร API ก็สามารถ "ทำงาน" ได้แล้ว
ใน Apidog คุณสามารถเปิดใช้งาน บริการ Mock ได้ด้วยคลิกเดียว ซึ่งช่วยให้สร้างการตอบกลับที่สมจริงโดยอัตโนมัติตามข้อกำหนด API ของคุณ
ด้วยบริการ mock ที่มีอยู่ ทีมฟรอนต์เอนด์และแบ็กเอนด์สามารถทำงานพร้อมกันได้ โดยระบุปัญหาต่างๆ เช่น ฟิลด์ที่ไม่ชัดเจน โครงสร้างที่ไม่สมเหตุสมผล หรือการออกแบบ API ที่ไม่สะดวกตั้งแต่เนิ่นๆ — ซึ่งช่วยให้สามารถปรับปรุงได้ตั้งแต่ต้น
เราแนะนำให้มีการทดสอบและปรับปรุงหลายรอบในช่วงระยะ mock — ถามคำถามเช่น: ชื่อฟิลด์ชัดเจนพอหรือไม่? โครงสร้างใช้งานง่ายหรือไม่? ข้อความแสดงข้อผิดพลาดสามารถดำเนินการได้หรือไม่? การวางรากฐานที่แข็งแกร่งในระหว่างการ mock จะนำไปสู่กระบวนการพัฒนาที่ราบรื่นยิ่งขึ้นในภายหลัง
การพัฒนา ขั้นตอนการพัฒนาเกี่ยวข้องกับการนำฟังก์ชันการทำงานไปใช้ตามเอกสารการออกแบบ นักพัฒนาเขียนและดีบักโค้ด ทำการทดสอบหน่วย และตรวจสอบให้แน่ใจว่าคุณสมบัติทั้งหมดทำงานตามที่คาดไว้ ขั้นตอนนี้ยังเน้นที่คุณภาพโค้ดและการเพิ่มประสิทธิภาพการทำงาน เพื่อเตรียมระบบสำหรับการทดสอบและการปรับใช้ในภายหลัง
1 การนำเอนด์พอยต์ API ไปใช้ ▼
นักพัฒนาแบ็กเอนด์นำ API ไปใช้ตามข้อกำหนดการออกแบบอินเทอร์เฟซ ซึ่งรวมถึงการจัดการคำขอที่เข้ามา การโต้ตอบกับฐานข้อมูล การตรวจสอบความถูกต้องของข้อมูลที่ป้อน และการบังคับใช้กฎทางธุรกิจ
โค้ดควรสะอาด อ่านง่าย และบำรุงรักษาง่าย — ทั้งสำหรับตัวคุณเองและสำหรับผู้อื่นที่อาจทำงานกับมันในภายหลัง รูปแบบอินพุตและเอาต์พุตของ API แต่ละรายการต้องเป็นไปตามโครงสร้างที่สอดคล้องกันและหลีกเลี่ยงความไม่สอดคล้องกันหรือความสับสน
เมื่อเกิดข้อผิดพลาด — เช่น ข้อมูลไม่ถูกต้อง ปัญหาฐานข้อมูล หรือบริการบุคคลที่สามไม่ตอบสนอง — ควรจับภาพและจัดการอย่างเหมาะสม ควรส่งคืนข้อความแสดงข้อผิดพลาดที่ชัดเจนเพื่อป้องกันไม่ให้ระบบขัดข้องโดยไม่คาดคิด
2 การทดสอบการรวม API ▼
หลังจากที่การนำ API ไปใช้เสร็จสมบูรณ์ ทีมฟรอนต์เอนด์และแบ็กเอนด์จำเป็นต้องทำงานร่วมกันเพื่อทดสอบอินเทอร์เฟซ พวกเขาตรวจสอบว่าพารามิเตอร์คำขอที่ส่งโดยฟรอนต์เอนด์และโครงสร้าง/ข้อมูลการตอบกลับที่ส่งคืนโดย API ตรงตามที่คาดหวัง
ในระหว่างการทดสอบการรวม อาจพบความแตกต่างระหว่างการนำไปใช้จริงกับเอกสารการออกแบบ — หรือพฤติกรรม API ที่ไม่คาดคิด สมาชิกในทีมจำเป็นต้องทำงานร่วมกันเพื่อดีบักและปรับเปลี่ยนโค้ด API หรือตรรกะการเรียกใช้ฟรอนต์เอนด์ เพื่อให้มั่นใจว่าการใช้งาน API มีความเสถียรและถูกต้อง
ในขณะเดียวกัน กรณีขอบเขต เช่น การตรวจสอบสิทธิ์ การหมดเวลาของคำขอ และการตอบกลับข้อผิดพลาด ก็ควรได้รับการทดสอบเพื่อให้แน่ใจว่า API มีความปลอดภัยและแข็งแกร่ง การร้องขอข้ามต้นทาง (CORS) และความเข้ากันได้ของรูปแบบข้อมูล (เช่น JSON) ก็ต้องได้รับการตรวจสอบเพื่อหลีกเลี่ยงปัญหาในขณะรันไทม์
3 การทดสอบอัตโนมัติ ▼
เมื่อการพัฒนา API เสร็จสมบูรณ์ การทดสอบไม่ควรพึ่งพาการตรวจสอบด้วยตนเองเพียงอย่างเดียว ควรเขียนสคริปต์ทดสอบอัตโนมัติเพื่อให้การทดสอบสามารถทำงานได้โดยอัตโนมัติเมื่อมีการเปลี่ยนแปลงใดๆ — ช่วยตรวจจับปัญหาตั้งแต่เนิ่นๆ
การทดสอบอัตโนมัติครอบคลุมไม่เพียงแต่เวิร์กโฟลว์ปกติเท่านั้น แต่ยังรวมถึงกรณีขอบเขตต่างๆ เช่น พารามิเตอร์ที่จำเป็นขาดหายไป ประเภทข้อมูลไม่ถูกต้อง สิทธิ์ไม่เพียงพอ และการละเมิดกฎทางธุรกิจ ซึ่งช่วยให้มั่นใจว่า API ทำงานได้อย่างน่าเชื่อถือภายใต้เงื่อนไขทั้งหมด
การทดสอบเหล่านี้มักจะแบ่งออกเป็นสามประเภท: การทดสอบหน่วย (เพื่อตรวจสอบฟังก์ชันแต่ละรายการ) การทดสอบการรวม (เพื่อตรวจสอบการโต้ตอบข้ามโมดูล) และการทดสอบ API (เพื่อจำลองคำขอและตรวจสอบว่าการตอบกลับตรงกับผลลัพธ์ที่คาดหวังหรือไม่)
หากคุณกำลังเขียนการทดสอบโดยใช้โค้ด (เช่น ด้วยเครื่องมืออย่าง Jest หรือ SuperTest) จะมีความยืดหยุ่น แต่ต้องใช้ความพยายามมากขึ้นในการจัดการโฟลว์ข้อมูลและการยืนยัน
เพื่อประสบการณ์ที่ใช้งานง่ายยิ่งขึ้น คุณสามารถใช้คุณสมบัติ การทดสอบอัตโนมัติ ของ Apidog ซึ่งรองรับการกำหนดค่าแบบลากและวางด้วยภาพ ทำให้คุณสามารถสร้างเวิร์กโฟลว์การทดสอบที่ครอบคลุมได้อย่างรวดเร็วโดยไม่ต้องเขียนโค้ด คุณสามารถตั้งค่าการเรียก API ตามลำดับ ส่งข้อมูลการตอบกลับระหว่าง API และกำหนดค่าการยืนยันเพื่อตรวจสอบค่าที่ส่งคืน

4 การรวมและการปรับใช้ต่อเนื่อง ▼
การรวมต่อเนื่อง (CI) หมายถึงทุกครั้งที่มีการคอมมิตโค้ด ระบบจะสร้างโปรเจกต์และรันการทดสอบโดยอัตโนมัติเพื่อให้แน่ใจว่าโค้ดทำงานตามที่คาดไว้ การปรับใช้ต่อเนื่อง (CD) ทำได้มากกว่านั้นโดยการปรับใช้เวอร์ชันใหม่ไปยังสภาพแวดล้อมการทดสอบหรือการผลิตโดยอัตโนมัติหลังจากผ่านการทดสอบ — ทำให้การส่งมอบเร็วขึ้นและน่าเชื่อถือยิ่งขึ้น
เมื่อตั้งค่า CI/CD คุณต้องกำหนดสคริปต์สำหรับแต่ละขั้นตอน: วิธีการสร้าง ทดสอบ และปรับใช้ หากขั้นตอนใดล้มเหลว ระบบจะแจ้งเตือนทีมทันที ระบบอัตโนมัติช่วยลดงานด้วยตนเองและหลีกเลี่ยงความไม่สอดคล้องกันของสภาพแวดล้อม เช่น "มันทำงานบนเครื่องของฉัน"
หากคุณต้องการรวมการทดสอบ API เข้ากับไปป์ไลน์ CI/CD ของคุณ คุณสามารถใช้เครื่องมือ Apidog CLI ซึ่งช่วยให้คุณสามารถรันการทดสอบอัตโนมัติผ่านบรรทัดคำสั่งและรวมเข้ากับแพลตฟอร์มยอดนิยมเช่น Jenkins และ GitLab นอกจากนี้ยังรองรับ งานที่กำหนดเวลาไว้, ร่วมกับ Runner ที่โฮสต์ด้วยตนเอง, ทำให้สามารถตรวจสอบสถานะ API ของคุณโดยอัตโนมัติและรับประกันว่าทุกอย่างพร้อมก่อนการปรับใช้
5 การเพิ่มประสิทธิภาพการทำงาน ▼
หลังจากที่ API เปิดใช้งานแล้ว ทีมควรตรวจสอบเวลาตอบสนองและประสิทธิภาพของเซิร์ฟเวอร์อย่างต่อเนื่องเพื่อระบุปัญหาคอขวดที่อาจเกิดขึ้น ปัญหาทั่วไป ได้แก่ การสืบค้นฐานข้อมูลที่ช้า การส่งคืนข้อมูลที่มากเกินไป และการคำนวณซ้ำซ้อนบ่อยครั้ง
เพื่อแก้ไขปัญหาเหล่านี้ คุณสามารถเพิ่มประสิทธิภาพดัชนีฐานข้อมูล แคชข้อมูลที่ใช้งานบ่อย ลดฟิลด์ที่ไม่จำเป็นในการตอบกลับ API ปรับปรุงตรรกะโค้ด หรือแม้แต่เปลี่ยนการดำเนินการบางอย่างเป็นการดำเนินการแบบอะซิงโครนัส — ทั้งหมดนี้มีเป้าหมายเพื่อปรับปรุงประสิทธิภาพ
นอกจากความเร็วแล้ว ความเสถียรภายใต้การทำงานพร้อมกันสูงก็เป็นสิ่งสำคัญ เมื่อปริมาณการใช้งานเพิ่มขึ้น ระบบสามารถล่มได้ง่าย เทคนิคต่างๆ เช่น การปรับสมดุลโหลด การจำกัดอัตรา และกลไกการสำรองข้อมูลช่วยป้องกันความล้มเหลวของ API และรับประกันว่าระบบจะยังคงเสถียรและตอบสนองต่อผู้ใช้
6 การเสริมความปลอดภัย ▼
เมื่อ API เปิดใช้งานแล้ว อาจถูกนำไปใช้ในทางที่ผิดหรือถูกโจมตี ดังนั้นความปลอดภัยจึงเป็นสิ่งสำคัญ ประการแรก ต้องมีการยืนยันตัวตนของผู้ใช้ วิธีการทั่วไป ได้แก่ OAuth2 และ JWT เพื่อให้แน่ใจว่าเฉพาะผู้ใช้ที่ได้รับอนุญาตเท่านั้นที่สามารถเรียกใช้ API ได้ ควรมีการควบคุมการเข้าถึงเพื่อป้องกันการเข้าถึงข้อมูลที่ละเอียดอ่อนโดยไม่ได้รับอนุญาต
สิ่งสำคัญคือต้องป้องกันรูปแบบการโจมตีทั่วไป เช่น SQL injection, cross-site scripting (XSS) และ cross-site request forgery (CSRF) เพื่อป้องกันการใช้ประโยชน์จาก API ในทางที่ผิด
ข้อมูลที่ละเอียดอ่อนควรได้รับการเข้ารหัสทั้งในขณะที่จัดเก็บและในขณะส่งผ่านโดยใช้ HTTPS เพื่อป้องกันการรั่วไหลของข้อมูล นอกจากนี้ยังสามารถใช้การจำกัดอัตราเพื่อปกป้อง API จากการใช้งานในทางที่ผิด ความปลอดภัยไม่ใช่งานที่ทำครั้งเดียวจบ — การทดสอบความปลอดภัยเป็นประจำและการแก้ไขอย่างรวดเร็วเป็นสิ่งสำคัญในการลดความเสี่ยงเชิงรุก
7 การบำรุงรักษาเอกสารและการปรับปรุงอย่างต่อเนื่อง ▼
API ไม่ได้คงที่ — เมื่อความต้องการทางธุรกิจพัฒนาและคุณสมบัติเปลี่ยนแปลงไป API ก็จะมีการอัปเดตด้วย เอกสารจะต้องได้รับการอัปเดตตามนั้นเพื่อให้สะท้อนพฤติกรรมจริงของ API ช่วยให้นักพัฒนาฟรอนต์เอนด์ แบ็กเอนด์ และบุคคลที่สามเข้าใจและรวมเข้าด้วยกันได้อย่างรวดเร็ว
นอกจากการรักษาเนื้อหาให้ทันสมัยแล้ว API ก็ควรได้รับการปรับปรุงตามความคิดเห็นจากการใช้งาน — ทำให้เร็วขึ้น ปลอดภัยขึ้น และใช้งานง่ายขึ้น อาจมีการเพิ่มเอนด์พอยต์ใหม่ ปรับฟิลด์ หรือรวมฟังก์ชันที่ซ้ำกันเพื่อรักษา API ให้เรียบง่ายและใช้งานง่าย
การจัดการเวอร์ชันที่เหมาะสมก็เป็นสิ่งสำคัญเช่นกัน การเปลี่ยนแปลงที่สำคัญควรเผยแพร่เป็นเวอร์ชันใหม่ และเวอร์ชันที่เลิกใช้งานแล้วควรระบุไว้อย่างชัดเจน ด้วยการทำงานร่วมกันของทีมที่ดี API จะมีความเสถียร จัดการได้ง่ายขึ้น และอยู่ในตำแหน่งที่ดีขึ้นเพื่อรองรับการเติบโตของธุรกิจในระยะยาว
การส่งมอบ ในระหว่างขั้นตอนการส่งมอบ จุดเน้นจะเปลี่ยนจากการเขียนโค้ดและการรวม API ไปสู่การทำให้แน่ใจว่าพร้อมสำหรับการใช้งานจริง — ซึ่งหมายความว่าผู้ใช้สามารถนำไปใช้ได้อย่างง่ายดายและทำงานได้อย่างราบรื่นในการผลิต
1 เผยแพร่เว็บไซต์เอกสารออนไลน์ ▼
เมื่อ API ได้รับการพัฒนาและปรับใช้แล้ว ขั้นตอนต่อไปคือการจัดระเบียบและเผยแพร่เอกสารออนไลน์ ซึ่งช่วยให้นักพัฒนาฟรอนต์เอนด์ ผู้ทดสอบ และนักพัฒนาบุคคลที่สามสามารถทำความเข้าใจวิธีการใช้ API แต่ละรายการได้อย่างรวดเร็ว — รวมถึงวิธีการร้องขอ รูปแบบพารามิเตอร์ และโครงสร้างการตอบกลับ
หลีกเลี่ยงการแชร์เฉพาะภาพหน้าจอหรือไฟล์ PDF แต่ให้ใช้เครื่องมือเช่น Apidog หรือ Swagger UI เพื่อสร้างเอกสารออนไลน์แบบโต้ตอบ เครื่องมือเหล่านี้ไม่เพียงแต่ให้รูปลักษณ์ที่สะอาดและเป็นมืออาชีพเท่านั้น แต่ยังช่วยให้ผู้ใช้สามารถทดสอบ API ได้โดยตรงในเบราว์เซอร์ด้วยการคลิกเพียงครั้งเดียว
ที่สำคัญที่สุด: เอกสารของคุณต้องสอดคล้องกับ API จริง เมื่อใดก็ตามที่ API เปลี่ยนแปลง เอกสารควรได้รับการอัปเดตตามนั้น มิฉะนั้น ผู้ใช้จะประสบปัญหาและเสียเวลาพยายามค้นหาว่ามีอะไรผิดพลาด
2 คู่มือเริ่มต้นใช้งาน ▼
การมีเอกสารไม่เพียงพอ นักพัฒนาหลายคนไม่รู้ว่าจะเริ่มต้นจากตรงไหนเมื่อพวกเขาพบ API ของคุณเป็นครั้งแรก นั่นคือเหตุผลที่คู่มือ "เริ่มต้นใช้งาน" ที่ชัดเจนเป็นสิ่งสำคัญ ตัวอย่างเช่น: จำเป็นต้องมีการรับรองความถูกต้องหรือไม่? คุณจะได้รับโทเค็นได้อย่างไร? ลำดับการเรียก API ที่แนะนำคืออะไร? รายละเอียดเหล่านี้ควรได้รับการอธิบายอย่างชัดเจน
การรวมตัวอย่างโค้ดที่สมบูรณ์ — เช่น cURL, JavaScript หรือ Python snippets — สามารถเพิ่มโอกาสที่นักพัฒนาจะเรียกใช้ API ครั้งแรกได้สำเร็จอย่างมาก แม้แต่ตัวอย่าง "Hello World" ง่ายๆ ก็ช่วยให้พวกเขาสร้างความมั่นใจได้ภายในไม่กี่นาทีและเริ่มต้นใช้งานได้เร็วขึ้น
3 รหัสข้อผิดพลาดและการจัดการข้อยกเว้น ▼
ข้อผิดพลาดเป็นสิ่งที่หลีกเลี่ยงไม่ได้ในการใช้งาน API แต่สิ่งที่สำคัญที่สุดคือผู้เรียกสามารถเข้าใจข้อความแสดงข้อผิดพลาดได้อย่างรวดเร็วและระบุสาเหตุหลักได้หรือไม่ ดังนั้น รหัสข้อผิดพลาดแต่ละรายการควรมีความหมายที่ชัดเจน — เช่น พารามิเตอร์ไม่ถูกต้อง สิทธิ์ไม่เพียงพอ หรือบริการล้มเหลว — และควรมีคำแนะนำเกี่ยวกับวิธีการแก้ไข
ขอแนะนำให้กำหนดมาตรฐานรูปแบบการตอบกลับข้อผิดพลาด ตัวอย่างเช่น โดยการรวม code
, message
และ requestId
สิ่งนี้ทำให้การดีบักง่ายขึ้นและปรับปรุงความชัดเจน นอกจากนี้ ให้จัดเตรียมตารางรหัสข้อผิดพลาดที่สมบูรณ์เป็นส่วนหนึ่งของเอกสารเพื่อให้ผู้ใช้สามารถค้นหาปัญหาและแก้ไขได้อย่างรวดเร็วโดยไม่สับสน
4 จัดเตรียม SDK หรือ Client Wrappers ▼
เพื่อช่วยให้ผู้ใช้เรียกใช้ API ของคุณได้อย่างมีประสิทธิภาพและแม่นยำยิ่งขึ้น การจัดเตรียม SDK เป็นแนวทางที่มีประสิทธิภาพที่สุด
สำหรับภาษาที่เป็นที่นิยมเช่น JavaScript และ Python คุณสามารถพัฒนาไลบรารีไคลเอนต์ที่ใช้งานง่ายซึ่งรวบรวมตรรกะทั่วไป — เช่น การสร้างลายเซ็น การจัดการโทเค็น การลองใหม่ และการจัดการข้อผิดพลาด สิ่งนี้ช่วยให้ผู้ใช้มุ่งเน้นไปที่ตรรกะทางธุรกิจโดยไม่ต้องกังวลเกี่ยวกับรายละเอียดการใช้งานระดับต่ำ
SDK สามารถสร้างขึ้นโดยอัตโนมัติโดยใช้ข้อกำหนด OpenAPI หรือสร้างด้วยตนเอง แม้ว่าคุณจะไม่สามารถจัดหา SDK ที่สมบูรณ์ได้ การเสนอตัวอย่างโค้ดหรือเทมเพลต wrapper ก็ยังสามารถลดช่วงการเรียนรู้สำหรับการรวมได้อย่างมาก
5 การกำหนดเวอร์ชัน API และการแจ้งเตือนการเปลี่ยนแปลง ▼
เมื่อ API เปิดใช้งานและถูกใช้งานภายนอกแล้ว ไม่ควรเปลี่ยนแปลงโดยพลการ แม้แต่การแก้ไขเล็กน้อยในชื่อฟิลด์ โครงสร้างการตอบกลับ หรือรหัสสถานะก็อาจทำให้การรวมที่มีอยู่เสียหายได้
หากจำเป็นต้องมีการเปลี่ยนแปลงที่ส่งผลกระทบ ให้แยกการเปลี่ยนแปลงเหล่านั้นโดยใช้หมายเลขเวอร์ชัน — ตัวอย่างเช่น การอัปเกรดจาก /v1/
เป็น /v2/
— ในขณะที่ยังคงให้เวอร์ชันเก่าทำงานได้ บันทึกการเปลี่ยนแปลงที่บันทึกการอัปเดตแต่ละครั้ง ผลกระทบ และทางเลือกอื่นที่มีอยู่
สำหรับการเปลี่ยนแปลงที่สำคัญ ให้แจ้งผู้ใช้ล่วงหน้าผ่านอีเมล การประกาศกลุ่ม หรือช่องทางการสื่อสารอื่นๆ เพื่อป้องกันความล้มเหลวที่ไม่คาดคิดและหลีกเลี่ยงตั๋วสนับสนุนหรือข้อร้องเรียนที่ไม่จำเป็น
6 การสนับสนุนหลังการขายและช่องทางข้อเสนอแนะ ▼
การส่งมอบไม่ได้หมายถึงการสิ้นสุดของงานของคุณ — แต่เป็นจุดเริ่มต้นของการใช้งานจริง ตั้งค่าช่องทางการสนับสนุนที่ชัดเจนล่วงหน้า เช่น กลุ่ม Feishu, กลุ่ม DingTalk หรือระบบตั๋ว เพื่อให้ผู้ใช้สามารถรับความช่วยเหลือได้ทันท่วงทีเมื่อเกิดปัญหา
นอกจากนี้ การสร้างหน้า FAQ เฉพาะที่ตอบคำถามทั่วไปในระหว่างการรวม API ก็มีประโยชน์ ซึ่งช่วยให้ผู้ใช้แก้ไขปัญหาได้ด้วยตนเอง กำหนดสมาชิกในทีมที่ได้รับมอบหมายเพื่อตรวจสอบและตอบกลับความคิดเห็นเป็นประจำ เพื่อให้แน่ใจว่าไม่มีปัญหาใดที่ไม่ได้รับการตอบและปรับปรุงประสบการณ์การบริการโดยรวม
การวิเคราะห์ ขั้นตอนการวิเคราะห์จะเปลี่ยนจุดเน้นจากการพัฒนา API เอง และใช้มุมมองแบบองค์รวมว่า API ทำงานอย่างไรในการผลิต ซึ่งเกี่ยวข้องกับการระบุปัญหาที่อาจเกิดขึ้นและพื้นที่สำหรับการปรับปรุง ทำให้เป็นกระบวนการต่อเนื่องที่ช่วยพัฒนาและปรับปรุงคุณภาพของ API เมื่อเวลาผ่านไป
1 ตรวจสอบประสิทธิภาพ API ▼
เมื่อ API เปิดใช้งานแล้ว ขั้นตอนแรกคือการตั้งค่าการตรวจสอบ คุณควรมีข้อมูลที่ชัดเจนเกี่ยวกับเมตริกสำคัญ เช่น ปริมาณการเรียก API อัตราความสำเร็จ และเวลาตอบสนองเฉลี่ย ซึ่งสามารถทำได้ผ่านระบบบันทึกเกตเวย์ API หรือเครื่องมือ APM (Application Performance Monitoring)
เป้าหมายคือการตรวจจับปัญหาเชิงรุก — ไม่ใช่แค่การแก้ไขปัญหาหลังจากเกิดความล้มเหลว ตัวอย่างเช่น หาก API ส่งคืนข้อผิดพลาด 5xx บ่อยครั้ง หรือใช้เวลาตอบสนองนานกว่า 3 วินาที อาจบ่งชี้ถึงข้อผิดพลาดทางตรรกะหรือปัญหาคอขวดของฐานข้อมูลที่ต้องได้รับการแก้ไขทันที
2 ระบุปัญหาคอขวดด้านประสิทธิภาพ ▼
เมื่อประสิทธิภาพต่ำกว่าที่คาดไว้ จำเป็นต้องมีการตรวจสอบเพิ่มเติมเพื่อระบุสาเหตุหลัก API ที่ช้าอาจเกิดจากการสืบค้นฐานข้อมูลที่ซับซ้อน ดัชนีที่ขาดหายไป หรือการพึ่งพาบริการบุคคลที่สาม เครื่องมือติดตามสามารถช่วยระบุได้อย่างรวดเร็วว่าใช้เวลาส่วนใหญ่อยู่ที่ใด
เมื่อระบุปัญหาได้แล้ว ให้ประเมินกลยุทธ์การเพิ่มประสิทธิภาพที่อาจเกิดขึ้น — เช่น การเพิ่มแคช การเพิ่มประสิทธิภาพการสืบค้น SQL หรือการใช้การประมวลผลแบบอะซิงโครนัส — เพื่อปรับปรุงความเร็วการตอบสนองโดยรวมของ API
3 วิเคราะห์รูปแบบการใช้งาน API ▼
นอกเหนือจากเมตริกประสิทธิภาพแล้ว สิ่งสำคัญคือต้องทำความเข้าใจว่า API ถูกใช้งานจริงอย่างไร เอนด์พอยต์ใดที่ถูกเรียกบ่อยที่สุด? ฟิลด์ใดที่แทบไม่เคยใช้? พารามิเตอร์ใดที่มักจะส่งผ่านผิดพลาด? ข้อมูลเชิงลึกเหล่านี้สามารถเปิดเผยได้ว่าการออกแบบ API ของคุณสอดคล้องกับการใช้งานจริงหรือไม่
ตัวอย่างเช่น ฟิลด์ที่ไม่ได้ใช้งานนานอาจซ้ำซ้อน; พารามิเตอร์ที่ใช้ผิดบ่อยครั้งอาจบ่งชี้ถึงเอกสารที่ไม่ชัดเจนหรือการออกแบบที่ไม่ดี หากผู้ใช้รวม API หลายรายการซ้ำๆ เพื่อดึงข้อมูลบางอย่าง อาจคุ้มค่าที่จะพิจารณาเอนด์พอยต์ที่ตรงกว่าเพื่อลดความซับซ้อนในการรวม
4 รวบรวมความคิดเห็นของผู้ใช้ ▼
ความคิดเห็นเชิงอัตวิสัยจากนักพัฒนามีคุณค่าพอๆ กับข้อมูลการใช้งานจริง รวบรวมข้อมูลผ่านแบบสำรวจ ช่องทางการสนับสนุน กลุ่มแชท หรือระบบติดตามปัญหา เพื่อทำความเข้าใจปัญหาและข้อเสนอแนะจากผู้ใช้ API ได้ดียิ่งขึ้น
ปัญหาหลายอย่างจะไม่ปรากฏในบันทึก — ตัวอย่างเช่น การตั้งชื่อที่ไม่ชัดเจน การออกแบบพารามิเตอร์ที่ซับซ้อน หรือเอกสารที่ไม่เป็นระเบียบ ความคิดเห็นจากโลกแห่งความเป็นจริงมักจะเน้นจุดบอดในการออกแบบ API และทำหน้าที่เป็นข้อมูลอ้างอิงที่สำคัญสำหรับการปรับปรุง
ขอแนะนำให้จัดระเบียบและจัดหมวดหมู่ความคิดเห็นเหล่านี้เป็นประจำ ประเมินผลกระทบ และรวมรายการที่สามารถดำเนินการได้ในการปรับปรุง API ในอนาคต
5 การทำซ้ำเวอร์ชันอย่างต่อเนื่อง ▼
ข้อเสนอแนะในการเพิ่มประสิทธิภาพไม่ควรอยู่แค่ในขั้นตอนการอภิปราย — ควรนำไปรวมในการอัปเดตเวอร์ชัน API สำหรับการเปลี่ยนแปลงที่ส่งผลกระทบ ให้วางแผนกลยุทธ์การกำหนดเวอร์ชันที่ชัดเจน (เช่น การอัปเกรดจาก v1
เป็น v2
) และแจ้งผู้ใช้ทุกคนล่วงหน้า
พิจารณาการเผยแพร่การอัปเดตทีละน้อยโดยใช้เทคนิคเช่น canary releases เพื่อให้แน่ใจว่าการเปลี่ยนผ่านเป็นไปอย่างราบรื่นและลดความเสี่ยงในระหว่างการโยกย้าย
การรักษาระดับการพัฒนาที่มีโครงสร้างและสอดคล้องกันเป็นสิ่งสำคัญเพื่อให้มั่นใจถึงความสามารถในการใช้งานและความเสถียรของ API ในระยะยาว
// Step Icon const icons = { start: '<svg viewBox="0 0 1024 1024" width="18" height="18"><path d="M161.2 839.9v-654c0-56.1 60.7-91.1 109.3-63.1l566.3 327c48.6 28 48.6 98.1 0 126.2L270.4 903c-48.5 28-109.2-7.1-109.2-63.1z" fill="currentColor"></path></svg>', design: '<svg viewBox="0 0 1028 1024" width="18" height="18"><path d="M391.869261 773.877043l-152.40467-149.914397L143.638911 879.564202l248.23035-105.687159z m489.089494-479.228016L723.673152 132.48249 267.754086 582.225681l163.461478 169.537743 449.743191-457.114397z m129.593774-123.915953c21.316732-24.006226 0-70.12607 0-70.12607s-41.637354-46.119844-89.550194-81.083269c-47.91284-34.963424-84.868482 0-84.868483 0L755.050584 100.607004l164.656809 164.059144c0.099611 0 69.428794-69.926848 90.845136-93.933074z" fill="currentColor"></path><path d="M859.143969 1024h-694.287938C73.911284 1024 0 950.088716 0 859.143969v-694.287938C0 73.911284 73.911284 0 164.856031 0h495.165759v69.727626H164.856031C112.361089 69.727626 69.727626 112.361089 69.727626 164.856031v694.387549c0 52.395331 42.633463 95.128405 95.128405 95.128404h694.387549c52.395331 0 95.128405-42.633463 95.128404-95.128404V364.077821h69.727627v495.165759c-0.099611 90.845136-74.010895 164.75642-164.955642 164.75642z" fill="currentColor"></path><path d="M850.677043 493.571984v196.333074c0 90.845136-73.911284 164.856031-164.856031 164.856031h-196.233463v-69.727626h196.333074c52.395331 0 95.128405-42.633463 95.128404-95.128405V493.571984" fill="currentColor"></path><path d="M204.202335 208.18677m-34.863814 0a34.863813 34.863813 0 1 0 69.727627 0 34.863813 34.863813 0 1 0-69.727627 0Z" fill="currentColor"></path><path d="M204.202335 307.797665v199.22179-199.22179m34.863813-34.863813h-69.727627v268.949416h69.727627V272.933852z" fill="currentColor"></path></svg>', develop: '<svg t="1747383085060" viewBox="0 0 1024 1024" version="1.1" p-id="39086" width="18" height="18"><path d="M256 512l81.6 108.8a32 32 0 0 1-51.2 38.4l-96-128a31.968 31.968 0 0 1 0-38.4l96-128a32 32 0 0 1 51.2 38.4L256 512zM670.4 620.8a32 32 0 0 0 51.2 38.4l96-128a31.968 31.968 0 0 0 0-38.4l-96-128a32 32 0 0 0-51.2 38.4L752 512l-81.6 108.8zM503.232 646.944a32 32 0 1 1-62.464-13.888l64-288a32 32 0 1 1 62.464 13.888l-64 288z" p-id="39087" fill="currentColor"></path><path d="M160 144a32 32 0 0 0-32 32V864a32 32 0 0 0 32 32h688a32 32 0 0 0 32-32V176a32 32 0 0 0-32-32H160z m0-64h688a96 96 0 0 1 96 96V864a96 96 0 0 1-96 96H160a96 96 0 0 1-96-96V176a96 96 0 0 1 96-96z" p-id="39088" fill="currentColor"></path></svg>', deliver: '<svg t="1747719805966" viewBox="0 0 1024 1024" version="1.1" p-id="3539" width="18" height="18"><path d="M466.725 332.79c73.787 0 133.811-60.024 133.811-133.812S540.512 65.166 466.725 65.166 332.913 125.19 332.913 198.978s60.024 133.811 133.812 133.811z m0-223.02c49.188 0 89.208 40.02 89.208 89.208 0 49.2-40.02 89.208-89.208 89.208s-89.208-40.009-89.208-89.208c0-49.188 40.02-89.208 89.208-89.208zM756.65 602.003c73.788 0 133.812-60.023 133.812-133.812S830.438 334.38 756.65 334.38s-133.812 60.023-133.812 133.81 60.023 133.812 133.812 133.812z m0-223.02c49.188 0 89.208 40.009 89.208 89.208S805.838 557.4 756.65 557.4c-49.188 0-89.208-40.008-89.208-89.208s40.02-89.208 89.208-89.208z m201.283 403.025c-8.504-31.406-44.984-90.798-122.17-90.798H649.605c-0.302-0.384-0.5-0.792-0.805-1.176-33.061-41.402-83.556-65.142-138.516-65.142h-83.35c-53.422-65.445-142.354-83.182-183.227-87.988v-24.109c0-12.327-9.986-22.302-22.302-22.302H87.592c-12.317 0-22.302 9.975-22.302 22.302V914.23c0 12.327 9.985 22.302 22.302 22.302h133.812c12.316 0 22.301-9.975 22.301-22.302v-30.826c56.81 26.18 170.572 75.43 222.856 75.43h0.305c127.125-0.523 464.05-144.374 478.326-150.495 10.215-4.377 15.637-15.594 12.741-26.331zM199.102 891.927h-89.208v-356.83h89.208v356.83z m267.59 22.302h-0.207c-44.505 0-165.916-53.133-222.78-80.066V581.96c38.082 5.222 114.207 22.406 154.078 78.193a22.3 22.3 0 0 0 18.142 9.343h94.358c41.326 0 79.113 17.64 103.669 48.372 10.302 12.893 17.282 26.353 20.864 40.247H374.74c-12.317 0-22.302 9.976-22.302 22.302 0 12.327 9.985 22.302 22.302 22.302h285.22c12.317 0 22.303-9.975 22.303-22.302 0-15.318-2.73-30.191-7.789-44.604h161.289c39.975 0 61.047 23.196 71.13 40.227-75.867 31.537-339.07 137.776-440.2 138.189z" fill="currentColor" p-id="3540"></path></svg>', analyze: '<svg viewBox="0 0 20 20"><path d="M5 15v-4M10 15v-8M15 15v-2" stroke="currentColor" stroke-width="2"></path></svg>', arrow: '<svg viewBox="0 0 1024 1024" width="18" height="18"><path d="M686 593.3s-372.6 0.1-541.8 0.1c-44.3 0-80.2-36-80.2-80.2 0-44.3 35.9-80.2 80.2-80.2 141.9 0 541.5-0.1 541.5-0.1S658.8 405.8 535.1 282c-31.4-31.3-31.4-82.1 0-113.5s82.2-31.4 113.5 0l288 288c31.3 31.4 31.3 82.1 0 113.5 0 0-161.9 161.9-285.6 285.7-31.4 31.4-82.1 31.4-113.5 0-31.4-31.4-31.4-82.1 0-113.5C637.8 641.7 686 593.3 686 593.3z" fill="currentColor"></path></svg>', }; // Initialization step icon function initStepIcons() { const iconNames = [ "start", "design", "develop", "deliver", "analyze", ]; document.querySelectorAll(".step").forEach((step, index) => { step.querySelector(".icon").innerHTML = icons[iconNames[index]] || ""; if (step.querySelector(".arrow-icon")) { step.querySelector(".arrow-icon").innerHTML = icons.arrow; } }); } // Generate accordion "Previous Next" buttons function generateStepNav(currentStep) { const steps = Array.from(document.querySelectorAll(".step")).map((el) => el.textContent.trim() ); let html = '<div class="step-nav">'; if (currentStep > 0) { html += ` <button class="step-nav-btn prev-step" onclick="switchStep(${currentStep - 1 })"> <svg viewBox="0 0 20 20"><path d="M12 4l-8 6 8 6"/></svg> ก่อนหน้า: ${steps[currentStep - 1]} </button>`; } if (currentStep < steps.length - 1) { html += ` <button class="step-nav-btn next-step" onclick="switchStep(${currentStep + 1 })"> ถัดไป: ${steps[currentStep + 1]} <svg viewBox="0 0 20 20"><path d="M8 4l8 6-8 6"/></svg> </button>`; } html += "</div>"; return html; } // Initialize accordion navigation function initStepNav() { document.querySelectorAll(".step-section").forEach((section, idx) => { const lastAccordionContent = section.querySelector( ".accordion-item:last-child .accordion-content" ); if (lastAccordionContent) { const navContainer = document.createElement("div"); navContainer.className = "step-nav-container"; navContainer.innerHTML = generateStepNav(idx); lastAccordionContent.appendChild(navContainer); } }); } // Switching steps function switchStep(stepIdx) { console.log("stepIdx:" + stepIdx) if (stepIdx === null || stepIdx === undefined) { const stepIdx = 0; const steps = document.querySelectorAll(".step"); const sections = document.querySelectorAll(".step-section"); steps.forEach((s, idx) => { s.classList.toggle("active", idx === stepIdx); }); sections.forEach((section, idx) => { section.style.display = idx === stepIdx ? "block" : "none"; }); } else { const steps = document.querySelectorAll(".step"); const sections = document.querySelectorAll(".step-section"); steps.forEach((s, idx) => { s.classList.toggle("active", idx === stepIdx); }); sections.forEach((section, idx) => { section.style.display = idx === stepIdx ? "block" : "none"; }); // Determine data-anchor let anchor = steps[stepIdx].getAttribute("data-anchor"); if (anchor && anchor.trim()) { anchor = anchor.trim().replace(/\s+/g, "_"); } else { anchor = steps[stepIdx].textContent.trim().replace(/\s+/g, "_"); } window.location.hash = encodeURIComponent(anchor); // Smooth scroll to top document .querySelector(".content-section") .scrollIntoView({ behavior: "smooth" }); } } // Initialize the accordion function function initAccordions() { document.querySelectorAll(".accordion-title").forEach((el) => { const toggleAccordion = function () { el.classList.toggle("active"); const content = el.nextElementSibling; content.classList.toggle("active"); if (content.classList.contains("active")) { content.style.maxHeight = content.scrollHeight + "px"; } else { content.style.maxHeight = 0; } }; el.onclick = toggleAccordion; el.querySelector(".step-num").onclick = function (e) { e.stopPropagation(); toggleAccordion(); }; }); } // Step Switch Event function bindStepClick() { document.querySelectorAll(".step").forEach((el, idx) => { el.onclick = () => switchStep(idx); }); } // Get the step index that should be displayed based on hash function getStepIndexFromHash() { const steps = document.querySelectorAll(".step"); // if (!window.location.hash) return 0; const hash = decodeURIComponent(window.location.hash.slice(1)); for (let idx = 0; idx < steps.length; idx++) { let anchor = steps[idx].getAttribute("data-anchor"); anchor = anchor && anchor.trim() ? anchor.trim().replace(/\s+/g, "_") : steps[idx].textContent.trim().replace(/\s+/g, "_"); if (anchor === hash) { return idx; } } // return 0; } // Click on the picture to enlarge it document.addEventListener('DOMContentLoaded', function () { const images = document.querySelectorAll('.img'); const popup = document.getElementById('imagePopup'); images.forEach(img => { img.style.cursor = 'pointer'; img.addEventListener('click', function () { popup.innerHTML = `<img src="${this.src}" alt="${this.alt}">`; popup.style.display = 'block'; }); }); popup.addEventListener('click', function () { this.style.display = 'none'; }); }); // Initialize after the page is loaded document.addEventListener("DOMContentLoaded", () => { initStepIcons(); initAccordions(); initStepNav(); bindStepClick(); switchStep(getStepIndexFromHash()); });