Tự học Node.js cơ bản để đi phỏng vấn (13 bài) – 5 – Dự án giỏ hàng đơn giản

13 min


1105
2.1k shares, 1105 points

Hãy tưởng tượng công ty bạn tổ chức một cuộc họp và mời bạn tham gia. Khi bạn đến nơi, người quản lý dự án giải thích rằng một nhà bán lẻ lớn đã thuê công ty viết một bộ ứng dụng.

Khách hàng đã yêu cầu một ứng dụng mua sắm. Công ty của bạn bắt đầu dự án viết một sản phẩm khả thi tối thiểu (MVP) cho danh sách mua sắm, nhưng dev NodeJs đang làm việc với nó đột ngột rời công ty. 

Phân tích yêu cầu dự án

Phiên bản MVP bao gồm 10 User stories (US), do thời gian cực kỳ ngắn, mỗi US có mô tả ngắn gọn, cùng với một danh sách các yêu cầu phải được đáp ứng.

Các US được triển khai theo trình tự sau:

  1. Items: Tìm theo ID
    Mỗi item trong cơ sở dữ liệu có một ID duy nhất và người dùng có thể tìm thấy một item cụ thể trong cơ sở dữ liệu bằng ID của nó.
  2. Items: Tìm kiếm theo mô tả
    Mỗi item trong cơ sở dữ liệu có một mô tả và người dùng cần có thể tìm thấy một hoặc nhiều item bằng cách sử dụng một số từ khoá trong mô tả (chẳng hạn như “thuốc ho”, “vị chuối” hoặc “hàng miễn phí”). Đưa ra một chuỗi văn bản (mô tả một phần), hệ thống sẽ trả về 0 hoặc nhiều kết quả khớp với các mục trong cơ sở dữ liệu.
  3. Vật phẩm: Tìm theo mã sản phẩm
    Mỗi mặt hàng trong cơ sở dữ liệu có một mã sản phẩm (UPC) duy nhất và người dùng cần có thể tìm thấy một mặt hàng cụ thể trong cơ sở dữ liệu bằng UPC của nó. Truyền vào một UPC, hệ thống sẽ trả về một vật phẩm từ cơ sở dữ liệu khớp với UPC đó.
  4. Danh sách sản phẩm:
    Người dùng cần có khả năng tạo danh sách mua sắm mới. Hệ thống sẽ cung cấp cách tạo mới một danh sách mua sắm trong cơ sở dữ liệu với thuộc tính sau:
    • Sự miêu tả
  5. Tìm danh sách mua sắm theo ID,
    Chỉ trả về kết quả khi danh sách mua sắm đã được tạo, nó sẽ được gán một ID duy nhất. Người dùng cần có thể tìm thấy danh sách mua sắm trong cơ sở dữ liệu bằng ID đó.
  6. Thêm mặt hàng vào danh sách mua sắm
    Người dùng cần có thể thêm một mặt hàng vào danh sách mua sắm trong cơ sở dữ liệu cùng với thuộc tính sau:
    • Số lượng
  7. Tìm danh sách mua sắm theo ID,
    Trả lại tất cả các mặt hàng trong danh sách. Sau khi tạo danh sách mua sắm, danh sách đó sẽ được gán một ID duy nhất trong db cùng với tất cả sản phẩm trong danh sách đó.
  8. Cập nhật danh sách mua sắm:
    Người dùng cần có khả năng cập nhật các thuộc tính của sản phẩm trong giỏ hàng:
    • Số lượng
    • Thuộc tính.
  9. Xóa mặt hàng khỏi danh sách mua sắm
    Người dùng cần có thể xóa một mặt hàng khỏi giỏ hàng.

Testing

Đây là những gì bạn sẽ làm:

  1. Chạy bộ kiểm tra chức năng.
  2. Nếu bất kỳ bước nào không thành công:
    • Viết mã để triển khai chức năng trong câu chuyện tương ứng.
    • Quay lại Bước 1.
  3. Nếu tất cả các bước thành công:
    • Bạn đã hoàn tất.

Chạy thử nghiệm chức năng

