22 points in apply web application framework [part 2]

22 quan điểm cần cân nhắc khi áp dụng web application framework Datetime hiện tại Production code Date time hiện tại thì có thể lấy thông tin 1 cách dễ dàng nhưng không vì thế mà chủ quan, Bắt buộc phải get thông tin “ngày giờ hiện tại” Test code Ở testcode thì trên thực

22 quan điểm cần cân nhắc khi áp dụng web application framework

Datetime hiện tại

Production code

Date time hiện tại thì có thể lấy thông tin 1 cách dễ dàng nhưng không vì thế mà chủ quan, Bắt buộc phải get thông tin “ngày giờ hiện tại”

Test code

Ở testcode thì trên thực tế thông tin ngày giờ nó cũng khá phiền phức, vì mỗi lần test là giá trị time này lại thay đổi, test sẽ không ổn định. Bởi vậy, thông thường khi test sẽ cố định date time hiện tại

Ví dụ bên Ruby có Timecop gọi là “gem”, có thể dễ dàng cố định datetime hiện tại.

Timecop.freeze(Time.new(2017,12,15,12,34,56))Time.now #=> 2017-12-15 12:34:56 +0900Timecop.return

Ngược lại, bên Java với trường hợp là các ngôn ngữ hệ JVM thì cần cơ chế replace Clock object khi test để có thể cố định được datetime hiện tại, cần phải dùng DI, định nghĩa wrapper class độc lập v.v..

Đây chỉ là vấn đề ngôn ngữ chứ không phải vấn đề framework, nên về cách cố định datetime hiện tại nên tìm ra giải pháp sớm.

Presentation

Định nghĩa routing và Thiết kế endpoint

Định nghĩa routing thì dễ bị confuse, nếu release 1 lần thì sau đó refactoring sẽ khó refactoring, nên chúng ta cần ý thức sâu sắc về tầm quan trọng của cấu trúc hóa.

Ngoài ra nếu thiết kế endpoint không có tính nhất quán thì có thể khiến hiểu lầm, các member trong team cần quyết sách hợp lý ngay từ đầu. Tham khảo thêm: Best practise of WebAPI designWeb API: The Good Parts.

Request param

Về cơ bản thì việc xử lý request parameter sẽ phụ thuộc vào framework. Nếu có cơ chế mapping với object Form tùy ý thì nhất định tôi cũng muốn được sử dụng. Vì cũng có nhiều framework chỉ mapping với hash đơn thuần, nên trong trường hợp đó cần mapping với object bằng tay.

Thêm đó, dù có sai sót gì thì cũng không được để nguyên hash cho nên với giai đoạn đầu thì nhàn dễ nhưng với những người vào sau lại không biết đã cấu trúc như nào lại phải mất nhiều thời gian để tìm hiểu code.

Validation

Cũng có framework thực hiện validation khi vĩnh viễn hóa database như Rails, nhưng framework gần đây thì có nhiều cái sẽ thực hiện validation bằng controller. Do phạm vi mà các gọi validation sẽ khác nhau tùy theo framework nên nhiệm vụ của validation cần thống nhất nhận thức trong team. Luận điểm của validation tham khảo Chương 9.1_Test của Design application architecture pattern.

Ngoài ra cũng cần làm rõ việc định nghĩa của validation sẽ viết vào đâu. Ý kiến cá nhân của thôi thì Validation sẽ định nghĩa Form object vào Presentation layer, còn cũng có nhiều người định nghĩa nó trong domain model.

Về hoạt động khi validation error, throw exception rồi throw exception handler thì implement sẽ dễ dàng hơn. Tuy nhiên, vì hơi rối nên phương châm là handling mỗi lần cũng được.

Response

Nếu chỉ trả về JSON thôi thì việc đưa object sẽ convert sang chuỗi ký tự JSON là nhanh chóng. Tuy nhiên, không convert y nguyên domain model. Domain model sẽ trở nên kết hợp chặt chẽ với View và domain model, domain model trở nên khó thay đổi. Cách làm này có vẻ phức tạp **nhưng cơ bản là nên chèn trước View. **

Trường hợp trả về HTML thì sẽ install template engine. Về template engine thì tùy theo từng cái mà cấu trúc khác nhau, khuyết điểm khác nhau. ít có thể thực hiện được nên sẽ kiểm chứng kỹ trước khi install. Ngoài ra, vì logic không được gọn gàng với template engine nên team hãy thống nhất nhận thức với nhau thật chỉn chu.

