flask: สร้าง web backend ด้วย python

Pure
4 min readJul 9, 2021

--

สวัสดีครับ ทุกคนที่นี้คงเคยมีไอเดียอยากทำ web app ของตัวเองดูบ้าง ไม่ว่าจะใช้ในธุรกิจของตัวเอง ใช้กับกลุ่มเพื่อน หรือไว้ใช้งานส่วนตัว แต่ก็ล้มเลิกความคิดไปเพราะกลัวความยุ่งยากของการติดตั้งเครื่องมือในฝั่ง backend หรือเรื่อง hosting ต่างๆนาๆ ผมก็เคยกลัวเรื่องพวกนี้เหมือนกัน แต่พอศึกษาดูระดับนึงก็พบว่าการทำเว็บจริงๆไม่ได้ยุ่งยากอะไรขนาดนั้น เลยอยากจะมาแบ่งปันความรู้ และเครื่องมือต่างๆที่ใช้ในฝั่งของ backend/server-side ในบทความนี้ครับ

คำเตือน

  1. บทความนี้ตั้งใจจะเล่าเรื่องทางฝั่งของ backend และการติดต่อกับ frontend เป็นหลัก ขออนุญาติข้ามความรู้พื้นฐานของภาษา python และ frontend พวก HTML/CSS/JS ไปนะครับ (เพราะถ้าให้เขียนด้วยคงกลายเป็นอีกบทความนึงไปเลย)
  2. ตัวผมเองก็เพิ่งศึกษาเรื่องการเขียนเว็บเหมือนกัน เทคนิค/เครื่องมือที่ใช้อาจจะไม่ใช่สิ่งที่ดีที่สุด แต่ขอยืนยันว่าสามารถนำไปใช้ได้จริงแน่นอน ถ้าหากมีข้อผิดพลาดอะไรแจ้งในคอมเม้นได้เลยนะครับ พร้อมแก้ไขเสมอครับ

มา เข้าเรื่องกันเลย

ทำไมต้อง​ flask

ทุกคนคงเคยมีคำถามแบบนี้ เราจะมี backend ให้ยุ่งยากทำไม ในเมื่อเราสามารถเขียน javascript ได้ แล้วตัว jsก็สามารถประมวลผลอะไรได้แทบทุกอย่างอยู่แล้ว ไม่เห็นจำเป็นจะต้องเรียกใช้backendหรืออะไร คำตอบคือใช่ครับ แต่การใช้ js ประมวลผลยังมีข้อจำกัดใหญ่ๆอยู่เพราะ js เป็น client-side script หมายความว่าการประมวลผลเกิดขึ้นในเครื่องของผู้ใช้ ก็ดูไม่มีอะไรใช่ไหม ลองนึกถึงเว็บใหญ่ๆอย่าง facebook ดูสิ ถ้าข้อมูลทุกอย่างถูกส่งมาประมวลผลที่เครื่องของผู้ใช้ คอมบ้านไหนจะเข้าfacebookได้ เรื่องที่สอง ต่อมาจากเรื่องเดิม คือเนื่องจากการประมวลผลเกิดขึ้นในเครื่องของผู้ใช้ เราก็ต้องส่งไฟล์ js ของเราไปที่เครื่องของผู้ใช้ด้วย หมายความว่าทุกคนก็จะสามารถเห็นการทำงานข้างหลังของเว็บเราได้ด้วยการกดF12ปุ่มเดียว แล้วถ้าเว็บของเรามีการใช้งาน database ด้วยล่ะ ทุกคนก็สามารถเห็น api key ต่างๆที่ใช้เข้าถึง database ของเราได้ทันที แบบนี้ใครจะเข้ามาดู แก้ไข หรือลบdataทั้งหมดของเราทิ้งก็ได้เลยสิ เริ่มเข้าใจความสำคัญของ backend แล้วใช่ไหมล่ะ

หลักการทำงานของเว็บเราจะเป็นประมาณนี้ครับ

ต่อมา ตัวโมดูล​ flask ที่เราพูดถึงกันอยู่นี่เป็น​ web framework สำห​รับ​ภาษา​ python อธิบายง่ายๆ​ มันก็คือโมดูลที่เปลี่ยนโปรแกรม​ python ของเราให้กลายเป็น​ server ที่ฝั่ง​ frontend สามารถเรียกใช้ได้ครับ

มา​ เริ่มเขียนโค้ดกัน

