สวัสดีครับ ผมชื่อต้นก้า พึ่งเรียนจบจากคณะวิศวกรรมศาสตร์ สาขาวิศวกรรมสารสนเทศ มหาวิทยาลัยพระจอมเกล้าลาดกระบังครับ
ในวันนี้ผมจะแชร์ประสบการณ์การออกแบบโครงสร้างระบบ front-end, back-end การเลือกใช้ฐานข้อมูล และ hosting ต่าง ๆ ของเว็ปไซต์ blog ชื่อดังเว็ปนึงที่พึ่งเปิดตัวครับ 555 เอาหล่ะ แต่ก่อนที่เราจะมาอธิบายวิธีการแบบเป๊ะ ๆๆ เรามาพูดถึง background และแรงจูงใจที่ผมอยากจะทำเว็ป blog เป็นของตัวเองกันก่อนดีกว่า ขอออกตัวก่อนครับ ว่าผมสาย back-end css ผมได้เท่าที่ทุกท่านเห็นนี่แหละฮ้ะ 555
background 🔥
เหตุการณ์ทั้งหมดเกิดขึ้นในขณะที่ผมกำลังนั่งไถเว็ป วงแหวนเว็บ เล่น ๆ เพื่อลอก inspiration ของคนอื่น (ล้อเล่นนะครับ 😂) ผมก็ได้ไปเจอเว็ปไซต์แนะนำตัวของบุคคลปริศนาคนนึง ซึ่งตอนนี้ผมก็ได้ลืมชื่อของบุคคลปริศนาคนนั้นไปแล้ว 😥 แต่เรียกได้ว่า เเว้ปแรกที่ผมเห็นผมถึงพูดกับตัวเองดัง ๆ ว่า "ไอเชี่ยยยย เท่ ชิปหาย" ซึ่งเหตุการณ์ในวันนั้นทำให้ผมอยากสร้างเว็ป blog เป็นของตัวเองขึ้นมา จนเกิดมาเป็นเว็ปไซต์ที่ทุกท่านเห็นกันนี่แหละครับ
ซึ่งหลังจากที่เรามีแรงจูงใจแล้ว ขั้นตอนต่อไปเราก็จะมา list concern ต่าง ๆ ในการจัดทำเว็ปไซต์นี้ตามลิสต์ด้านล่างครับ
- No User No Code เนื่องจากเว็ป blog นี้ ผมเป็นเจ้าของและพัฒนาเพียงคนเดียวส่วนไหนที่ User ไม่เห็นหรือไม่ได้สัมผัสถึงความเท่ ๆ ของผมจะพยายามทำให้มัน no code ทั้งหมด
- Front-end is the most user จากข้อแรกถ้าเรา no code ในส่วนของ front-end User จะรู้ได้ทันที และอาจจะไม่ได้สัมผัสถึงความเท่ ๆ ของผมก็ได้ ดังนั้น front-end ผมจะเขียนเองทั้งหมด!!
- No more cost ค่าใช้จ่ายทั้งหมดที่ใช้จะต้องไม่สูงมาก (ถ้าไม่มีจะดีมาก ๆ) เพราะผมไม่มีตังแล้ว TT
มาเลือก tools ที่เราจะใช้กันเถอะ 🚀
ซึ่งจาก concern ที่กล่าวมาเรื่อง No more cost ทำให้ผมนึกถึง firebase ขึ้นมาทันที เพราะเคยมีโปรเจ็คที่เคยทำที่มหาลัย ตอนนั้นผมเลือกใช้ firebase แล้วได้เห็นข้อดีต่าง ๆ มากมาย ไม่ว่าจะเป็น real-time database, authentication, แถมยังมี storage ให้ใช้อีก และที่สำคัญกว่านั้น คือ ถ้าหากเราไม่ได้ใช้งานมันหนักมาก แบบยอด User ทะลุ 20k ล้านคนต่อวินาที มันจะฟรี!! ซึ่งทุกวันนี้ โปรเจ็คที่ทำที่มหาลัยของผม ก็ยังสามารถเล่นได้อยู่ เอาเป็นว่าเราปัก firebase ไว้ในใจก่อน
แต่ ๆๆๆ จาก concern เรื่อง No User No Code ทำให้เราตระหนักได้ว่าเราจำเป็นต้องหา tools อะไรสักอย่าง ที่ทำหน้าที่เป็น CMS Admin ในการเพิ่มข้อมูล เวลามี Blog ใหม่ ๆ หรือจะ implement ในส่วนไหนเพิ่มเติม เพราะถ้าเราต้องมานั้งเขียน front-end หน้า admin เอง ผมคงเป็นซึมเศร้าไปเสียก่อน TT ซึ่งผมก็ใช้เวลาหาอยู่ค่อนข้างนาน จนได้มาลองเจ้าตัว rowy.io โดยมี concept ว่า Low-code backend on Firebase หลังจากได้ลองใช้งานแล้ว ผมก็ค่อนข้างประทับใจและที่สำคัญคือมันฟรี!! (ถ้าเราไม่ใช้ feature อื่นที่เสียตังของมันอะนะ) ซึ่งเดี่ยวผมจะมาขยายความในส่วนล่างว่ามันดียังไง
และในส่วนสุดท้ายจะเป็นเลือกใช้ tools สำหรับ front-end ผมคิดไว้อยู่แล้วว่าเราจะ Coding 100% โดยผมก็ได้เลือกเจ้าตัว next.js ซึ่งเป็น react ที่สามารถทำ ssr หรือ server-side rendering ได้อย่างอีซี่ และการทำ routing แบบ react-router ต้องชิดซ้ายเลยทีเดียว
สรุปในหัวข้อนี้เราจึงได้ tools ที่ใช้ทั้งหมดมา 3 tools ได้แก่
- firebase ที่เป็นทั้ง database, storage และอาจใช้ทำ authentication ในอนาคต
- rowy ที่ใช้เป็นหน้า admin dashboard + CRUD เอาของเข้าเจ้าตัว firebase
- next.js ที่ใช้ในการทำ ssr, routing โดย base จาก react
Diagram
เมื่อเราได้ tools ที่เราจะใช้แล้วต่อไปเราก็จะมาวาด diagram เพื่อให้เข้าใจระบบมากยิ่งขึ้น โดยหาก admin ทำการสร้างข้อมูล blog ใหม่ผ่านหน้า rowy เจ้าตัว rowy จะทำการสร้าง record เข้าสู่ firestore และเมื่อมี User เข้ามาดู blog หรือเนื้อหาภายในเว็ปเจ้าตัว UI ของ next.js จะส่ง request ไปที่ api และทำการเรียกขอข้อมูลจาก firestore และส่งข้อมูลกลับไปให้หน้า UI ตาม diagram ด้านบนเลย
Rowy X Firebase
ต่อไปเราจะมา config เจ้าตัว rowy กันเลยโดยเมื่อเราทำการเชื่อมเจ้าตัว rowy เข้ากับ firestore ของเราแล้ว เราสามารถที่จะสร้างตารางเพื่อเก็บข้อมูลของเราได้ ถึงเเม้ว่าเจ้าตัว firestore จะเก็บข้อมูลแบบ non-relational database แต่ใน rowy เราสามารถกำหนด schema ให้กับ document ของแต่ละ collection ได้ในลักษณะแบบ table ตามตัวอย่างรูปด้านล่าง โดยใน firestore จะเก็บข้อมูลเป็น collection และ document (เพื่อน ๆ สามารถอ่านเพิ่มเติมได้ ที่นี่ ถ้าจะให้เทียบง่าย ๆ collection จะเหมือน table ใน relational database และ document จะเหมือน row แต่ละ row ที่อยู่ใน table หรือ collection อีกที (1 collection มีได้หลาย document เหมือนกับ 1 table มีได้หลาย row)
รูปด้านบนก็จะเป็นตัวอย่าง (ตัวอย่างแหละ ไม่ได้แคปรูปของจริงมาจริง ๆ นะ 555) ผมได้สร้าง table ว่า Blogs ขึ้นมาโดยเราสามารถกำหนดชื่อ column และ type ให้กับข้อมูลของเราได้ด้วย ในตัวอย่างผมทำการเพิ่ม record ใน table blogs ขึ้นมา 2 row และใส่ value ต่าง ๆ ซึ่งเจ้าตัว rowy จะมีประเภทของข้อมูลให้เลือกแบบเยอะมาก แต่ชอบมากที่สุดก็คงเป็น type markdown นี่แหละที่ในขณะที่เพิ่มข้อมูลเราสามารถ preview markdown ของเราได้แบบ real-time เลย (ถึงแม้เวลาเก็บข้อมูลมันจะเก็บเป็นแบบ string ก็ตาม)
ซึ่งหลังจากที่เราเพิ่ม record ลงไปใน rowy แล้ว เจ้าตัว rowy ก็จะทำการ sync ข้อมูลของเราเข้าไปใน document ให้เราแบบ real-time เลย (real-time จริง ๆ ไม่ต้องกด save เลย) จะเห็นได้ว่าใน collection ของผมจะมี 2 document เรียบร้อยแล้ว
จะเห็นว่าในส่วนของ rowy ก็เสร็จแบบเรายังไม่ได้เปิด vscode เลย อ่อ มีเปิดรอบนึงเพราะกด icon ผิด (ล้อเล่นครับ 555)
Next.js X Firebase
ในส่วนของ Next.js ต่อกับ Firebase นั้น ตอนแรกผมกะจะอธิบาย step การต่อแบบละเอียด ๆ ให้เพื่อน ๆ ได้อ่านกันแหละฮ้ะ แต่พอคิดไปคิดมาแล้ว ถ้าอธิบายแบบละเอียดไป ก็จะไม่ใช่การรีวิวหล่ะสิ 555 เอาเป็นว่าถ้าเพื่อน ๆ สนใจจำเป็นต้องมีพื้นฐานความรู้เกี่ยวกับ React และ Next.js เสียก่อน (ขอบอกไว้ก่อนว่า doc next.js อ่านง่ายมาก ๆ เพื่อน ๆ สามารถไปศึกษากันได้ ที่นี่) และ doc ของ firebase ซึ่งการ implement ในส่วนของ api นั้นค่อนข้างที่จะง่ายมาก ๆ ผมจะแปะตัวอย่างโค้ดของเส้น /api/blogs ที่เป็นเส้นที่เอาไว้เรียกดูข้อมูล blogs ทั้งหมดที่ public ทั้งหมดเอาไว้
import { NextApiRequest, NextApiResponse } from "next";
import { collection, getDocs, query, where, orderBy } from "firebase/firestore";
import { db } from "@/backend/common/firebase";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if(req.method === "GET") {
let blogs:any[] = [];
let blogsCollection = collection(db, "blogs");
let q = query(blogsCollection, where("public", "==", true), orderBy("index", "asc"));
let snapshot = await getDocs(q);
snapshot.forEach((doc) => {
blogs.push(doc.data());
});
res.status(200).json(blogs);
}
}
ซึ่งสำหรับการ deploy project next.js ผมก็ได้ใช้ตัว vercel แค่กด ๆ คลิก ๆ ก็ได้เว็ปไซต์อย่างที่ทุกคนเห็นแล้วหล่ะครับ เอาจริง ๆ ส่วนที่ implement ยากที่สุดสำหรับผมก็คือ front-end นี่แหละฮ้ะ 5555 พวกหลังบ้านออกจะอีซี่มาก ๆ (แหละมั่ง) ก็หวังว่า blog สั้น ๆ นี้จะเป็นประโยชน์สำหรับผู้ที่เข้ามาอ่านบ้างนะฮ้ะ วันนี้ผมก็ขอลาไปก่อน แล้วพบกันใน blog ต่อ ๆ ไปนะคับ ขอบคุณมากค้าบบบบ <3