Đầu tiên, tôi sẽ giải thích cho bạn cách chạy thử nghiệm chức năng. Bạn không cần phải làm điều này ngay bây giờ, nhưng tôi muốn giải thích cách nó hoạt động và nó trông như thế nào, để khi bạn chạy nó sau trong phần hướng dẫn, bạn sẽ hiểu nó hoạt động như thế nào.

Để chạy thử nghiệm chức năng, hãy lấy mã nguồn từ GitHub .

Chạy:

npm test

Cho xem nhiều hơn

Khi đầu ra trông như thế này, bạn đã hoàn thành:

$ npm test

1531086599944:INFO: testItemFindById(): TEST PASSED
1531086599982:INFO: testItemFindByDescription(): TEST PASSED
1531086599985:INFO: testListsCreate(): TEST PASSED
1531086599987:INFO: testListsAddItem(): TEST PASSED
1531086599988:INFO: testListsFindByIdWithAllItems(): TEST PASSED
1531086599989:INFO: testListsUpdate(): TEST PASSED
1531086599989:INFO: testListsUpdateItem(): TEST PASSED
1531086599989:INFO: testListsRemoveItem(): TEST PASSED
1531086599990:INFO: testListsFindById(): TEST PASSED
1531086599990:INFO: testItemFindByUpc(): TEST PASSED

Nếu một thử nghiệm thất bại, nó trông giống như thế này:

$ npm test


1531087259727:ERROR: testItemFindById(): TEST FAILED. Try again.
1531087259728:ERROR: testItemFindById(): ERROR MESSAGE: Unexpected token N in JSON at position 0.
.
.

Trong trường hợp đó, bạn cần viết mã để sửa lỗi kiểm thử và chạy lại kiểm thử chức năng.

Dữ liệu

Dữ liệu cho MVP của Danh sách mua sắm là từ Dự án cơ sở dữ liệu tạp hóa mở và được sử dụng miễn phí.

Dữ liệu từ Dự án cơ sở dữ liệu tạp hóa mở ở dạng hai bảng tính MS Excel:

  • Grocery_Brands_Database.xlsx chứa thông tin liên quan đến các thương hiệu trong cơ sở dữ liệu.
  • Grocery_UPC_Database.xlsx chứa thông tin cho từng mặt hàng (theo UPC) trong cơ sở dữ liệu.

Mỗi mục có một UPC duy nhất. Ngoài ra, mỗi mặt hàng chỉ được liên kết với một thương hiệu.

Cả hai bảng tính Excel đã được chuyển đổi thành tệp CSV. Các tệp đã được đặt cùng với các tệp CSV trong repo GitHub.

Dữ liệu sẽ được tải vào cơ sở dữ liệu SQLite ngay bây giờ. Mã để tạo và truy cập cơ sở dữ liệu đã được viết trước khi bạn tham gia dự án, vì vậy bạn chỉ cần lưu ý về mã này trong trường hợp gặp sự cố.

Data model

Mô hình dữ liệu bao gồm các table sau:

  • item : mặt hàng
  • brand : nhãn hàng
  • shopping_list : được sử dụng để lưu trữ dữ liệu danh sách mua sắm.
  • shopping_list_item: được sử dụng để lưu trữ thông tin về một mặt hàng đã được thêm vào danh sách mua sắm.

Mã để truy cập cơ sở dữ liệu nằm trong repo GitHub . 

  • items-dao-sqlite3.js là mã để truy cập cơ sở dữ liệu liên quan đến mặt hàng.
  • lists-dao-sqlite3.js là mã để truy cập cơ sở dữ liệu liên quan đến danh sách.

Để cách ly ứng dụng khỏi nguồn dữ liệu cơ bản, một lớp đối tượng truy cập dữ liệu (DAO) đã được khởi tạo, nhưng nó chưa hoàn thành:

  • items-dao.js là lớp hỗ trợ liên quan đến vật phẩm.
  • lists-dao.js là lớp hỗ trợ liên quan đến danh sách.

Application framework

Có một số hạn chế mà bạn nên biết:

  • Ứng dụng không thể sửa đổi dữ liệu của item hoặc brand.
  • Bạn chỉ có thể sử dụng Node.js “vanilla”, nghĩa là chỉ API Node.js và không có package nào khác từ npm. Một ngoại lệ là node-sqlite3 sẽ được cài đặt khi bạn chạy npm install.
  • Bạn phải triển khai backend bằng RESTful.