เริ่มจากการติดตั้ง module ที่ใช้กันด้วย pip install flask กับ pip install flask_cors แล้วลองก็อปโค้ดข้างล่างไปดูครับ

from flask import *
import flask_cors
app = Flask(__name__)
flask_cors.CORS(app)
@app.route("/")
@app.route("/index")
def main():
return "Hello world!"
if __name__ == "__main__":
app.run(debug=True)

โค้ดนี้จะ​ import module flask เข้ามาในโปรแกรมแล้วสร้าง​ applications object ของ​ flask ขึ้นมาครับ​ โดยเมื่อมีการเรียก​ web service ที่ path /index ที่เรากำหนดไว้​ ตัวแอพจะส่งข้อความ​ Hello world ออกมาครับ

ลองกดรันเหมือนโปรแกรม​python​อื่นๆ (จะรันใน Editor หรือ cmd หรืออะไรก็แล้วแต่สะดวกเลยครับ)

พอรันแล้ว ในterminalเราจะขึ้นมาแบบนี้

​ แล้วลองเข้า 127.0.0.1:5000/index ใน browser แล้วไปเช็คดูครับ

ข้อความจะถูก return ออกมาแบบนี้

ไม่ได้จำกัดแค่สตริงเท่านั้น flask ยังสามารถส่งข้อมูลแบบอื่นๆออกมาได้อีก

อย่างเช่น ไฟล์ .json

รูปภาพ(.jpg)

ข้างล่างคือโค้ดที่ใช้ทดสอบเมื่อกี้นะครับ จะสังเกตได้ว่าผมเพิ่ม app route ขึ้นมาสองอันคือ /json กับ /img เพื่อใช้ return ไฟล์ .json กับไฟล์ภาพครับ

ตรง app.route() ไม่จำเป็นต้องเป็นใช้ชื่อแบบนี้เท่านั้นนะครับ อยากกำหนดอะไรก็ได้ครับ อย่างที่ผมเบียนเมื้อกี้นี้ ผมกำหนด route เป็น /json กับ /img เวลาเข้าในbrowser ก็เข้าที่ 127.0.0.1:5000/json กับ 127.0.0.1:5000/img ครับ

แค่นี้ web server ของเราก็พอจะใช้งานได้แล้ว ได้เวลาสลับกลับไปที่ฝั่ง frontend กันแล้ว

ถ้าเรามีไฟล์ index.html อยู่แบบนี้

<!DOCTYPE html>
<html>
<head>
<title>Sample web app</title>
<script src = "script.js"></script>
</head>
<body>
<p id = "test"></p>
<script>render()</script>
</body>
</html>

โค้ดที่เอามาก็ง่ายๆ ในหน้า index.html มี paragraph ที่ตั้ง id ไว้ว่า test แล้วเรียกฟังก์ชั่น render() ในไฟล์ script.js

ถ้าเราต้องการเปลี่ยน paragraph test ให้กลายเป็นไฟล์รูปที่ backend ส่งมาล่ะ(รูปจาก 127.0.0.1:5000/img ในขั้นที่แล้ว) จะทำยังไง

เราก็เพิ่ม url ของรูปเราลงในไฟล์ script.js แบบนี้

function render(){
const endpoint = "http://127.0.0.1:5000/"
var img = document.createElement("img");
img.src = endpoint + "img";
img.width = 400;
document.getElementById("test").appendChild(img);
}
รูปที่ส่งมาจากฝั่ง backend ก็ขึ้นในหน้า index.html ได้แล้ว
ถ้าดูใน terminal ของฝั่ง backend จะเห็นว่า server เราโดนเรียกใช้งานอยู่แบบนี้

จะเห็นได้ว่า backend ของเราทำงานได้อย่างที่เราได้คุยกันตอนต้นบทความแล้ว โดยเว็บของเราสามารถแสดงรูปภาพทั้งที่ไม่ได้อยู่ใน directory เดียวกับ index.html ตรงๆได้ วิธีนี้ทำให้เราสามารถซ่อนอัลกอริทึ่มหรือข้อมูลหลายๆอย่างจากผู้ใช้ได้ครับ

แล้วถ้าเกิดเราต้องการส่งข้อมูลจากฝั่ง frontend เพื่อไปประมวลผลที่ backend ล่ะ จะทำยังไง