Setting application và Xử lý init

Module hóa

File setting và code init của application thường default là file độc lập. Tuy nhiên thường có cơ chế READ file riêng nên người ta vẫn hay chia tách file dựa theo vai trò. Lý do là việc Module hóa này thường bị coi nhẹ, việc chia nhỏ nhiều file thì về sau dễ thay đổi/update hơn.

Comment

Chúng ta phải bỏ tư tưởng “code sao cho người khác không cần đọc comment mà vẫn hiểu được”!
Để mà cho người sau đọc hiểu được thì chúng ta có thể dùng các comment, viết càng nhiều comment giải thích càng tốt.=
Về nội dung comment, viết được “mình đang code cái gì” và vì sao mình code vậy thì khi mình định sửa code sau này , các thông tin đó sẽ vô cùng có ích.

Định nghĩa build

JavaScript trước nay vẫn rất phức tạp, tuy nhiên đã là ngôn ngữ thì cái nào cũng sẽ có defactor standard nên chúng ta hãy sử dụng standard. Ví dụ như Java thì có Gradle , Scala thì có sbt.etc…

Định nghĩa library phụ thuộc

Bất kể ngôn ngữ/framework nào, việc định nghĩa library phụ thuộc là bắt buộc. Cách thức định nghĩa thì tra Google là ra ngay, point quan trọng nhất vẫn là lên chiến lược chỉ định repository quản lý và version up cho lib.

Policy quản lý

Giảm thiểu các thư viện phụ thuộc, vì nhiều thư viện mà bạn không biết mình đang sử dụng ở đâu sẽ phải chịu chi phí bảo trì lãng phí. Ngoài ra, nếu bạn cứ cố đẩy nó vào một cách tùy tiện, có nguy cơ phụ thuộc sẽ trở nên phức tạp và bạn sẽ không thể nâng cấp. Khi áp dụng library vào bạn cần test ngẫu nhiên và đưa ra quyết định cẩn thận

Chiến lược version up

Chỉ có 1 chiến lược version up duy nhất. Đó là version up thường xuyên. Nếu bạn coi việc version up là sự kiện gì đó đặc biệt thì vô hình trung sẽ tăng rào cản tâm lý, dần dần lại bỏ luôn việc thực hiện version up.

Module hóa và comment

Tươgng tự với file setting etc.. định nghĩa build cũng cần module hóa, nên bạn cũng comment càng nhiều càng tốt. Ngay cả OSS nổi tiếng cũng có hàng trăm dòng định nghĩa build không comment, nhưng bạn không cần phải bắt chước nó.

Database migration

Việc data migration có thể áp dụng các thứ được cung cấp framework standard, hoặc có thể áp dụng library thao tác đơn lập. Ở đây tôi xin giới thiệu 2 quan điểm, các bạn tùy ý tham khảo xem cái nào phù hợp với team của mình nhé.

DSL

Có nhiều công cụ migration có cung cấp DSL để support một cách minh bạch nhiều database. Ví dụ Active Record migration của Rails, có thể định nghĩa migration trên code Ruby

classCreateProducts<ActiveRecord::Migrationdefchange
    create_table :productsdo|t|
      t.string :name
      t.text :description
      t.timestamps
    endendend

Trong khi đó bên JavaのFlyway thì lại viết SQL.

CREATETABLE person(
  id INT(11)NOTNULL,
  name VARCHAR(100)NOTNULL,PRIMARYKEY(id));

Rollback

Nhiều công cụ di chuyển có cơ chế rollback, nhưng một số công cụ, chẳng hạn như Flyway, không có cơ chế rollback. Tôi không thích có incident trên product, vì vậy cá nhân tôi không cần chức năng rollback, nhưng nó cũng khá tiện lợi trong quá trình phát triển.

Nguồn: viblo.asia

Bài viết liên quan

WebP là gì? Hướng dẫn cách để chuyển hình ảnh jpg, png qua webp

WebP là gì? WebP là một định dạng ảnh hiện đại, được phát triển bởi Google

Điểm khác biệt giữa IPv4 và IPv6 là gì?

IPv4 và IPv6 là hai phiên bản của hệ thống địa chỉ Giao thức Internet (IP). IP l

Check nameservers của tên miền xem website trỏ đúng chưa

Tìm hiểu cách check nameservers của tên miền để xác định tên miền đó đang dùn

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