RESTful API

Có một service RESTful API cho mỗi user story và một chức năng DAO cho mỗi service RESTful. Chúng được tóm tắt trong bảng sau:

User storyHTTP methodĐường dẫn RESTfulfunction
Item: Tìm theo IdGET/items?id=123itemsDao.findById()
Item: Tìm kiếm theo mô tảGET/items?description=free rangeitemsDao.findByDescription()
Vật phẩm: Tìm theo mã sản phẩmGET/items?upc=123456789012itemsDao.findByUpc()
Danh sách: Tạo danh sách mua hàngPOST/listslistsDao.create()
Danh sách: Tìm danh sách mua hàng theo Id,GET/lists/123listsDao.findById()
Danh sách: Thêm mặt hàng vào danh sách mua sắmPOST/lists/123/itemslistsDao.addItem()
Danh sách: Tìm danh sách mua sắm theo Id, trả lại tất cả các mặt hàng trong danh sáchGET/lists/123/itemslistsDao.findByIdWithAllItems()
Danh sách: Cập nhật danh sách mua sắmPUT/lists/123listsDao.update()
Danh sách: Cập nhật mặt hàng trong danh sách mua sắmPUT/lists/123/items/567listsDao.updateItem()
Danh sách: Xóa mặt hàng khỏi danh sách mua sắmDELETE/lists/123/items/567listsDao.removeItem()

Mỗi đường dẫn RESTful được xử lý bởi một trong hai lớp:

  • Hạng mục: Xử lý trong file items-handler.js
  • Danh sách: Xử lý trong file lists-handler.js

Cấu trúc source code

Thư mục nguồn dự án chứa các file sau:

Hình 1. Các tập tin trong thư mục nguồn dự án

Tập tài liệu

Config

  • app-settings.js chứa các cài đặt ứng dụng trong một đối tượng được gọi là appSettings.

Controllers

Logic bộ điều khiển (kết hợp logic ứng dụng và Node) nằm trong thư mục controller:

  • items-handler.js gọi lớp DAO thay mặt cho bộ định tuyến ( routes.js) cho tất cả item routes.
  • lists-handler.js gọi lớp DAO thay mặt cho bộ định tuyến ( router.js) cho tất cả list routes.
  • routes.js gọi trình xử lý định tuyến thay mặt cho máy chủ HTTP REST ( server.js).

Bạn cần cung cấp code triển khai còn thiếu cho items-handler.js và lists-handler.js.

Data

Các tệp dữ liệu nằm trong thư mục dữ liệu:

  • Grocery_Brands_Database.csv chứa thông tin liên quan đến thương hiệu.
  • Grocery_UPC_Database.csv chứa thông tin liên quan đến các mặt hàng.

Models

Các DAO nằm trong thư mục models:

  • items-dao-sqlite3.js gọi cơ sở dữ liệu SQLite để lấy dữ liệu cho ứng dụng.
  • items-dao.js là lớp cách ly giữa ứng dụng và cơ sở dữ liệu SQLite.
  • lists-dao-sqlite3.js gọi cơ sở dữ liệu SQLite để lấy dữ liệu cho ứng dụng.
  • lists-dao.js là lớp cách ly giữa ứng dụng và cơ sở dữ liệu SQLite.

Bạn cần cung cấp code triển khai còn thiếu cho items-dao.js và lists-dao.js

Scripts

Các tập lệnh SQL nằm trong thư mục tập lệnh:

  • brand.sql là SQL để tạo bảng thương hiệu.
  • item.sql là SQL để tạo bảng mục.
  • shopping_list.sql là SQL để tạo bảng shopping_list.
  • shopping_list_item.sql là SQL để tạo bảng shopping_list_item.

Test

Các file liên quan đến thử nghiệm nằm trong thư mục test:

  • functional-test.js là bộ kiểm tra chức năng mà bạn nên chạy để xác thực mã của mình.
  • REST-Project-Unit6-soapui-project.xml là một dự án SoapUI để thử nghiệm dự án.
  • unit-test.js chứa tất cả các bài kiểm tra trong dự án.

Utils

