""โอกาส" ก็สำคัญพอกับ "อากาศ" นั่นแหละ"
โครงสร้างพื้นฐาน(มาก)ของการติดต่อแอป ฯ กับ Database ฝั่ง Server สำหรับผู้เริ่มต้น
28 Jan 2017 19:06   [252675 views]

ทุกวันนี้ทำแอป ฯ แค่ Offline มันไม่พอแล้ว เพราะแอป ฯ ที่นิ่งเฉยไม่มีอะไรเปลี่ยนแปลงผู้คนจะใช้แค่ครั้งสองครั้งแล้วก็เลิก ดังนั้นไม่ต้องแปลกใจที่แอป ฯ เกือบทั้งหมดที่เราใช้ทุกวันนี้จึงเป็นแอป ฯ แบบ Online มีการติดต่อกับฝั่ง Server ทั้งสิ้น

ซึ่งพอความต้องการฟีเจอร์ด้านนี้มันสูง(จนกลายเป็นเรื่องสามัญไปแล้ว) งานที่ทุกคนไม่ว่าจะระดับนักศึกษายันระดับมืออาชีพต้องทำให้เป็นคือ "การเขียนโปรแกรมติดต่อกับฝั่ง Server"

ทำให้เกิดหนึ่งในคำถามคลาสสิคที่เจอบ่อยมากตามเพจโปรแกรมมิ่งคือ

ผมอยากเขียนแอป ฯ ให้ติดต่อกับ Database ฝั่ง Server จะต้องทำยังไงครับ?

ซึ่งอันนี้ต้องยอมรับว่า เป็นคำถามที่เกิดจากความไม่เข้าใจโครงสร้างพื้นฐานของการออกแบบระบบเลย แต่ความไม่รู้ก็ไม่ใช่ความผิดแต่อย่างใด ถ้าไม่รู้ก็แค่ต้องทำให้รู้เนอะ บล็อกนี้เลยตั้งใจเขียนเป็น Reference สำหรับผู้เริ่มต้นครับ ถ้าเกิดใครเจอคำถามแบบเดียวกันนี้ก็สามารถส่งบล็อกนี้ให้ผู้ถามอ่านได้ทันที มา เริ่มเลยละกันกับ "โครงสร้างพื้นฐานของระบบที่มีการติดต่อแอป ฯ กับ Server" =)

โครงสร้างพื้นฐาน Client และ Server

เริ่มต้นจากโครงสร้างแบบ Overview สุด ๆ การทำแอป ฯ แบบ Online จะประกอบด้วยส่วนสำคัญสองส่วนคร่าว ๆ ได้แก่ Client และ Server

Client คือส่วนที่เอาไว้ประสานผู้ใช้ ในที่นี้ก็คือแอป ฯ มือถือนั่นเอง ส่วน Server คือส่วนด้านหลังที่ตั้งอยู่สักที่นึงเพื่อให้ Client ติดต่อเข้าไปเพื่อเก็บข้อมูลหรือดึงข้อมูลออกมาอีกทีนึง

สำหรับผู้เริ่มต้นก็มักจะมองว่าฝั่ง Server คือส่วนของ Database เอาไว้เก็บข้อมูลโน่นนี้ ถ้างั้นก็เลยสามารถวาดโครงสร้างพื้นฐานแบบคร่าว ๆ ได้เป็นแบบนี้

ในชีวิตจริงเราก็จะมี Client อยู่มากมาย อาจจะเป็นมือถือนับล้านเครื่อง ส่วน Server ก็จะตั้งไว้ตรงกลางสักที่นึงในโลกเพื่อรอให้ Client ติดต่อไป

โอเค ตอนนี้เรารู้จัก Client กับ Server แล้ว ... แต่ ... ภาพด้านบนยังมีส่วนที่สร้างปัญหาในอนาคตได้ ปัญหาคืออะไรและเราจะแก้กันยังไง ? ไปดูหัวข้อต่อไป

ห้ามติดต่อกับ Database โดยตรง

ภาพด้านบนก็ดู Simple ดีเนอะ ตั้ง Database Server ไว้และให้ Client ติดต่อเข้าไปเลย

แต่ !!

ข้อห้ามข้อนึงของระบบ Client - Server คือ เราห้ามให้ Client ติดต่อ Database โดยตรงเป็นอันขาด

สาเหตุมีอยู่เยอะมาก

1) ช่องโหว่ความปลอดภัยใหญ่

