Tại sao lại chọn Fastify framework thay vì ExpressJS?
Trước đây, mỗi khi bắt đầu một dự án Nodejs mới là mình mặc định sử dụng ExpressJS framework. Có lẽ mọi người ở đây chắc cũng giống mình.
Với những ưu điểm, thế mạnh về cộng đồng, ExpressJS vẫn luôn là framework được sử dụng rộng rãi nhất hiện nay.
Tuy nhiên, cho đến một ngày, mình nhận dự án với code base đang sử dụng fastify. Mình khá tò mò về nodejs framework mới mẻ này. Ok, thử lên mạng tìm hiểu xem sao, kết quả mình thấy là rất nhiều người cũng sử dụng fastify cho các dự án của họ. Đặc biệt là fastify được đánh giá rất tốt.
Sau một thời gian làm việc với fastify, mình ngày càng cảm thấy yêu thích nó hơn và cũng dần sử dụng nó cho các dự án sau này.
Bài viết này, chúng ta cùng nhau tìm hiểu fastify là gì? Tại sao lại chọn fastify cho các dự án Nodejs nhé.
Giới thiệu Fastify
Fastify không chỉ là một nodejs framework khác bên cạnh ExpressJS. Nó là một trong những framework được quảng bá là nhanh nhất hiện nay. Cái này có lẽ phải để các dự án thực tế trả lời, chứ nghe mấy ông sáng lập quảng cáo thì cũng biết vậy thôi nhỉ
Có một số lý do để bạn thích fastify:
- Hiệu năng cao, tốc độ nhanh
- Hỗ trợ Async/Await cho tất cả các thành phần như: route handlers, application hooks, server methods (ví dụ:
.listen()
)… - JSON input: Mặc định fastify hỗ trợ đọc json từ body mà bạn không cần phải cấu hình chỉ định application/json
- Logging: Fastify có sẵn một trình ghi log. Do đó, bạn không cần phải suy nghĩ cách ghi log như nào, lưu log ở đâu… Fastify nó làm sẵn cho hết rồi.
Và còn rất nhiều ưu điểm khác của fastify so với ExpressJS, các bạn cứ sử dụng và trải nghiệm dần dần.
Xây dựng ứng dụng quản lý sách bằng fastify + MongoDB
Để các bạn có một trải nghiệm, một cái nhìn chân thực hơn về fastify framework, chúng ta sẽ cùng nhau thực hành tạo một ứng dụng REST API.
Tổng quan dự án: Dự án xây dựng REST API với đầy đủ các tính năng CRUD một cửa hàng sách. Để lưu trữ dữ liệu, chúng ta sử dụng MongoDB.
Các dependencies sử dụng trong dự án:
- fastify: Tất nhiên rồi, dự án này chúng ta đang học cách sử dụng fastify mà.
- mongoose: module giúp đơn giản hóa thao tác với MongoDB.
- nodemon: giúp tự khởi động server mỗi khi cập nhật code.
- boom: Hỗ trợ xử lý HTTP error đơn giản hơn.
Ok, mọi thứ đã sẵn sàng, chúng ta vào việc thôi!
Khởi tạo dự án fastify
Để tạo một dự án một dự án mới tinh, mình hay dùng câu lệnh sau:
Trên Linux: mkdir fastify-store && cd fastify-store && touch index.js && npm init -y Trên Window: mkdir fastify-store && cd fastify-store && type nul > index.js && npm init -y
Trong đó, fastify-store là tên thư mục dự án.
Tiếp theo là cài đặt các dependencies cần thiết mà mình đã liệt kê ở trên:
npm install boom mongoose fastify nodemon
Sau khi cài đặt xong, chúng ta mở index.js và thêm đoạn code để tạo một http server.
//index.js const fastify = require('fastify')({ logger: true }) const PORT = 3000 fastify.get('/', async() => { return { Test: 'VNTALKING xin chào cả nhà' } }) const serve = async () => { try { await fastify.listen(PORT) fastify.log.info(`Server listening to PORT ${fastify.server.address().port}`) } catch (err) { fastify.log.error(err) process.exit(1) } } serve()
Trong đoạn code trên:
- Bật fastify logger, mặc định tính năng này là disabled.
- Chọn một port và gán cho ứng dụng. Cụ thể, port mình chọn ở trên là 3000
- Định nghĩa một route (“/”). Tức là trang root của chúng ta.
Sau khi sửa code xong thì chạy server thôi.
npx nodemon index
Kết quả khi chạy lệnh trên:
Mở postman (hoặc trình duyệt) để truy cập thử đường dẫn http://localhost:3000
Xem thêm việc làm Node.js developer hấp dẫn nhất tại TopDev
Cài đặt MongoDB
Các bạn tải MongoDB về và cài đặt trên máy tính của mình nhé. Bạn cài đặt bình thường như bao phần mềm khác thôi. Do khuôn khổ bài viết, mình sẽ không hướng dẫn chi tiết cách cài đặt MongoDB.
Sau khi cài đặt mongodb thành công, bạn sử dụng công cụ Robo3T để kết nối vào DB.
Tạo mới database. Trong dự án này thì mình đặt tên là fastify-store
Ngon rồi đấy!
Quay trở lại dự án, bạn mở index.js và thêm đoạn code kết nối tới DB.
const mongoose = require('mongoose') //setup DB const mongoUrl ="mongodb://127.0.0.1:27017/fastify-store" try { mongoose.connect(mongoUrl, { useNewUrlParser: true, useUnifiedTopology: true }) console.log("Database connected sucessfully"); } catch (error) { console.log(error); }
Lưu code lại và nhìn thấy dòng “Kết nối tới Database thành công
” trong màn hình console là được.
Tạo Book Model
Model là một class giúp chúng ta tương tác với database. Một instance của modal là một document.
Bạn tạo mới một file đặt tên là Book.js
// Book.js const mongoose = require('mongoose') const bookSchema = new mongoose.Schema({ title:{ type: String, required: true }, description:{ type: String, required: true }, genre: { type: String, required: true }, author: { type: String, }, price: { type: Number, required: true }, completed:{ type: Boolean, required: true } }); module.exports = mongoose.model('Book', bookSchema)
Mongoose sẽ tự động convert model thành một document trong Database.
Khởi tạo Routes và Controllers
Tương ứng với các tính năng CRUD, cụ thể: Xem, Thêm, sửa, xóa. Chúng ta sẽ định nghĩa các endpoint như sau:
GET, url: /api/books
– Trả về danh sách toàn bộ sách trong cơ sở dữ liệuGET, url: /api/book/:id
– Trả về một sách tương ứng với id truyền vàoPOST, url:/api/book
– Thêm một sách mớiPUT, url: /api/book/:id
– Cập nhật sách theo idDELETE, url: /api/book/:id
– Xóa một sách theo id
Chúng ta tạo mới một file router đặt tên là bookRoutes.js
// bookRoutes.js const bookController = require('./bookController'); const routes = [ { method: 'GET', url: '/api/books', handler: bookController.getAllBooks }, { method: 'GET', url: '/api/book/:id', handler: bookController.getSingleBook }, { method: 'POST', url: '/api/book', handler: bookController.addNewBook }, { method: 'PUT', url: '/api/book/:id', handler: bookController.updateBook }, { method: 'DELETE', url: '/api/book/:id', handler: bookController.deleteBook } ] module.exports = routes
Tương ứng với router là controller: bookController.js
// bookController.js const boom = require('boom') const Book = require('./Book'); // get all books exports.getAllBooks = async (req, reply) => { try { let books = await Book.find() return reply.code(200) .send( { Message: "Success", data: books } ) } catch (err) { throw boom.boomify(err) } } //get a single book by id exports.getSingleBook = async (req, reply) => { try { const id = req.params.id let book = await Book.findById(id) return reply.code(200) .send({ Message: "Success", data: book}, ) } catch (err) { throw boom.boomify(err) } } //add a new book exports.addNewBook = async (req, reply) => { try { let book = new Book(req.body); let newBook = await book.save() return reply.code(200) .send({ Message: "New Book added successfully", data: newBook}) } catch (err) { throw boom.boomify(err) } } //edit a book exports.updateBook = async (req, reply) => { try { const id = req.params.id let updatedBook = await Book.findByIdAndUpdate(id, req.body, { new: true }) return reply.code(200) .send({ Message: "Book updated successfully", data: updatedBook}); } catch (err) { throw boom.boomify(err) } } //delete a book exports.deleteBook = async (req, reply) => { try { const id = req.params.id let deletedBook = await Book.findByIdAndDelete(id); return reply.code(200) .send({ Message: `${deletedBook.title} has been deleted successfully`, data: id}) } catch (err) { throw boom.boomify(err) } }
Cuối cùng là thêm khai báo router trong index.js
... const routes = require("./bookRoutes") ... routes.forEach((route, index) => { fastify.route(route) }); ...
Server sẽ tự khởi động lại và chúng ta tiến hành test thôi nhỉ!
Test ứng dụng fastify với Postman
Đầu tiên là tạo mới và lưu một cuốn sách:
Xem danh sách toàn bộ sách trong database
Các bạn có thể tải toàn bộ mã nguồn minh họa trong bài viết tại đây:
Tạm kết
Qua bài viết này, chúng ta đã biết tới một fastify framework vô cùng mạnh mẽ, đặc biệt trong các dự án xây dựng REST API.
Fastify framework xứng đáng là một ứng cử viên nặng ký cho các dự án sắp tới của bạn. Mình tin là như vậy
Bạn đã sử dụng fastify cho dự án nào chưa? Đừng tiếc một bình luận bên dưới nhé!
Bài viết gốc được đăng tải tại vntalking.com
Có thể bạn quan tâm:
- List câu hỏi phỏng vấn NodeJS Developer hay và khó
- Một thủ thuật nhỏ để tối ưu code nodejs
- module.exports và exports trong NodeJS khác nhau như thế nào?
Xem thêm Việc làm IT hấp dẫn tại TopDev
- F Framework nào tốt nhất cho dự án của bạn? – Checklist chi tiết
- K Kinh nghiệm xử lý responsive table hiệu quả
- S Stackoverflow là gì? Bí kíp tận dụng Stack Overflow hiệu quả
- 7 7 kinh nghiệm hữu ích khi làm việc với GIT trong dự án
- B Bài tập Python từ cơ bản đến nâng cao (có lời giải)
- B Bảo mật API là gì? Một số nguyên tắc và kỹ thuật cần biết
- H Hướng dẫn cài đặt và tự học lập trình Python cơ bản từ A-Z
- C Chinh Phục Phân Tích Dữ Liệu Với Pandas Trong Python: Hướng Dẫn Từng Bước
- D Display CSS là gì? Cách khai báo và sử dụng thuộc tính display trong CSS
- C Compiler là gì? Công việc cụ thể của một trình biên dịch