Các tiện ích nằm trong thư mục utils. Tiện ích là các mô-đun cung cấp chức năng tiện ích:

  • load-db.js là mô-đun để tải cơ sở dữ liệu với dữ liệu từ Dự án cơ sở dữ liệu tạp hóa mở.
  • logger.js là mô-đun để đặt giao diện tốt hơn console.log với các cấp độ nhật ký, v.v.
  • utils.js chứa các tiện ích quá nhỏ so với mô-đun của chính chúng, nhưng hữu ích bên ngoài bất kỳ mô-đun cụ thể nào (chẳng hạn như phân tích cú pháp URL).

Thư mục gốc (root)

Có ba file trong thư mục gốc:

  • package-lock.json: Đừng lo lắng về tệp này bây giờ, chúng ta sẽ tìm hiểu chi tiết về nó trong bài sau.
  • package.json: khai báo thông tin và các package dùng trong dự án.
  • server.js: HTTP server front-end cho ứng dụng.

Trong phần tiếp theo, bạn sẽ bắt đầu và chạy, viết mã để pass tất cả các bài kiểm tra chức năng.

Tuy nhiên, có một vài điều bạn cần làm trước tiên. Chúng ta sẽ cùng nhau thực hiện các bước.

Bước 1. Thiết lập môi trường

Trước tiên, hãy đảm bảo rằng bạn đang sử dụng đúng phiên bản của Node và npm, tương ứng là 16 và 7:

node -v && npm -v

Bạn sẽ thấy đầu ra như thế này

$ node -v && npm -v
v16.13.0
v7.21.1

Để thiết lập môi trường của bạn, hãy điều hướng đến repo GitHub và chạy:

npm install

Điều này tạo ra một thư mục node_modules trong thư mục gốc. Nó chứa sqlite3 mô-đun và tất cả các phụ thuộc của nó. Đây là bắt buộc đối với Node.js.

Bây giờ bạn đã cài đặt sqlite3 mô-đun, bạn đã sẵn sàng thiết lập cơ sở dữ liệu cục bộ của mình.

Bước 2. Tải cơ sở dữ liệu SQLite cục bộ

Để thiết lập cơ sở dữ liệu cục bộ của bạn để thử nghiệm, bạn cần tải dữ liệu Dự án cơ sở dữ liệu tạp hóa mở vào cơ sở dữ liệu của mình. Mô-đun  load-db.js được viết cho mục đích này.

Để chạy mô-đun tải cơ sở dữ liệu, hãy chạy npm run load-db và bạn sẽ thấy kết quả như sau:

$ npm run load-db

> shopping-list@1.0.0 load-db /Users/sperry/home/development/projects/IBM-Code/Node.js/Course/Unit-6
> node ./utils/load-db

1531086312416:INFO: mainline(): Script start at: 7/8/2018, 4:45:12 PM
1531086312419:INFO: createDbFixtures(): Dropping all tables...
1531086312422:INFO: createDbFixtures(): Dropping all tables, done.
1531086312424:INFO: createDbFixtures(): Creating item table...
1531086312424:INFO: createDbFixtures(): Creating item table, done.
1531086312424:INFO: createDbFixtures(): Creating brand table...
1531086312424:INFO: createDbFixtures(): Creating brand table, done.
1531086312425:INFO: createDbFixtures(): Creating shopping_list table...
1531086312425:INFO: createDbFixtures(): Creating shopping_list table, done.
1531086312425:INFO: createDbFixtures(): Creating shopping_list_item table...
1531086312425:INFO: createDbFixtures(): Creating shopping_list_item table, done.
1531086312425:INFO: createDbFixtures(): DONE
1531086312425:INFO: mainline:createDbFixtures(resolved Promise): Loading data for brand...
1531086312426:INFO: loadData(): Loading data files...
1531086312427:INFO: loadData():readableStream.on(open): Opened file: ./data/Grocery_Brands_Database.csv
1531086320293:INFO: loadData():readableStream.on(close): Closed file: ./data/Grocery_Brands_Database.csv
1531086320293:INFO: mainline:createDbFixtures(resolved Promise): Loading brand data, done.
1531086320293:INFO: mainline:createDbFixtures(resolved Promise): Loading data for item...
1531086320293:INFO: loadData(): Loading data files...
1531086320293:INFO: loadData():readableStream.on(open): Opened file: ./data/Grocery_UPC_Database.csv
1531086433275:INFO: loadData():readableStream.on(close): Closed file: ./data/Grocery_UPC_Database.csv
1531086433275:INFO: mainline:createDbFixtures(resolved Promise): Loading item data, done.
1531086433275:INFO: mainline:createDbFixtures(resolvedPromise): Script finished at: 7/8/2018, 4:47:13 PM

