Tutorial

Flask vs FastAPI ต่างกันยังไง ? เราควรจะเลือกใช้ตัวไหน ?

By Arnon Puitrakul - 14 มีนาคม 2022 - 1 min read min(s)

Flask vs FastAPI ต่างกันยังไง ? เราควรจะเลือกใช้ตัวไหน ?

ปีก่อนเราสอน Course Machine Learning Deployment (ปีนี้ก็จะเปิดอีกเด้อ รอได้เลย) แล้วมีผู้เรียนถามว่า ทำไมตอนนั้นเราใช้ Flask ไม่ได้ใช้ FastAPI ในการสอน เออ เป็นคำถามที่ดีเลย เพราะจริง ๆ แล้ว 2 Library นี้มันทำเหมือนกันคือ ทำให้เราสามารถ Deploy Web Server ได้ง่าย ๆ เลย แล้ว มันต่างกันยังไง แล้ว FastAPI มันดีกว่า Flask จริง ๆ เหรอ

Flask

Flask เป็น Library ตัวนึงที่นักพัฒนาเรียกตัวเองว่าเป็น "Micro-framework" เขียนขึ้นมาจาก Python เปิดมาในช่วงปี 2010 ก็คือนานแล้วละ ที่มันทำให้เราทำพวก Web Server ได้ง่าย ๆ เพียงไม่กี่บรรทัด เราก็ได้แล้ว ซึ่งก็จริงของเขาแหละ โดยที่ Flask มันจะทำงานอยู่บน WSGI หรือ Web Server Gateway Interface (PEP3333) อีกทีนึง

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "Hello World"

if __name__ == "__main__" :
    app.run()

การใช้งาน ก็ง่ายมาก ๆ เราสามารถสร้าง Function ของแต่ละ Endpoint ได้เลย พร้อมกับกำหนด Path ผ่าน Decorator แค่นั้นเลย เราก็ใช้งานได้แล้ว

ในการรัน Web Server ขึ้นมา เราอาจจะใช้ท่าที่เราใช้ด้านบนก็ได้ หรือจะใช้ Command flask run ก็ได้เหมือนกัน แต่อันหลังเป็นอะไรที่ Documentation ของ Flask เองก็บอกไว้แหละ ทำแบบใน Documentation ดีกว่า เราแค่ชินกับการใช้ app.run() เท่านั้นแหละ

FastAPI

FastAPI เรียกว่า เกิดหลังจาก Flask ไป 8 ปีเลยทีเดียว เพราะมันเกิดในช่วงปี 2018 แน่นอนว่า ถ้าเราเอามาเปรียบเทียบแบบนี้แปลว่า สิ่งที่มันทำได้ก็ไม่ต่างจาก Flask เลยคือ การสร้าง Web Server ขึ้นมาโดยใช้ Code เพียงไม่กี่บรรทัดเท่านั้นแหละ แต่สิ่งที่ FastAPI ต่างจาก Flask และทำให้เหนือกว่าในด้านนึงคือการที่ FastAPI เลือกใช้ ASGI (Asynchronous Server Gateway Interface) ไว้เดี๋ยวมาคุยกันว่ามันคืออะไร ต่างจาก WSGI ยังไง

นอกจากนั้น FastAPI มันคิดมาเจ๋งกว่านี้อีกคือ มันมาพร้อมกับ Auto Generated Documentation และ SWAG UI ให้กับทุก Endpoint เลย ทำให้เราไม่ต้องมานั่งจำแล้วว่า เรามี Endpoint อะไรบ้าง แล้วแต่ละอัน มันรับอะไรคืนอะไร มันทำให้เราหมดแล้ว เมื่อก่อน เราอาจจะต้องใช้พวกโปรแกรมอย่าง Postman แล้วแชร์ Environment อะไรกันยากไปหมด แต่อันนี้คือ มันทำให้เราหมดเลย เราไม่ต้องยุ่งอะไรกับมันเลย

อีกเรื่องที่คำคัญมาก ๆ คือ FastAPI มีพวก Data Validator มาให้เราด้วย หมายความว่า เราสามารถกำหนดลงไปได้เลยว่า Parameter ของแต่ละ Endpoint จะเป็นอะไร และ Type ใดบ้าง หรือกระทั่ง เราสามารถเขียน Custom Validation Function มาเพื่อเช็คมันตรง ๆ เลยก็ยังได้ ทำให้เราสามารถป้องกันปัญหาหลาย ๆ อย่างที่จะเกิดขึ้นได้ แต่กลับกัน Flask ไม่มีสิ่งนี้มา ทำให้เราจะต้อง Implement เองทั้งหมด ซึ่งใช้เวลาโดยใช่เรื่องอีก

WSGI vs ASGI

มาที่ความแตกต่างชัด ๆ ของเจ้า 2 ตัวนี้กันเลย เป็นสิ่งที่ทำให้หลาย ๆ คนบอกว่าเห้ยนี่นะ เราไม่ต้องใช้แล้ว Flask เราใช้ FastAPI ดีกว่า เร็วกว่า เพราะ FastAPI มันใช้ AGSI นะ แต่ Flask มันใช้แค่ WSGI เองนะ นั่นบูลลี่ Flask ไปอี๊ก