ในการเปิดให้ Client สามารถติดต่อเข้าไปยัง Database Server ได้โดยตรง เราจำเป็นต้องเปิด Port ให้เครื่องข้างนอกสามารถติดต่อตรงเข้ามาที่ Database ได้ และแน่นอนว่าผู้ไม่หวังดีก็สามารถติดต่อมาได้เช่นกัน

หากเป็น Database ที่มีการใส่ Username / Password ไว้ ก็อาจจะโดน Bruteforce เพื่อหารหัสเข้าถึงได้ในที่สุด หรือถ้าเป็น Database ที่ไม่มีการจำกัดการเข้าถึงไว้เช่น MongoDB ก็จะโดนโจมตีได้ทันทีอย่างข่าวที่เห็นไปไม่นานมานี้ (ฐานข้อมูล MongoDB ถูกเจาะเป็นจำนวนมาก ข้อมูลถูกล้างและเรียกค่าไถ่)

และหากโดนแฮคจริง ๆ เราจะไม่สามารถจำกัดความเสียหายได้เลยเพราะ Database Server สามารถทำงานกับข้อมูลได้ทุกอย่าง อย่างเลวร้ายสุดก็คือโดนลบข้อมูลหมด ถึงขั้นปิดบริการเลยนะ

2) ความไร้มาตรฐานของ Interface

หากคุณฝืนติดต่อตรงไปยัง Database คุณจะไม่สามารถทำงานร่วมกับโปรแกรมเมอร์คนอื่นในโลกได้เลย เพราะว่าไม่มีใครเค้าทำกันนั่นเอง

3) ประสิทธิภาพแย่(มาก)

โดยปกติการทำงานกับ Database มันจะไม่ได้ตรงไปตรงมา ประมาณว่าดึงข้อมูลแล้วเอามาใช้ให้จบ ๆ ไปอะไรแบบนั้นนะ แต่มันจะต้องมี Logic อะไรเต็มไปหมดเพื่อให้มันทำงาน ๆ นึงได้

การจะทำงานสักงานเช่น ทำระบบ Blog แล้วจะสร้างบล็อกใหม่ เราอาจจะต้องติดต่อไปยัง Database ทั้งหมด 10 ครั้งกว่าทุกอย่างจะทำงานได้เสร็จสมบูรณ์

และการติดต่อแต่ละครั้งนี่ก็ใช้เวลาสูงมากนะ อาจจะครั้งละ 1 วินาที ถ้าต้องติดต่อ 10 ครั้งก็รอไป 10 วินาทีกว่าจะเสร็จหนึ่งงาน ซึ่งไม่ Make Sense เอาเสียเลย เราแฮปปี้มั้ยหละที่จะทำสักอย่างแล้วต้องรอ 10 วิอ่ะ ไม่ใช่มะ

นอกจากนั้นระหว่างรอการติดต่อ 10 วินาทีนั้น ก็อาจจะมี Client เครื่องอื่นติดต่อเข้าไปและเกิดปัญหาได้จากสถานะของ Database ที่เปลี่ยนไปเปลี่ยนมาอยู่

อันนี้ถือเป็นอีกหนึ่งปัญหาใหญ่ที่เตรียมตัวเจอหากฝืนติดต่อไปยัง Database โดยตรง

4) การซ้ำกันของโค้ดโดยไม่จำเป็น

หากเราติดต่อจาก Client ตรงไปยัง Database Server โค้ดส่วนของการทำงานกับ Database ก็จะถูกฝังไว้ใน Client ซึ่งในชีวิตจริงจะมีอยู่หลายตัวมาก หลัก ๆ ถ้าทำแอป ฯ มือถือก็ iOS และ Android

ส่งผลให้เราต้องยัดโค้ดที่สุดซับซ้อนไปทั้งใน iOS และ Android อย่างหลีกเลี่ยงไม่ได้ จึงเกิดการซ้ำกันของโค้ดโดยไม่จำเป็น หนำซ้ำหากต้องการจะแก้ไขอะไรก็ต้องแก้ทั้งสองที่ (หรือถ้ามากกว่านั้นก็นับไป) ความลำบากจะเพิ่มขึ้นตามเวลาเลยหละ


จริง ๆ ยังมีเหตุผลสนับสนุนอีกเป็นสิบว่าทำไมเราไม่ควรเปิด Database Server ให้เข้าถึงจากภายนอกได้ แต่หลัก ๆ ก็คงเป็น 4 ข้อที่พูดถึงไป ดังนั้นขอให้จำไว้ว่า ถึงแม้ทางเทคนิคเราจะสามารถติดต่อตรงไปยัง Database ได้ แต่เรา "ห้ามทำเป็นอันขาดไม่ว่ากรณีใด ๆ" อย่ามักง่าย อย่าคิดว่าไม่เป็นอะไรหรอกมั้ง เพราะถ้าเกิดความเสียหายแล้วเราจะไม่สามารถแก้ไขอะไรได้เลย ทำได้แค่ปิดบริการอย่างเดียวเท่านั้น