Bây giờ dữ liệu được tải vào cơ sở dữ liệu SQLite cục bộ của bạn và bạn đã sẵn sàng để bắt đầu viết mã và thử nghiệm!

Bước 3. Khởi động Node (chế độ development )

Bất cứ lúc nào bạn cần kiểm tra ứng dụng, bạn phải khởi động máy chủ HTTP REST, nằm trong server.js, bằng cách chạy lệnh npm start. Nó sử dụng nodemon để tự động khởi động lại server bất cứ khi nào bạn thay đổi code:

$ npm run start-dev

> shopping-list@1.0.0 start-dev /Users/sperry/home/development/projects/IBM-Code/Node.js/Course/Unit-6
> nodemon server.js

[nodemon] 1.17.5
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `node server.js`
1531086509416:INFO: Database ./data/shopping-list.db is open for business!

Bước 4. Chạy bộ kiểm tra chức năng

Tiếp theo, chạy thử nghiệm chức năng của bạn bằng lệnh npm test.

Bộ kiểm tra chức năng sẽ thất bại lúc đầu. Nhiệm vụ của bạn là viết mã cho đến khi vượt qua tất cả các bài kiểm tra.

Bước 5. Viết mã

Bạn phải hoàn thành dự án bằng cách viết mã trong các mô-đun sau:

  • controllers/items-handler.js
  • controllers/lists-handler.js
  • models/items-dao.js
  • models/lists-dao.js

Sử dụng trình gỡ lỗi VSCode

Một trong những điều tôi thích ở VSCode là nó rất dễ sử dụng.

Điều tương tự cũng áp dụng cho việc debug với VSCode. Khi bạn đã tải dự án Bài 6 vào VSCode, bạn có thể dễ dàng gỡ lỗi:

  1. Mở server.js.
  2. Nhấp vào tab Debug.
  3. Đặt điểm ngắt – breakpoint (hoặc hai hoặc ba).
  4. Nhấp vào nút Run.

Hình 2. Khởi động ứng dụng MVP của Danh sách mua sắm trong VSCOde

Bắt đầu ứng dụng Danh sách mua sắm trong VSCode

Để đặt điểm dừng – braekpoint, hãy nhấp một lần vào bên trái của dòng mã mà bạn muốn trình gỡ lỗi dừng lại ( điểm màu đỏ trong hình )

Kiểm tra mã (ví dụ: chạy tập lệnh kiểm tra chức năng) và khi trình gỡ lỗi gặp một dòng có điểm ngắt được đặt trên đó, nó sẽ dừng lại. Sau đó, bạn có tất cả các loại thông tin trong tầm tay của bạn.

Hình 3. Trình gỡ lỗi VSCode Trình gỡ lỗi VSCode

Để biết thêm thông tin về trình gỡ lỗi VSCode, hãy xem trang Gỡ lỗi VSCode .

Phần kết luận

Trong hướng dẫn này, bạn đã làm việc trên ứng dụng Node.js trong dự án thực tế.

Bạn đã học:

  • Cách thiết lập môi trường của bạn để phát triển Node
  • Cách tải và làm việc với cơ sở dữ liệu SQLite
  • Cách khởi động Node và sử dụng nodemon
  • Cách làm việc với trình gỡ lỗi VSCode.

Trong một vài hướng dẫn tiếp theo, chúng ta quay lại quá trình phát triển Node và xem xét một số hệ sinh thái xung quanh, bao gồm npm và tệp điều khiển dự án Nodejs : package.json.


Like it? Share with your friends!

1105
2.1k shares, 1105 points

What's Your Reaction?

hate hate
0
hate
confused confused
0
confused
fail fail
0
fail
fun fun
1
fun
geeky geeky
0
geeky
love love
0
love
lol lol
1
lol
omg omg
1
omg
win win
1
win

0 Comments

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *