Giới thiệu
Khi cố gắng tìm hiểu về web
phát triển, chúng tôi thường thấy rằng front-end dễ tiếp cận hơn đáng kể so với back-end. Có nhiều lý do cho điều này, đặc biệt là cảm giác phản hồi tức thì đến từ việc thay đổi một thành phần nhất định của trang trong mã và nhận thấy thay đổi đang được áp dụng cho trang web. Phản hồi này thường hữu ích cho người mới bắt đầu vì nó cho phép họ điều chỉnh mã và học hỏi từ những sai lầm của mình. Thật không may, phần phụ trợ lại không như vậy: đôi khi, một lượng công việc đáng kể được dành cho việc thiết lập trước môi trường và cài đặt các phần phụ thuộc cần thiết để thông báo “Hello World” đơn giản xuất hiện trên thiết bị đầu cuối., rất nhiều tiến bộ liên tục được thực hiện trong cộng đồng nguồn mở nhằm tạo điều kiện thuận lợi cho quá trình phát triển các framework và cải thiện trải nghiệm của nhà phát triển NodeJ là một ví dụ điển hình về điều này. mã bằng Javascript một cách thuận tiện, đồng thời cung cấp nhiều công cụ và tính năng tích hợp giúp phân biệt nó với các đối thủ cạnh tranh. Trong bài viết này, chúng ta sẽ khám phá NodeJ và hệ sinh thái của nó, bằng cách tiếp cận thực hành, xây dựng một dự án đầy đủ chức năng.
Chúng ta sẽ xây dựng cái gì?
Các ứng dụng ToDo là một dự án phù hợp dành cho những người mới bắt đầu học phát triển front-end. Đây là lý do tại sao chúng tôi quyết định xây dựng API danh sách Todo. Điều này sẽ cho phép chúng tôi thêm tính lưu giữ dữ liệu vào giao diện của mình và cung cấp cho chúng tôi khả năng thao tác dữ liệu này (bằng cách thêm, cập nhật, xóa việc cần làm, v.v.).
Bạn có thể tìm thấy mã cuối cùng tại đây.
Công cụ của chúng tôi
Chúng tôi sẽ sử dụng ngăn xếp công nghệ đơn giản hóa cho dự án này. Nó có thể được coi là phiên bản tối thiểu của rất nhiều công cụ bạn sẽ tìm thấy trong các dự án thực tế, lý do là các ý tưởng cấp cao hơn đều giống nhau. Các chi tiết về việc triển khai và lựa chọn một công cụ cụ thể thay vì một công cụ khác không quan trọng để bắt đầu.
-
NodeJs, như chúng tôi đã đề cập, là một trong những framework Javascript phổ biến nhất để xây dựng các ứng dụng phía máy chủ.
-
ExpressJs là một framework Javascript tối thiểu được sử dụng trên NodeJS. Nó tăng tốc quá trình phát triển bằng cách sử dụng nhiều tính năng tích hợp. Nó cũng được sử dụng như một cách để tiêu chuẩn hóa các hoạt động phát triển trong các dự án NodeJS nhằm tạo điều kiện thuận lợi cho các kỹ sư sử dụng.
-
LowDB là một cơ sở dữ liệu trong bộ nhớ đơn giản. Tính đơn giản của nó cho phép chúng tôi trình bày cách tương tác với cơ sở dữ liệu trong dự án NodeJs mà không cần xử lý các chủ đề nâng cao hơn như triển khai và cấu hình.
Bây giờ chúng ta đã xác định được tất cả các công cụ mà chúng ta sẽ sử dụng, hãy truy cập bàn phím và bắt đầu viết mã!
Cài đặt
Nút có sẵn trên tất cả các nền tảng. Bạn có thể tìm thấy tất cả hướng dẫn cài đặt trên trang web chính thức. Người dùng Windows phải đảm bảo thêm nút đường dẫn đến biến môi trường để có thể sử dụng nút này trên dòng lệnh.
Chúng tôi cũng sẽ cần cài đặt npm. Npm là trình quản lý gói tiêu chuẩn cho NodeJ. Nó sẽ cho phép chúng tôi quản lý các phần phụ thuộc của dự án. Bạn có thể tìm thấy hướng dẫn cài đặt tại đây.
Khởi tạo dự án
Đi tới liên kết và sao chép dự án khởi đầu:
Đây là kho lưu trữ khởi đầu đơn giản cho dự án của chúng tôi. Nó chứa tất cả các phần phụ thuộc mà chúng tôi sẽ sử dụng cùng với cấu trúc tệp dự án. Chúng tôi sẽ giải thích từng yếu tố một khi đạt được. Mở terminal của bạn, điều hướng đến đường dẫn của dự án và chạy lệnh:
npm install
Thao tác này sẽ cài đặt tất cả các phần phụ thuộc của dự án được chỉ định trong tệp pack.json. pack.json là tệp được tìm thấy ở thư mục gốc của bất kỳ dự án Javascript/NodeJs nào, nó chứa siêu dữ liệu về dự án sau và được sử dụng để quản lý tất cả các phần phụ thuộc, tập lệnh và phiên bản của dự án.
Sau khi tất cả các phụ thuộc được cài đặt, chúng ta có thể khởi động ứng dụng của mình:
npm run start
“bắt đầu” là một tập lệnh mà chúng tôi đã chỉ định trong gói. tập tin json. Nó chỉ định tệp nhập vào ứng dụng của chúng tôi, trong trường hợp của chúng tôi là app.js.
Thông báo sau sẽ xuất hiện trong terminal của bạn:
Điều này có nghĩa là máy chủ của chúng tôi đã khởi động thành công và đang lắng nghe mọi yêu cầu được gửi tới cổng 3000. Hãy xem app.js và giải thích điều gì đang xảy ra ở đây:
App.js là tệp đầu vào dự án của chúng tôi (và là tệp duy nhất tại thời điểm này). Chúng tôi khởi tạo một ứng dụng nhanh có tên là ứng dụng, chỉ định rằng tất cả các yêu cầu có phương thức http “GET” và đường dẫn con '/' sẽ được xử lý theo tuyến này, chuyển vào một hàm gọi là phần mềm trung gian, nhận đối tượng yêu cầu và phản hồi dưới dạng các thông số. Điều này rất quan trọng vì yêu cầu chứa tất cả thông tin cần thiết để xử lý nó (tham số, nội dung yêu cầu, tiêu đề yêu cầu, v.v.) và đối tượng phản hồi là đối tượng sẽ được trả về máy khách. Chúng tôi bắt đầu bằng việc gửi tin nhắn “Xin chào thế giới”. Sau đó, chúng tôi làm cho ứng dụng của mình lắng nghe mọi yêu cầu đến cổng được chỉ định (trong trường hợp của chúng tôi là 3000) và ghi thông báo “Đang nghe cổng 3000” để cho biết rằng ứng dụng của chúng tôi đã hoạt động và sẵn sàng nhận yêu cầu.
Mở terminal của bạn và trong thanh liên kết gõ “localhost:3000/”, rồi nhấn Enter. Đây là đường dẫn được chỉ định mà chúng tôi có thể sử dụng để truy cập máy chủ của mình cục bộ. Bạn sẽ nhận được thông báo sau:
Cấu hình cơ sở dữ liệu
Lowdb là cơ sở dữ liệu nguồn mở dễ sử dụng và không yêu cầu thiết lập cụ thể. Ý tưởng chung đằng sau nó là lưu trữ tất cả dữ liệu trong tệp json cục bộ. Sau khi cài đặt LowDB (điều này đã được thực hiện khi chúng tôi cài đặt tất cả các phần phụ thuộc), chúng tôi có thể thêm đoạn mã sau vào db.js:
Mã này khá giống với mã được tìm thấy trên tài liệu chính thức của LowDB. Chúng tôi đã điều chỉnh nó một chút cho trường hợp sử dụng của riêng mình. Hãy giải thích từng dòng một:
Một số dòng đầu tiên dùng để nhập các phụ thuộc cần thiết. “tham gia” là một chức năng tiện ích có sẵn trong mô-đun “đường dẫn”. Đây là một trong những mô-đun cốt lõi của NodeJ cung cấp rất nhiều phương thức để xử lý và xử lý các đường dẫn. “Low” và “JSONFile'' là hai lớp được LowDB thể hiện. Cái đầu tiên tạo phiên bản tệp json sẽ chứa dữ liệu của chúng tôi. Cái thứ hai tạo phiên bản cơ sở dữ liệu thực tế sẽ hoạt động theo nó. Cuối cùng, “lodash” là một trong những thư viện javascript được sử dụng nhiều nhất, cung cấp nhiều chức năng tiện ích cho các tác vụ lập trình thông thường. Chúng tôi thêm nó vào phiên bản cơ sở dữ liệu của mình để cho phép chúng tôi sử dụng các phương pháp nâng cao của nó để xử lý dữ liệu của mình.
Đầu tiên, chúng ta chỉ định đường dẫn cho tệp db.json. Đó là tệp sẽ chứa dữ liệu của chúng tôi và được chuyển đến LowDB. Nếu không tìm thấy tệp ở đường dẫn đã chỉ định, LowDB sẽ tạo một tệp.
Sau đó, chúng tôi chuyển đường dẫn tệp tới bộ điều hợp LowDB và chuyển nó sang phiên bản cơ sở dữ liệu LowDB mới của chúng tôi. Sau đó, biến “db” có thể được sử dụng để liên lạc với cơ sở dữ liệu của chúng tôi. Sau khi phiên bản cơ sở dữ liệu được tạo, chúng tôi đọc từ tệp json bằng cách sử dụng db.read(). Điều này sẽ đặt trường “dữ liệu” trong phiên bản cơ sở dữ liệu của chúng tôi để chúng tôi có thể truy cập nội dung cơ sở dữ liệu. Lưu ý rằng chúng ta đặt trước dòng này bằng từ “await”. Điều này nhằm xác định rằng lệnh này có thể mất một khoảng thời gian không xác định để giải quyết và quy trình NodeJ phải chờ thực thi trước khi tiếp tục với phần còn lại của mã. Chúng tôi thực hiện điều này vì thao tác đọc yêu cầu quyền truy cập bộ nhớ vào tệp đã chỉ định và thời gian để thực hiện loại thao tác này tùy thuộc vào thông số kỹ thuật máy của bạn.
Bây giờ chúng ta có quyền truy cập vào trường dữ liệu, chúng ta đặt nó làm đối tượng chứa một mảng bài đăng trống, hay nói đúng hơn là chúng ta kiểm tra xem tệp có chứa bất kỳ dữ liệu nào trước đó hay không và đặt mảng trống nếu không phải như vậy.
Cuối cùng, chúng ta thực thi db.write() để áp dụng các sửa đổi mà chúng ta đã thực hiện cho dữ liệu và xuất phiên bản cơ sở dữ liệu để nó có thể được sử dụng trong các tệp khác trong dự án của chúng ta.
Quy trình làm việc Yêu cầu/Phản hồi chung
Hãy xem xét sơ đồ sau:
Nó cho thấy kiến trúc chung được áp dụng trong rất nhiều ứng dụng phụ trợ được xây dựng bằng NodeJs/Express. Hiểu quy trình làm việc chung đằng sau việc xử lý yêu cầu sẽ không chỉ cho phép bạn xây dựng và cấu trúc các ứng dụng NodeJ mà còn cho phép bạn chuyển các khái niệm này sang bất kỳ nhóm kỹ thuật nào mà bạn chọn trên thực tế. Chúng tôi sẽ khám phá các lớp khác nhau can thiệp vào quá trình này và giải thích vai trò của chúng:
## Lớp yêu cầu HTTP
Đây là lớp đầu tiên trong ứng dụng của chúng ta, hãy tưởng tượng nó như một cổng nhận nhiều yêu cầu khác nhau đến từ các máy khách khác nhau, sau đó mỗi yêu cầu sẽ được phân tích và chuyển tiếp đến phần chuyên dụng của ứng dụng để xử lý.
-
Bộ định tuyến: ở đây chúng ta đang đề cập đến bộ định tuyến Express, nhưng khái niệm này có thể được tìm thấy trong nhiều khung phụ trợ. Bộ định tuyến là một cách để áp dụng phân phối logic trong logic kinh doanh cho mã của chúng tôi, nghĩa là mỗi bộ phần tử có chung các tính năng tương tự đều được xử lý bởi cùng một mục nhập và có thể tách biệt khỏi phần còn lại của bộ. Điều này có lợi ích là làm cho mỗi thành phần của mã trở nên độc lập với các thành phần khác và dễ bảo trì và mở rộng hơn. Cụ thể hơn và làm ví dụ, tất cả các yêu cầu đáp ứng các điều kiện của đường dẫn url chia sẻ “/posts” sẽ được xử lý bởi cùng một bộ định tuyến. Tùy thuộc vào phương thức http của họ (GET, POST, v.v.), một bộ điều khiển khác sẽ được sử dụng.
-
Bộ điều khiển: bộ điều khiển nhận các yêu cầu được lọc từ bộ định tuyến, áp dụng xử lý bổ sung và gọi các phương thức dịch vụ phù hợp.
Lớp logic nghiệp vụ
Lớp này là duy nhất tùy thuộc vào trường hợp sử dụng cụ thể của ứng dụng và logic nghiệp vụ đằng sau nó.
-
Dịch vụ: Dịch vụ là tập hợp các phương thức chứa logic cốt lõi của ứng dụng. Họ cũng tương tác với cơ sở dữ liệu thông qua việc sử dụng ORM/ODM.).
-
Dịch vụ của bên thứ ba: nhiều ứng dụng hiện đại chọn ủy quyền một phần logic của ứng dụng cho các dịch vụ chuyên dụng có thể truy cập thông qua API. Các dịch vụ thuộc loại này có thể là dịch vụ xử lý thanh toán, lưu trữ tệp tĩnh, thông báo và các dịch vụ khác.
-
ODM/ORM: ORM và ODM đóng vai trò trung gian giữa dịch vụ và cơ sở dữ liệu. Vai trò của họ là cung cấp khả năng trừu tượng hóa cấp cao trên cơ sở dữ liệu cho phép nhà phát triển viết mã bằng ngôn ngữ lập trình mà họ lựa chọn thay vì các ngôn ngữ cơ sở dữ liệu chuyên dụng, chẳng hạn như SQL.
Lớp lưu giữ dữ liệu
- Cơ sở dữ liệu: như chúng tôi đã đề cập trước đó, hầu hết tất cả các ứng dụng đều cần một số hình thức lưu giữ dữ liệu. Phần này được xử lý bởi cơ sở dữ liệu và tùy thuộc vào bản chất của dữ liệu, logic nghiệp vụ và nhiều cân nhắc khác, việc lựa chọn một cơ sở dữ liệu nhất định thay vì cơ sở dữ liệu khác được coi là rất quan trọng đối với hiệu quả và khả năng mở rộng của ứng dụng.
Ví dụ: Thêm bài viết
Bây giờ chúng ta đã hiểu ý tưởng chung đằng sau kiến trúc, hãy áp dụng nó vào ví dụ đơn giản của chúng ta. Chúng tôi sẽ triển khai tính năng thêm bài đăng việc cần làm vào ứng dụng của mình. Giả sử rằng bất kỳ bài đăng nào cũng có một id duy nhất sẽ cho phép chúng tôi xác định nó sau này trong cơ sở dữ liệu của chúng tôi, tiêu đề là một chuỗi và thứ tự có kiểu số nguyên. Theo sơ đồ của chúng tôi, chúng tôi sẽ bắt đầu bằng cách triển khai bộ định tuyến. Thêm mã sau vào tệp index.js:
Đây là tập tin bộ định tuyến của chúng tôi. Chúng tôi nhập phương thức express và “addPost” từ bộ điều khiển của mình (chúng tôi sẽ sớm triển khai phương thức này), tạo một phiên bản của bộ định tuyến tốc hành và liên kết phương thức addPost với bộ định tuyến của chúng tôi - nghĩa là đối với mỗi yêu cầu có đường dẫn gốc và http phương thức “POST”, phương thức “addPost” sẽ được gọi để xử lý nó.
Trước khi triển khai phương thức của mình trong bộ điều khiển, chúng tôi tham chiếu bộ định tuyến mới trong tệp app.js chính của mình và chỉ định đường dẫn của nó là “/posts”: Tất cả các tuyến có đường dẫn được chỉ định sẽ được chuyển tiếp đến bộ định tuyến này, vì vậy nó có thể được xử lý bằng các phương pháp điều khiển khác nhau:
Chúng tôi nhập bộ định tuyến và đặt tên nó là “bài viết”. app.use(“/posts”,..) có nghĩa là tất cả các yêu cầu có đường dẫn phụ “/posts”, bất kể phương thức http của chúng, sẽ được chuyển đến bộ định tuyến được chỉ định.
Các thay đổi khác đối với app.js bao gồm nhập tệp cấu hình cơ sở dữ liệu để thực thi tệp đó và sử dụng express.json() làm phần mềm trung gian để cho phép chúng tôi truy cập vào đối tượng nội dung yêu cầu.
Bây giờ các tuyến đường của chúng ta đã được thiết lập, chúng ta có thể thêm phương thức “addPost” vào tệp control.js:
“addPost” là một hàm phần mềm trung gian lấy làm tham số cho các đối tượng yêu cầu, phản hồi và hàm tiếp theo. Khi hàm tiếp theo được gọi, tiến trình sẽ chuyển sang phần mềm trung gian tiếp theo trong chuỗi hoặc kết thúc yêu cầu. Trong mã của phương thức, chúng tôi trích xuất tiêu đề và thứ tự từ phần nội dung yêu cầu và chuyển chúng dưới dạng tham số cho hàm dịch vụ “createPost”. Hàm này lấy các thuộc tính của bài đăng, tạo một bài đăng mới và trả về nó. Khi bài đăng mới được tạo, chúng tôi sẽ trả lại cho khách hàng cùng với mã trạng thái 200, nghĩa là yêu cầu đã thành công. Bạn có thể nhận thấy rằng mã của chúng tôi được đặt bên trong khối try/catch để phát hiện bất kỳ lỗi không mong muốn nào và chuyển nó sang phần mềm trung gian tiếp theo. Cách tốt nhất được coi là gắn vào tất cả các bộ định tuyến một phần mềm trung gian xử lý lỗi để khắc phục lỗi và trả về thông báo lỗi có ý nghĩa cho máy khách.
Tất cả những gì còn lại bây giờ là triển khai hàm “createPost” trong service.js:
Như chúng tôi đã đề cập trước đó khi giải thích các lớp khác nhau của kiến trúc, lớp dịch vụ tương tác với giải pháp lưu trữ dữ liệu thông qua việc sử dụng ORM/ODM. Tuy nhiên, trong ví dụ của chúng tôi, chúng tôi sẽ không cần sử dụng ORM riêng vì Lowdb có hỗ trợ Javascript tích hợp. Bạn có thể tìm thấy tất cả thông tin chi tiết về cú pháp của nó trong tài liệu.
Phương thức “createPost” nhận tiêu đề và thứ tự làm tham số và sử dụng chúng để tạo đối tượng bài đăng. Đối với id duy nhất, chúng tôi sử dụng thư viện chuyên dụng có tên là “nanoid”, tạo ra một chuỗi ký tự duy nhất. Chúng tôi thêm bài đăng mới vào mảng bài đăng trong cơ sở dữ liệu và ghi những thay đổi này; bài viết mới sau đó được trả về bởi hàm.
Bây giờ “createPost” đã sẵn sàng, tính năng thêm bài đăng hiện đã hoàn tất và đang chạy. Chúng tôi kiểm tra nó bằng Postman, một công cụ phổ biến để kiểm tra API:
Chúng tôi chọn “POST” làm phương thức http cho yêu cầu cùng với đường dẫn url được chỉ định “localhost:3000/posts”. Chúng tôi thêm tiêu đề và thứ tự ở định dạng json trong phần nội dung và gửi yêu cầu. Như hình trên chúng ta nhận được trạng thái 200 OK cùng với bài viết mới tạo.
Phần kết luận
Rất nhiều khái niệm và ý tưởng đã được khám phá trong dự án này: Chúng tôi đã đề cập đến cách cài đặt và thiết lập môi trường dự án của mình, tìm hiểu cách định cấu hình LowDB để duy trì dữ liệu cục bộ, khám phá kiến trúc chung của các ứng dụng phụ trợ NodeJS/Express và xem cách áp dụng nó trong một ví dụ đơn giản. Cuối cùng, chúng tôi đã thử nghiệm ứng dụng của mình bằng Postman.
Mục đích ở đây là đưa ra một phiên bản đơn giản hóa của tất cả những gì dùng để xây dựng các ứng dụng phụ trợ hiện đại. Như chúng ta đã thấy trước đó, NodeJs là một công cụ mạnh mẽ cho phép chúng ta xây dựng các API đơn giản và phức tạp. Kết hợp với hệ sinh thái khung phong phú, chẳng hạn như express và vô số công cụ cũng như thư viện dành cho mọi trường hợp sử dụng, đây là một giải pháp hợp pháp để phát triển chương trình phụ trợ hiện đại - một giải pháp mà chúng tôi khuyên bạn nên tìm hiểu và nắm vững.