ประเด็นนี้ถือเป็นการตอบชัด ๆ สำหรับมือใหม่ที่มักถามคำถามว่า "จะติดต่อจากแอป ฯ มือถือไปยัง Database ได้ยังไง" ว่าคำถามนี้ผิดครับ เพราะว่าเราจะไม่ทำกันแบบนั้น

แล้วถ้าห้ามติดต่อ Database โดยตรงจาก Client แล้วเราจะทำยังไงหละ ?

คั่น Client กับ Database ด้วยโค้ดฝั่ง Server

วิธีที่ถูกต้องคือ เราจะต้องเขียนโค้ดฝั่ง Server ขึ้นมาเป็นตัวกลางระหว่าง Client และ Database อีกทีครับ โดยโค้ดตัวนี้จะถูกฝังอยู่บน Server จะที่เดียวหรือคนละที่กับ Database ก็ได้ ไดอะแกรมจึงกลายเป็นแบบนี้

โดย Server Side Code นี้จะเขียนด้วยภาษาหรือเฟรมเวอร์คอะไรก็ได้ตามถนัดและความเหมาะสม จะ PHP, Node.js, JSP, Spring, Golang ฯลฯ ก็ได้หมด แต่การติดต่อ (Interface) จะต้องอยู่ในรูปแบบมาตรฐาน เช่น REST หรือ GraphQL โดยมีเหตุผลว่า

1) จะได้ทำงานร่วมกับคนอื่นได้

2) เมื่อ Interface เป็นมาตรฐาน ก็จะมีไลบรารี่ให้เลือกใช้มากมายแทบไม่ต้องทำอะไรเลย ใช้งานง่าย ชีวิตดี

3) Server Side Code ควรจะเป็น Blackbox ที่คนติดต่อ (Client) ไม่จำเป็นต้องรู้ว่าด้านในทำมาจากอะไร เพียงแต่เรียกใช้งานได้ เพราะวันหนึ่งหากเราต้องการเปลี่ยนเทคนิคเบื้องหลัง เช่นเปลี่ยนจาก PHP เป็น Node.js ก็เปลี่ยนได้เลยขอเพียงคงรูปแบบการติดต่อ (Interface) ไว้ให้เหมือนเดิม

และการติดต่อนี้เองที่เราเรียกมันว่า Application Programming Interface หรือ API

ซึ่งพอมันอยู่ในโครงสร้างแบบนี้ ปัญหาทั้งหมดที่ลิสต์ไว้ด้านบนก็จะมลายหายไป

- Database ถูกซ่อนไว้เบื้องหลัง API อีกทีนึง ไม่ได้เปิดสู่ภายนอก ทำให้ไม่มีช่องให้เจาะเข้าไปยัง Database โดยตรงอีกต่อไป

- หาก API โดนแฮคก็จะถูกจำกัดความเสียหายไว้ที่ความสามารถของ API ไม่ใช่ว่าจะทำอะไรก็ได้

- ประสิทธิภาพดี เพราะ API กับ Database สามารถคุยกันได้โดยใช้เวลาน้อยมากเนื่องจากมันอยู่บน Server อาจจะใช้เวลาติดต่อแค่ 1ms ต่อครั้งเท่านั้น หากงานนั้น ๆ ต้องติดต่อ 10 ครั้งก็ใช้เวลาแค่ 10ms ส่งผลให้การทำงานโดยรวมเร็วมาก ๆ Server อาจจะส่งผลตอบกลับในไม่กี่มิลลิวินาทีเลย

- โค้ดไม่มีการซ้ำกันโดยไม่จำเป็นอีกต่อไป เพราะเราจะยัดโค้ดที่เอาไว้ติดต่อกับ Database ไว้ที่เดียวคือบน Server และมองว่า API คือ "งาน ๆ นึง" ติดต่อแค่รีเควสต์เดียวแล้วที่เหลือให้ Server ทำให้เรา หากต้องการแก้ไขอะไรก็แก้ที่เดียวคือ Server นั่นเอง

และนี่คือคำตอบของคำถามที่ถามกันมาเยอะ ๆ ในกรุ๊ปต่าง ๆ