เราจะไม่บอกละกันว่าอะไรเร็วกว่า แต่สิ่งที่ AGSI เหนือกว่า WGSI หลายเท่าเลยนั่นคือ การรองรับโหลดจำนวนมากพร้อม ๆ กัน เพราะ AGSI ตามชื่อของมันเลยคือ Asynchronous หมายความว่า มันสามารถที่จะรองรับการทำงานแบบ Parallel ได้ เช่น เรามี Load เข้ามาทั้งหมด 5 โหลด ถ้าเป็น Synchronous แบบเมื่อก่อน เราก็ต้องทำทีละโหลด โหลดนึงเสร็จก็ไปที่อันต่อไป กลับกัน Asynchronous ทำให้เราสามารถรันทั้งหมด หรือเกือบทั้งหมดได้พร้อม ๆ กันเลย คือ รันได้ทีละมากกว่า 1 โหลด

ซึ่งเอาเข้าจริงแล้ว ถ้าเรานึกถึงธรรมชาติของพวก Web Server เวลาเราใช้งานจริง ๆ เราก็จะต้องออกแบบให้มันสามารถรับโหลดได้พร้อม ๆ กันอยู่แล้ว ทำให้ AGSI เลยเป็นอะไรที่น่าสนใจกว่า WSGI ในแง่ของการรับโหลดค่อนข้างเยอะ นั่นแหละ เป็นสาเหตุที่ทำให้หลาย ๆ คนบอกว่า เนี่ยนะ FastAPI มันเร็วกว่า Flask เอาเข้าจริง พูดแบบนั้นมันก็ไม่ถูกซะทีเดียว แต่น่าจะบอกว่า FastAPI มันรับโหลดพร้อม ๆ กัน ได้มากกว่า Flask ละกัน ถ้าพูดว่าเร็ว ความเร็วต่อ Request เราว่า "ไม่น่าจะ" ต่างกันนะ ยังไม่เคยเทสเหมือนกัน

WGSI ออกมาในช่วงเวลาที่เราก็เน้น Serve กันแค่ HTTP ปกตินี่แหละ เป็นหน้าเว็บ เป็น API อะไรก็ว่ากันไป เมื่อเวลาผ่านไปมันก็จะมีพวกการเชื่อมต่อแบบอื่น ๆ งอกขึ้นมา ที่อาจจะจำเป็นต้องมีการเปิด HTTP เอาไว้ เช่นการส่ง WebSocket ที่มันจะต้องเปิดคาไว้ แล้วก็ค่อย ๆ โยนข้อมูลไปเรื่อย ๆ  หรือส่งมาแล้ว มันมีหลาย Event ที่ต้องทำ พวกนี้แหละ เป็นข้อจำกัดของ WGSI ทำให้ AGSI ตอบโจทย์กว่ามาก ๆ ในเรื่องของการทำอะไรที่เราต้องเปิด HTTP คาไว้ยาว ๆ

ดังนั้น สรุปง่าย ๆ คือ WGSI มันเกิดมาก่อน ทำงานแบบพื้น ๆ เลยคือการ รับ Request แล้วส่ง Response กลับไป เมื่อโหลดเยอะ ๆ มันก็ไม่สามารถทำพร้อม ๆ กันได้ แต่ในขณะที่พวก AGSI มันสามารถทำงานหลาย ๆ โหลดพร้อม ๆ กันได้เลย ทำให้ต่อวินาที มันสามารถรับโหลดได้มากกว่านั่นเอง เราไม่ขอลงลึกไปถึงพวก Channel Layer อะไรนะ ไม่งั้นยาวมาก

แล้วเราจะเลือกใช้อันไหนดี ?

สำหรับงานทั่ว ๆ ไป เรามองว่า อะไรก็ได้นะ แต่ถ้าเราบอกว่า เราขึ้นงานจริง ณ วันนี้เลย เราแนะนำไปเล่น FastAPI ดีกว่า เพราะมันจัดการพวก Document และรองรับพวก Web Socket ด้วยเพราะมันใช้ AGSI ส่วนตัว Flask เราไม่ได้บอกว่ามันไม่ดีนะ เพราะจริง ๆ แล้ว การเขียนโปรแกรมแบบ Async เอาเข้าจริง มันก็จะมีความยากอยู่ในบางงาน หรือ เราจะต้องคำถึงพวกโหลด และ I/O Bound ต่าง ๆ ที่ทำให้ Async ไม่เป็น Async ซะทีเดียว เพราะมันต้องรอ I/O นอกจากนั้น อีกกลุ่มที่เราแนะนำให้ใช้ Flask คือ คนที่พึ่งเริ่มต้นเขียน เรามองว่า Flask เป็นอะไรที่เข้าใจง่าย ตรงไปตรงมา นั่นเอง ทำให้ตอนเราสอนเราเลยให้ใช้ Flask นั่นเอง