Chinh phục công nghệ: Nhóm anh tài NestJS lộ diện

Trong bối cảnh công ty đang liên tục đẩy mạnh mục tiêu đồng hành cùng business khách hàng thông qua hàng loạt giải pháp và sáng kiến sáng tạo, việc sẵn sàng học hỏi và linh hoạt công nghệ không còn là lựa chọn, mà đã trở thành một nhiệm vụ cấp thiết. Ở số thứ 2 của series “Chinh phục công nghệ”, hãy cùng khám phá bí kíp chinh phục framework tiếp theo - NestJS từ các cao nhân dày dạn kinh nghiệm thực chiến tại Sun*!

Khởi động số đầu tiên với Framework mobile “hot hit” Flutter, series "Chinh phục công nghệ" đã có một màn chào sân ấn tượng với sự hưởng ứng nồng nhiệt của các lập trình viên xứ sở mặt trời. Trong số tiếp theo, chúng ta sẽ tiếp tục đi sâu vào NestJS - Framework back-end đang “làm mưa làm gió” trên thị trường với quan điểm "không dễ - nhưng thú vị".

NestJS là framework chính thức trong Danh mục công nghệ chiến lược được Sun* công bố tại ấn phẩm Sun* Tech White Paper 2024. Được định hướng là một trong 35 thế mạnh công nghệ nổi trội tại Sun*, NestJS được các nhà phát triển tại đa dạng đơn vị CEV tìm hiểu, khai thác chuyên sâu và ứng dụng để đề xuất giải pháp cho khách hàng. Đối với các lập trình viên back-end, hiểu và sử dụng thành thục NestJS được xem là một trong những mục tiêu để ngày càng đa dạng năng lực công nghệ, tăng cường khả năng làm chủ sản phẩm và trở thành những “Người đồng hành đích thực” của business khách hàng.

Tổng quan về NestJS

NestJS là một framework được xây dựng trên nền tảng TypeScript, cung cấp các tính năng mạnh mẽ như Dependency Injection, kiến trúc module và khả năng mở rộng tốt. Khả năng hỗ trợ cho GraphQL và WebSocket cũng giúp NestJS nổi bật trong việc phát triển ứng dụng thời gian thực. Đặc biệt, NestJS đã nhanh chóng thu hút được sự chú ý của cộng đồng lập trình viên nhờ vào tính linh hoạt và hiệu suất vượt trội, cũng như khả năng tích hợp dễ dàng với các công nghệ khác như TypeORM và Mongoose.

Được ví von là framework “thần thánh” giải quyết "gót chân Asin" cho Nodejs, NestJS có những ưu/nhược điểm gì? Làm cách nào để “khắc chế” tất cả những lỗi thường gặp và sử dụng công cụ này hiệu quả? 

Hãy cùng Sun* News lắng nghe kinh nghiệm và góc nhìn thực chiến từ các “cao nhân” Sun* để có câu trả lời cho riêng mình nhé!

Văn Hoàng (CEV13): Với NestJS, tối ưu hóa không chỉ dừng lại ở cơ sở dữ liệu mà còn cần chú trọng đến cách sử dụng Middleware và Guards!

Văn Hoàng bắt đầu sự nghiệp tại Sun* với Ruby on Rails, sau đó nhanh chóng học và “nhảy” sang NestJS từ khi tham gia các dự án cần sử dụng framework này. 

NestJS là framework đầu tiên Hoàng tiếp cận khi bắt đầu với hệ sinh thái Node.js. Theo Hoàng, NestJS có một số lợi thế rõ rệt so với các Framework khác như ExpressJS bởi công nghệ này được phát triển dựa trên TypeScript ngay từ đầu. Thêm vào đó, NestJS còn cung cấp hệ thống Dependency Injection (DI) mạnh mẽ và sẵn có, giúp tổ chức mã nguồn dễ dàng và linh hoạt hơn.

Trong các dự án Hoàng đã tham gia suốt 3 năm thực chiến cùng NestJS, việc thiếu hiệu quả trong truy vấn cơ sở dữ liệu thường là nguyên nhân chính khiến ứng dụng chưa đạt hiệu suất tối ưu. Theo Hoàng:

  • Với NestJS, tối ưu hóa không chỉ dừng lại ở cơ sở dữ liệu mà còn cần chú trọng đến cách sử dụng Middleware và Guards.
  • Không nên áp dụng Middleware hoặc Guards một cách toàn cục (global) trừ khi thực sự cần thiết; thay vào đó, chỉ nên áp dụng cho các routes cụ thể để tránh làm giảm hiệu suất không đáng có.
  • Một số giải pháp  áp dụng để cải thiện hiệu năng: sử dụng indexes để tăng tốc độ truy vấn, phân trang (pagination) để giảm tải dữ liệu, và tránh vấn đề N+1 query – một lỗi phổ biến khiến hệ thống phải thực hiện quá nhiều truy vấn không cần thiết.
  • Trên môi trường production, hãy giới hạn độ dài của log và chỉ ghi log khi thật sự cần thiết, nhằm tránh gây lãng phí tài nguyên và ảnh hưởng đến tốc độ ứng dụng.