หากเราต้องการจะทำงานกับ Database ฝั่ง Server เราจะต้องทำ API ขึ้นมาเพื่อเป็นตัวกลางติดต่อครับ

หากไม่ทำตามนี้จะถือว่าบาปมาก เข้าใจตรงกันน้าาาาา

ศึกษาเพิ่มเติม

พอเห็นภาพคร่าว ๆ แล้วเนอะ คราวนี้ก็จะมาอยู่หลายส่วนเหมือนกันที่ต้องศึกษาเพิ่มเติมเพื่อให้ความรู้ในการทำ API สมบูรณ์ ได้แก่

- REST คืออะไร

- GraphQL คืออะไร

- JSON คืออะไร

- เราจะเขียน REST หรือ GraphQL ด้วยโค้ดฝั่ง Server ขึ้นมาได้ยังไง

หากองค์ความรู้ครบแล้วก็ลุยทำเลยครับ อันนี้สำคัญสุด งานโปรแกรมมิ่งคืองานปฏฺิบัตินะอย่าลืม การลงมือทำคือหนทางเดียวของความสำเร็จจ้า

ถ้าทำ Server ไม่เป็นจะทำยังไง ?

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

1) สกิลการทำ Mobile App

2) สกิลการตั้ง Server (ถ้าเลือกจะตั้งเอง แต่ถ้าใช้ Share Hosting ก็ไม่ต้อง)

3) สกิลการเขียนโค้ดฝั่ง Server

หากทีมใหญ่ก็คงไม่มีปัญหาอะไร กระจายงานกันทำ แต่ถ้าทีมเล็ก ๆ หรือว่าทำอยู่คนเดียวก็คงปาดเหงื่อ จะทำยังไงดีหละทีนี้ ?

ในกรณีนี้แนะนำให้ไปหาบริการ Backend as a Service (BaaS) เช่น Firebase มาใช้งานครับ

โดยระบบอย่าง BaaS จะเตรียมทุกอย่างเอาไว้ให้หมด ทั้ง Database, File Storage และ API โดยที่เราไม่ต้องแตะต้องงานฝั่ง Server เลยแม้แต่นิดเดียว แค่เขียน Client ให้เรียกคำสั่งตามที่เค้ากำหนดมา เป็นอันเสร็จเรียบร้อย งานเดียวที่เราต้องทำก็คือ Mobile App หรือหน้าเว็บเท่านั้น ลองดู Case Study ที่เราเคยทำโปรดักชั่นมาแล้วตัวนึงก็ได้ >> บันทึกเบื้องหลังการพัฒนาระบบ Live Blog ด้วย Angular 2 + Firebase

อันนี้คงเป็นคำแนะนำเบื้องต้นที่ดีที่สุดครับ หากคุณยังไม่พร้อมจะทำงานฝั่ง Server เองก็หาพวกนี้มาใช้ สะดวกและทำงานได้เร็ว =)

สรุป

ก็อย่างที่บอกนะครับ บล็อกนี้เน้นโครงสร้างพื้นฐานมาก ๆ สำหรับมือใหม่โดยเฉพาะนิสิตนักศึกษา เรียกว่าเลเวล 1 เลย นี่เป็นสิ่งแรกที่ทุกคนต้องเข้าใจก่อนจะไปทำอะไรอย่างอื่นต่อ สำหรับมืออาชีพเรื่องนี้กลายเป็นพื้นฐานที่ทุกคนรู้กันโดยไม่ต้องพูดถึงแล้ว แต่ยังไงถ้าใครเจอมือใหม่แล้วไม่อยากอธิบายซ้ำหลายรอบสามารถส่งบล็อกนี้ไปให้อ่านกันได้ครับ

จากนี้จะพยายามเขียนเรื่องพื้นฐานให้เยอะขึ้นเพราะพอมีเรื่องพวกนี้อ่านแล้วบทสนทนาใน Community ก็จะได้เข้มข้นขึ้น ไม่ใช่วนคุยแต่เรื่องพื้นฐานเดิม ๆ อีกต่อไป =)

เย้ เย

บทความที่เกี่ยวข้อง

Jul 23, 2017, 15:36
237172 views
บันทึกสองเดือนของการสังเกตการณ์ แอบดูการทำงานของคนใน Silicon Valley
Jun 19, 2017, 13:46
231230 views
สาย Dev ห้ามพลาด ชวนไปร่วมแข่งงาน TechJam by KBTG งาน AI Hackathon งานแรก ๆ ของไทย ชิงรางวัลไป Silicon Valley
0 Comment(s)
Loading