เราสามารถทำได้หลายวิธีครับ วิธีง่ายๆที่ผมใช้ก็จะเป็นการส่ง request parameter ไปที่ web server อย่างเช่นถ้าผมพิมพ์url 127.0.0.1:5000/user?id=12345 จะเป็นการเรียกserver ที่route /user โดยส่ง parameter เป็น id = 12345 (ถ้าลองสังเกตดู เว็บใหญ่ๆบางเว็บ อย่าง youtube ก็ใช้การส่ง parameter แบบนี้เหมือนกันครับ)

หลักการก็จะประมาณนี้ กลับมาเขียนโค้ดกันต่อดีกว่า ต่อไอลองก็อปโค้ดด้านล่างนี้ไปใส่ในไฟล์ python ของเราดู

@app.route("/user")
def login():
id = request.args.get('id')
return "Hello " + id

โค้ดก็ไม่มีอะไรมาก เรารับ parameter id มาจากฝั่ง frontend แล้วก็ส่งข้อความทักทายกลับไปครับ

ลองเข้าดูใน browser ได้เหมือนเดิมครับ พอเปลี่ยน url ข้อความก็จะเปลี่ยนไปด้วย

ต่อไปก็สลับกลับมาฝั่ง frontend กันเล้ย

function send(){
var id = 12345;
var xhr = new XMLHttpRequest();
xhr.open("GET",endpoint+"user?id="+id,false);
xhr.send(null);
document.getElementById("output").innerHTML = xhr.responseText;
}

ผมลองสร้างฟังก์ชั่นใหม่ขึ้นมาในไฟล์ script.js อันเดิม ตอนนี้เราจะสร้างตัวแปร xhr ที่ใช้เก็บ object XMLHttpRequest ที่จะใช้ส่งข้อมูลไปฝั่ง backend ครับ

บรรทัดต่อมาจะเป็นใส่ method ที่ใช้ส่งข้อมูล(ในที่นี้เป็นGET) ,endpoint ที่ใช้ ,และ false เพื่อให้ส่งข้อมูลแบบ Synchronous แล้ว send(null) เพราะครั้งนี้เราไม่จำเป็นต้องส่ง request body ใดๆไปด้วยครับ

ต่อมา xhr.responseText คือตัว response ที่ฝั่ง server ส่งมาให้ ในตอนนี้เราจะลองให้แก้ไขที่ paragraph output เพื่อทดสอบดูครับ

ปล. เรื่อง HTTP method ลองไปอ่านเพิ่มเติมได้ที่ลิ้งค์นี่นะครับ

แล้วผมก็จะแก้ไขไฟล์ index.html ให้สามารถรับ input ได้

อย่างที่เห็นข้างบน ไฟล์ index.html ที่แก้ไขใหม่ให้มีช่อง input ที่ตั้ง id เป็น num ปุ่มที่ใช้เรียกฟังก์ชั่น send() ในไฟล์ .js แล้วก็ paragraph ที่ตั้ง id เป็น output ครับ

พอเราลองใส่ id 12345 เข้าไป ตัวฟังก์ชั่น send() ก็จะส่งข้อมูลไปที่ฝั่ง backend เพื่อประมวลผล แล้วส่งกลับมาแบบนี้ครับ

โค้ดของเราก็ทำงานได้เรียบร้อยแล้วล่ะ

และแล้วเราก็สามารถทำให้ frontend และ backend ของเว็บเราเชื่อมต่อและส่งข้อมูลไปมาถึงกันได้สมบูรณ์แล้ว ที่เหลือก็เป็นการนำ server ของเราไป host แล้ว (คงไม่มีใครอยากเปิดคอมทิ้งไว้ตลอดเวลาอยู่แล้วล่ะ) ก็มีบริการหลายๆที่ ที่ให้เรา host ได้ทั้งแบบฟรีและเสียเงิน แต่ถ้าถามผม ส่วนตัวยังแนะนำ replit.com คู่กับ uptimerobot เหมือนเดิมครับ (ใครที่ไม่รู้จัก ไปอ่านที่ผมเล่าเรื่อง replit.com ได้ในบทความสอนทำบอท discord ช่วงล่างๆได้เลยครับ) อย่าลืมเปลี่ยนคำสั่งรันให้เป็น app.run(host=”0.0.0.0", port=8000) แล้วแก้ endpoint ในไฟล์ .js ให้ถูกต้องด้วยนะครับ

บทความตอนนี้ก็คงต้องขอจบแต่เพียงเท่านี้ครับ หวังว่าบทความนี้จะมีประโยชน์กับผู้อ่านทุกคนไม่มากก็น้อยครับ

สวัสดีครับ

--

--

Pure
Pure

Written by Pure

Just another Computer Engineering student.

No responses yet