Đồng thời, anh còn chia sẻ thêm một vài chông gai khác và giải pháp xử lý hiệu quả nhất:

“Chông gai”Cách khắc chế

Sử dụng async/await không đúng cách: thêm từ khóa async vào các hàm mà không sử dụng await bên trong gây ra rò rỉ bộ nhớ (memory leak).

Đảm bảo tất cả các Promise đều được xử lý đúng cách, không để Promise bị bỏ qua hoặc không xử lý hoàn toàn.

Lưu trữ dữ liệu trực tiếp vào bộ nhớ (in-memory) khi làm việc với các file lớn hoặc tập dữ liệu lớn gây ra tình trạng bộ nhớ bị tiêu tốn quá mức, dẫn đến memory leak

Chuyển dữ liệu này sang các dịch vụ lưu trữ bên ngoài như Redis, vừa giúp giảm tải bộ nhớ, vừa cải thiện hiệu suất ứng dụng

Không quản lý kết nối cơ sở dữ liệu cẩn thận, khiến tài nguyên bị cạn kiệt theo thời gian

Luôn chú ý giải phóng các kết nối cơ sở dữ liệu sau khi hoàn thành tác vụ, giúp tối ưu hóa tài nguyên và tránh tình trạng ứng dụng bị treo do quá tải.

Khai báo một service nhiều lần trong Providers, dẫn đến việc tạo ra nhiều instance của cùng một service và gây lãng phí bộ nhớ không cần thiết

Mỗi service chỉ nên được khai báo một lần trong Provider, giúp tiết kiệm bộ nhớ và tăng hiệu suất hệ thống.

Trong bối cảnh AI ngày càng trở thành một yếu tố quan trọng trong phát triển phần mềm hiện đại, Hoàng đánh giá NestJS có tiềm năng lớn để phát triển và mở rộng khả năng hỗ trợ cho các công nghệ này. Để làm quen với NestJS nhanh chóng cho những người mới, Hoàng cho rằng các lập trình viên cần “nằm lòng” các bước sau:

  1. Bắt đầu với First Steps: Chạy ứng dụng "Hello World" theo hướng dẫn cơ bản từ tài liệu chính thức tại NestJS First Steps để làm quen với cách thức hoạt động của framework.
  2. Tìm hiểu Lifecycle của Request: Nghiên cứu kỹ về vòng đời của request trong NestJS. Tài liệu chi tiết về chủ đề này có sẵn tại Request Lifecycle.
  3. Thử một Awesome NestJS Boilerplate: Sử dụng một boilerplate NestJS đã được cộng đồng phát triển sẵn để tiết kiệm thời gian. Một boilerplate mà mình hay sử dụng là Awesome NestJS Boilerplate.
  4. Đọc kỹ tài liệu chính thức: Khi gặp vấn đề hoặc muốn khám phá thêm, hãy tham khảo tại NestJS Documentation. Đây là nguồn kiến thức rất giá trị giúp bạn giải quyết các khúc mắc và học thêm nhiều điều thú vị.

Văn Ngọc (CEV06): Các framework sẽ không chênh nhau quá nhiều về performance, quan trọng là cách bạn viết code!

Văn Ngọc (CEV06) đã có kinh nghiệm làm việc với PHP và Express.js, và sau đó trở thành một trong những người tiên phong đề xuất sử dụng NestJS cho khách hàng khi nhận thấy tiềm năng “vô tận” của framework này. 

"So với Express.js, NestJS có cấu trúc tốt hơn và hỗ trợ TypeScript mặc định, điều này giúp giảm thiểu lỗi trong quá trình phát triển. Khi nhận lời tham gia dự án J**, điều đầu tiên mình làm là đã đề xuất sử dụng NestJS vì nó đảm bảo tính mở rộng và dễ bảo trì," anh chia sẻ.

Trong dự án J** anh tham gia, mặc dù nhiều thành viên lần đầu sử dụng NestJS, nhưng nhờ cấu trúc rõ ràng, mọi người đã nhanh chóng làm quen. "Chất lượng code tốt và ít bug đã góp phần giúp dự án được đánh giá cao," Văn Ngọc cho biết.

Theo Ngọc, các framework sẽ không chênh nhau quá nhiều về performance, quan trọng là cách lập trình viên viết code. Ngọc thường tập trung vào việc tối ưu database, cache, và sử dụng các công cụ giám sát để theo dõi hiệu suất và coi đó là xuất phát điểm đầu tiên để tối ưu hiệu suất cho mọi tác vụ.

Lỗi về Dependency Injection được Văn Ngọc xem là một trong những “chông gai” thường gặp nhất khi mới sử dụng NestJS. Để giải quyết điều này, anh cho biết các lập trình viên cần chú trọng đọc kỹ tài liệu, nắm kiến thức nền, kiểm tra cấu trúc code, xem lại các module, provider và service để xác định lỗi.

Khi được hỏi về tiềm năng của NestJS, Ngọc khẳng định trong tương lai, NestJS sẽ phát triển mạnh mẽ hơn, hỗ trợ nhiều công nghệ mới, và trở thành một trong những framework phổ biến nhất.

