Beginner tutorial for NodeJS, express and MongoDB
วันนี้เราจะมาพูดถึงการเขียน backend โดยใช้ nodejs, express และ mongoDB กันนะครับ สำหรับคนที่ยังไม่รู้ว่า backend และ express คืออะไร มีความสำคัญยังไงก็สามารถไปตามอ่านกันได้ที่บทความข้างล่างนี้เลยยย
หลังจากที่เปิดเข้าไปอ่าน link ก่อนหน้านี้เเล้ว ก็อาจจะมีบางคนที่ตกใจเล็กน้อย เเต่!!! อย่าพึ่งรีบปิดหนีไปไหน ใน tutorial นี้เราจะเน้นสอนแบบง่ายๆ ที่ไม่คำนึงถึงเรื่องของ best practice หรืออะไรที่มันฟังไม่รู้เรื่องพวกนั้น ก็คือใน tutorial นี้เราจะเขียนยังไงก็ได้ที่ทำให้เข้าใจได้ง่ายสุด เเต่ยังสามารถนำไปใช้งานได้ (สำหรับบางคนที่สนใจวิธีการเขียนที่เป็นมาตรฐาน และมีหลักการต่างๆมาช่วย ก็สามารถรอติดตามต่อได้ใน tutorial อันถัดๆ ไปนะครับ)
ก่อนที่เราจะมาเริ่มเขียน code กัน ก็ต้องมาดูสิ่งที่จะต้องใช้กันก่อน โดย tutorial นี้จะใช้อยู่ 4 อย่างคือ
- NodeJS ใช้สำหรับ run server ที่เราจะเขียนกัน
- MongoDB database เอาไว้เก็บข้อมูล
- Editor ตัวโปรด ถ้าใครที่ยังไม่มีก็เเนะนำให้โหลด VSCode ได้นะครับ 😊
- Postman เอาไว้ใช้ทดสอบ request กับ backend ที่เรากำลังจะเขียนกัน
Part 1: Getting started
ขั้นแรกให้เข้าไป download starter template จาก https://github.com/chutipon29301/medium-express-mongo-tutorial-1
หลังจากที่โหลดกันมาเสร็จเรียบร้อยก็ให้เปิด folder ที่โหลดมาด้วย editor ก็จะได้หน้าตาประมาณนี้
หลังจากนั้นก็ให้เปิด terminal
หรือ cmd
ขึ้นมาเเล้วทำการย้าย directory ของเราเข้าไปใน folder template
เมื่อเข้าไปได้เเล้ว ก็สามารถ install package ที่จำเป็นต้องใช้โดยใช้คำสั่ง npm install
ถ้าลงเสร็จเเล้วเราก็จะได้ folder ชื่อ node_modules
เพิ่มขึ้นมาใน folder ของเรา folder นี้จะทำหน้าที่เก็บ dependency ทั้งหมดที่เราใช้ใน project นี้ไว้ด้วยกัน
เมื่อเราได้ทำการโหลด package ทั้งหมดเข้ามาไว้ใน project ครบทุกตัวเเล้ว ในลำดับถัดไป เราก็จะมา test กันว่า project ที่เรานั่งโหลดมาตั้งนานเนี่ย มันใช้ได้รึเปล่า คำสั่งที่เราจะใช้นั้นก็คือ npm start
และนี่คือสิ่งที่เราหวังว่าจะเห็นกัน
สำหรับคนที่ไม่ได้เเบบนี้ก็อย่าพึ่งตกใจไป ลองแก้ไขปัญหาเบื่องต้นตามนี้ก่อนได้เลยครับ
- ถ้ามันบอกว่าหา
npm
ไม่เจอ: ให้ลองเช็คดูก่อนว่าเราได้ลง NodeJS นั้นถูกต้อง เพราะตัวnpm
ปกติแล้วมันจะมากับ installer ของ NodeJS อยู่เเล้ว - ถ้ามันบอกว่าหา dependency ไม่เจอ: ลองดูก่อนว่าที่เรา install package ไปนั้น ไม่ได้ลงผิด folder (ตรงนี้ขอย้ำอีกครั้งว่าต้องเรียก
npm install
ใน folder template ไม่ใช่เรียกข้างนอกสุดนะครับ)
และขั้นตอนตรวจสอบสุดท้าย ให้เข้าไปที่ browser และ เข้าไปที่ http://localhost:3000/ping สิ่งที่เราควรจะได้มานั้น ควรจะมีข้อความประมาณนี้
และก็ได้จบไปแล้วนะครับ สำหรับ part 1 มันคงเป็น part ที่ งงๆ กันอยู่ว่าทำไปทำไม จริงๆ แล้ว สิ่งที่ต้องการจาก part นี้ก็คือเรื่องของการเช็ค environment ของเครื่อง และการโหลด และ run project ที่ได้เตรียมไว้ให้สำหรับ tutorial นี้
Part 2: WebServer
ใน part นี้เราก็จะมาพูดถึงพระเอกของ tutorial นี้ดีกว่า นั้นก็คือ mongoDB นั้นเอง ก็จะมีหลายคนที่พึ่งเริ่มกันก็คงยังจะงงกันอยู่ว่า database นั้นเอาไว้ทำอะไร
Database นั้นมีหน้าที่เอาไว้เก็บข้องมูลเเบบถาวร โดย mongoDB ที่เราจะใช้กันนั้นจะเป็น database ที่เก็บข้อมูลเป็น object ข้อดีของการเก็บข้อมูลเเบบนี้คือง่าย และสามารถเรียนรู้เบื่องต้นได้เร็วกว่าแบบอื่นๆ
ต่อมาเราจะมาอธิบายโครงสร้างของ mongoDB กันดีกว่า เวลาเราต้องการใช้ mongoDB สิ่งแรกที่เรารู้ก่อนเลยคือชื่อ Database เป็นชื่อที่ตั้งให้กับ database ที่เราจะต้องการใช้ โดยส่วนใหญ่ก็จะใช้ชื่อ project เป็นชื่อ database เลย ลำดับถัดมา ใน แต่ละ database ก็จะมี collection อันนี้ก็จะเหมือน folder ที่จะคอยจัดการข้อมูลที่อยู่ใน database และสุดท้ายในแต่ละ collection ก็จะมี document หรือข้อมูลแต่ละ object ที่เราต้องการจะเก็บนั่นเอง
หลังจากที่เราเริ่มเห็นภาพว่าสิ่งที่เราจะต้องใช้นั้นมีหน้าตาและโครงสร้างเป็นยังไง ก็ได้เวลาที่เราจะเริ่มในสิ่งที่รอคอยกันแล้ว นั้นก็คือออออ…. Coding นั่นเองงงง
และอันนี้ก็คือ code พื้นฐานที่ได้เตรียมไว้ให้นะครับ ลองมาดูกันดีกว่าว่า code ชุดนี้เอาไว้ทำอะไรบ้าง
เริ่มจาก 2 บรรทัดแรกก่อนเลย
ใน project นี้เราก็จะให้ dependency 2 ตัวด้วยกัน ก็คือ express
และ body-parser
หน้าที่ของ express
ก็คือเอาไว้สร้าง webserver ที่จะเอาไว้ใช้ติดต่อกับ client ส่วน body-parser
เอาไว้แปลงข้อมูลที่ client ส่งมาให้เรา สิ่งที่เราได้ทำไว้ในส่วนนี้ก็คือ ประกาศตัวแปร bodyParser
และ app
เก็บค่าทั้ง 2 อย่างที่เราจะใช้เอาไว้
ในบรรทัดถัดมา ก็จะสังเกตได้ว่าเป็นการใช้อะไรซักอย่างกับ bodyParser
และ app
สิ่งที่ทำตรงนี้นั้นเป็นการบอกว่าให้ express
หรือ app
ใช้ bodyParser
ในการแปลงค่า body ที่เราจะใช้ใน project นี้
ตรงนี้ก็จะเป็นการบอก webserver ของเราที่ถูกสร้างมาจาก express ใช้ port 3000
ในการ run server
และสุดท้าย เป็นการบอกให้ app รอรับ GET
request โดยใช้ path /ping
และให้ ส่งค่า {msg: "pong"}
กลับไปให้กับคนที่เรียก /ping
ในลำดับต่อมา ก็มาถึงเวลาที่เราจะได้ใช้ mongo กันแล้ว สำหรับตัว mongoDB ใน node นั้นเค้าได้มีการเตรียม mongodb ชึ่งเป็น official driver สำหรับ NodeJS ไว้ให้ใช้กัน วิธีการลง เราจะใช้ npm ที่ได้มากับการลง node กันนะครับ เราต้องลง dependency นี้ด้วยการพิมพ์ npm install mongodb --save
ได้ใน terminal
หรือ cmd
เมื่อโหลดเสร็จแล้วก็กลับมาที่ file index.js
ของเรา เเล้วทำการ import mongodb ที่พึ่งจะโหลดไป เข้ามาใน file
ถัดไป เราจะมาทำการต่อ database กัน โดยสิ่งที่จะต้องใช้ในการ connect database ก็คือ database url ซื่งในที่นี้ เราจะให้ database ที่อยู่ในเครื่อง ดังนั้น database url ของเราก็จะเป็น mongodb://localhost:27017
แต่ถ้าเราจะต้องการใช้ database ที่อยู่ online ก็ให้ทำการเปลี่ยน url เป็น mongodb://<url-or-ip-address>:27017
และจาก code ข้างบนจะสังเกตได้ว่าเราได้ย้าย app.listen
เข้ามาข้างใน MongoClient.connect()
เพราะว่าเราจะต้องการให้ server ของเรานั้นเริ่มทำงานหลังจากที่ connect database ได้แล้ว
ใน code อันนี้ก็จะมีส่วนเพิ่มเติมอีก 2 ส่วนด้วยกันคือ if(error) throw error;
ส่วนนี้เป็นการเช็ค error ที่มาจากการต่อ database ถ้ามี error เราก็จะ throw error ออกมา อีกส่วนนึงก็คือ var db = client.db("MediumTutorial")
อันนี้ก็จะเป็นการประกาศตัวเเปรเอาไว้เก็บ database ของเรา ส่วนที่เราเขียนไว้ข้างใน db()
จะเป็นชื่อ database ที่ได้พูดไปเเล้วข้างบนนะครับ ใครที่ลืมก็ขึ้นไปอ่านใหม่ได้นะ
ต่อมาเราจะมาพูดถึงภาพรวมของสิ่งที่จะได้ทำใน tutorial นี้กันนะครับ โดยสิ่งที่เราจะมาเขียนกันในวันนี้จะเป็น backend ที่สามารถให้ user สามารถ create, list, edit, delete และ login
Part 2.1: List user
Syntax ของ mongo ที่เราจะใช้ใน request นี้ก็คือ find
และ toArray
เริ่มต้นจาก db
คือตัวแปรที่เราประกาศไว้ก่อนหน้านี้เพื่อเก็บ instance ของ database ที่เราจะต้องใช้, collection
เป็นการเรียกชื่อ collection ที่อยู่ใน database ในที่นี้ขอใช้ชื่อว่า users
ต่อมา find
หน้าที่ของมันก็คือใช้สำหรับหาข้อมูลที่อยู่ใน collection และ toArray
จะนำข้อมูลที่เราหาได้มาเปลี่ยนค่าให้เป็น array ของ object
ในส่วนของ find
นั้นเดี๋ยวจะมีอธิบายเพิ่มเติมอีกในตอนที่เรามาทำ request login กัน
หลังจากที่เราเขียนเสร็จแล้ว ก็ลองมา ทดสอบกันดีกว่า ว่า code ที่เราเขียนไปนั้นถูกต้องมั้ย ขั้นตอนแรก ถ้าเรายังไม่ได้ run npm start
ก็ให้ run คำสั่งนี้ก่อน ผลลัพท์ที่ควรจะได้นั้นหน้าตาควรจะเหมือนกับ part 1 และเราสามารถเข้าไปที่ requet ที่เราเขียนไว้โดยใช้ Postman เข้าไปที่ link localhost:3000/listUsers
และสิ่งที่เราจะได้มาก็คืออออ array เปล่านั่นเอง ถ้าถามว่าทำไมได้ผลมาแบบนี้หละ คำตอบนั้นก็ง่ายมากครับ ก็เรายังไม่ได้สร้าง user ไงงงง เพราะฉะนั้น part ถัดไปเราจะมาพูดในเรื่องของการสร้าง user กัน
Note: สำหรับคนที่ใช้ mac ให้ run process ของ mongo ขึ้นมาก่อน run
npm start
โดยให้พิมพ์mongod
ลงไปใน terminal
Part 2.2: Create user
อ้าาา มาถึงใน part 2.2 กันแล้ว ใน part นี้เราจะมาดูวิธีสร้าง user หรือการเอาข้อมูลใส่เข้า database กัน คำสั่งที่เราจะใช้ใน part นี้ก็คือ insertOne
เอาไว้ใช้ใส่ข้อมูลเข้า database โดยสิ่งที่จะต้องรู้เพิ่มเติมก็คือ _id
นั้นเป็น primary key ของ collection ที่เราจะเก็บ
หลายคนก็คงจะงงต่อว่า primary key มันคืออะไร อธิบายแบบง่ายสุดก็คือเป็น field ที่ใน 1 collection นั้นจะต้องไม่มีค่าซ้ำกันเลย ซึ่งในนี้ก็คือ email ที่ client ส่งมาให้เรา ถ้าเราพยายามใส่ document ที่มี _id
ซ้ำกันตัวของ mongo จะ throw error ออกมาบอกว่า _id
มีค่าซ้ำกันและทำให้การใส่ข้อมูลของเราไม่สำเร็จ
และแล้วก็มาถึงเวลาที่เราจะมาทดสอบกันอีกครั้งว่า code ของเรานั้นสามารถทำงานได้รึเปล่า ถ้าใครที่ยังไม่ได้ปิด npm start
จากขั้นก่อนหน้าก็ให้ใช้ postman เข้าไป send request ได้เลย ส่วนใครที่เผลอปิดไปแล้วก็ run ใหม่ด้วยนะครับ
ในการสร้างครั้งแรกนั้น สิ่งที่ควรจะได้ก็คือ OK
นะครับ เพราะเราได้เขียนไว้จาก code ด้านบนไว้ว่า ถ้าไม่เกิด error ให้ส่ง OK
กลับมา
เเต่ถ้าเราพยายามที่จะ add user ด้วย email อันเดิม เราก็จะได้ error แบบด้านล่างนี้ นี่เป็นการแสดงคุณสมบัตรของ _id
ที่ได้เล่าไปก่อนหน้านี้
หลังจากที่เราได้ add user ไปเรียบร้อยแล้ว ถ้าเราลองกลับไปใน request ที่ได้เขียนไว้ใน part 1 และลองใช้ดู ก็จะพบว่า เราจะไม่ได้ array เปล่าคืนอีกต่อไป เเต่จะได้ array ที่มี user ที่เราพึ่งจะ add ไป คืนกลับมา
Part 2.3: Edit user
ในส่วนนี้ เราก็จะมาพูดถึงวิธีการแก้ไขข้อมูลที่อยู่ใน database กัน ซึ่งก็ตาที่เห็นใน code ข้างบนนี้ ก็จะสังเกตได้ถึงคำสั่งที่เรา นั่นก็คือ updateOne
ตัวของ updateOne
จะใช้สำหรับ แก้ไขข้อมูลของ document 1 อันตามเงื่อนไขที่เราใส่ไปใน parameter ที่ 1 เป็นข้อมูลที่เราใส่ไปใน parameter ที่ 2 แต่ถ้าเราสังเกตดีๆ ก็จะพบว่า object ที่เราได้ใส่ไปใน parameter ที่ 2 นั้น หน้าตามันก็จะแปลกๆ กว่าที่เราเคยเจอมา
โดยปกติแล้ว mongo นั้นจะเอาค่าใน parameter ที่ 2 ที่เราได้ใส่ไป ไปแทนที่อันเก่าเลย แต่นั่นไม่ใส่สิ่งที่เราต้องการทำใน tutorial นี้ เราต้องการที่จะเปลี่ยน password เฉยๆ ไม่ใช่เปลี่ยนทั้ง document เป็น password อย่างเดียว ด้วยเหตุผลนี้ จึงเกิด syntax $set
ขึ้นมา เพื่อเป็นการบอก mongo ว่าเราต้องการที่จะ set ค่าที่อยู่ใน object นี้เข้าไปใน document ไม่ใช่การเอาไปทับทั้ง document
และเมื่อเราลอง edit และ list ออกมาดูเราก็จะเห็นได้ว่า password ที่เราใส่เข้าไปตอนแรกนั้นได้เปลี่ยนไปเป็นสิ่งที่เราใส่เป็น body เมื่อกี้
Part 2.4: Login
ต่อมา เราจะมาลองเขียน request login ดูบ้าง สิ่งที่เราจะทำใน request นี้ก็คือไปหา user 1 คนที่มี email ตรงกับที่ user ส่งเข้ามา แล้วค่อยเช็คว่า password นั้นตรงหรือไม่
ใน code ข้างบนนี้เราจะใช้ findOne
ในการหา document เพียง 1 อันเเละคืนกลับมาใน result โดยสิ่งที่เราสามารถใส่เข้าไปใน findOne
ก็คือ condition ที่เราจะต้องการหา ในที่นี้เราก็ต้องการที่จะหา email ซึ่งเราได้เก็บไว้ใน _id
เลยได้ object ที่เป็น condition เลยมีหน้าตาแบบนี้ {_id: req.body.email}
และถ้าเราลอง request โดยใช้ postman ดู ก็จะได้ค่าคืนมาเป็น true
และ false
ตามที่เราได้เขียนนะครับ
Part 2.5: Delete
และสุดท้ายนี้ เราจะมา delete user ออกจาก database กัน สำหรับ delete นั้นค่อนข้างง่ายนะครับ เพราะเราได้รู้เรื่องของ findOne
มาก่อนหน้านี้แล้ว เราก็แค่เปลี่ยนจาก findOne
เป็น deleteOne
เราก็จะสามารถ delete document ได้อย่างง่ายดาย
และเมื่อเราลอง delete และ list user ดู เราก็จะได้ ผลลัพธ์ ตามภาพด้านล่าง
และแล้วเราก็ได้มาถึงช่วงสุดท้ายของบทความนี้กันแล้ว สำหรับคนที่สนใจ วิธีการใช้ mongoDB ในแบบอื่นๆ ก็สามารถเข้าไปอ่าน function ทั้งหมดที่ทาง mongo ได้เตรียมไว้ให้ตาม link นี้ได้เลย
และสุดท้ายนี้ เราก็ได้เตรียม code ที่ได้ทำเสร็จแล้วไว้ใน folder ที่ชื่อ final ใครที่ตามไม่ทันก็สามารถเข้าไปดูกันได้นะครับ