Ngọc Khương (CEV12): Để thuần thục NestJS từ “hai bàn tay trắng”, không gì tốt hơn xung phong vào các dự án maintenance!

Với Ngọc Khương (CEV12), 3 năm thực chiến với NestJS đã giúp anh “lên tay” trông thấy, và bí kíp hàng đầu là tham gia vào các dự án maintenance tại Sun*. Đó cũng chính là xuất phát điểm đầu tiên của anh với NestJS.

"Lúc được add vào dự án thì mình cũng chỉ biết ExpressJS thôi, chưa hề vọc NestJS. Tài liệu https://docs.nestjs.com/ đã giúp mình tiết kiệm thời gian rất nhiều và mình đánh giá đây chính là document chỉn chu nhất về NestJS. Thực chiến là cách giúp bạn tiến lên với tốc độ thần tốc và nắm trong lòng bàn tay mọi framework", Khương chia sẻ.

Với kinh nghiệm chinh chiến cùng ExpressJS trước đó, Khương cho biết thực tế NestJS sử dụng ExpressJS làm default cho HTTP Server nên việc tiếp cận và sử dụng thư viện của framework này sẽ không khó với các Dev quen thuộc ExpressJS. Hoặc thậm chí Dev Java (Spring) vẫn cân được tất.

Theo Khương, các lỗi thường gặp làm giảm hiệu suất của ứng dụng thường không nằm ở NestJS, mà chủ yếu gây ra bởi những thư viện mà chúng ta tích hợp. 

“Ví dụ liên quan đến việc truy vấn, thao tác với DB, lập trình viên sẽ hay dùng TypeORM kết hợp với NestJS. Nếu không viết code tối ưu cho TypeORM thì sẽ “dính” ngay các issue liên quan đến performance” - Khương cho biết.

Một lưu ý cũng được Khương đề cao là cách sử dụng middleware, interceptor, pipe, exception handler...trong NestJS. Theo anh, các lập trình viên cần phải đảm bảo nắm lifecycle của NestJS để áp dụng những công cụ trên hiệu quả, để tránh mất thời gian debug khi đã “cài cắm” tools vào sản phẩm. "Đồng thời, anh em cũng nên tìm các project boilerplate để tham khảo. Giới thiệu với cả nhà 1 NestJS boilerplate mình đã dựng: Vndevteam NestJS Boilerplate, hy vọng hữu ích cho mọi người!" 

Đánh giá về tiềm năng của Framework này, Khương khẳng định: “Ít nhất trong 3 năm tới nó chưa bị thay thế đâu!” Tuy nhiên, anh cũng đề xuất thêm ngoài NestJS, hiện tại Bun là một JavaScript runtime đang nổi, nếu có một framework đủ tốt như NestJS xây dựng từ Bun thì có khả năng vượt mặt NestJS trong tương lai.

Thành Đạt (CEV03): NestJS tập trung giải quyết vấn đề kiến trúc nên nếu triển khai cho ứng dụng nhỏ trong thời gian ngắn - cần xem xét kỹ!

Thành Đạt (CEV03) đã bước vào “lãnh địa” của NestJS khi tham gia vào dự án J**S**. 

Sau hơn 3 năm sử dụng NestJS, những ưu và nhược điểm Đạt đúc rút được, có thể kể đến như: 

Ưu điểmNhược điểm
  • Ứng dụng được xây dựng bằng NestJS dễ test và dễ mở rộng hơn vì tính module hóa cao do framework sử dụng kiến trúc DI (dependency injection);
  • Dễ maintain hơn vì các ràng buộc lỏng lẻo. Khi maintain 1 dự án lớn sẽ ít bị tình trạng sửa ở module này mà impact sang module khác
  • Sử dụng Typescript nên giúp lập trình viên viết code tường minh hơn, giảm tỷ lệ mắc lỗi trong quá trình viết code.
  • Lúc mới tiếp cận thì có thể sẽ hơi khó nắm bắt đầy đủ các khái niệm của NestJS;
  • Vì NestJS tập trung giải quyết vấn đề kiến trúc nên nếu triển khai cho ứng dụng nhỏ và vừa trong thời gian ngắn khi chưa có kinh nghiệm với NestJS thì cần phải xem xét kỹ.

Với Đạt, cách tốt nhất để những lập trình viên “vọc” và học framework này chính là tham gia học một khóa trên Udemy. “Khi hiểu rõ bản chất và cách vận hành của NestJS, cũng như các khái niệm như Dependency Injection, Module và Controller, việc thực chiến không còn là nỗi lo nữa” - Đạt khẳng định.

Những chia sẻ từ các “cao nhân” đã mang lại cái nhìn sâu sắc về cách tối ưu hóa hiệu suất và vượt qua những thách thức phổ biến khi làm việc với NestJS. Ở số tiếp theo, bạn muốn lắng nghe chia sẻ về Framework nào? Để lại ý kiến cho Sun* News tại phần bình luận nhé!

#công nghệ

#Chinh Phục Công Nghệ

#TWP