RESTful với JavaLite và MySQL / SQLite

Doko
Administrator#
1. Giới thiệuJavaLite là một bộ frameworks (gồm nhiều framework con) dùng để đơn giản hóa một số tác vụ, đầu việc thường làm khi phát triển ứng dụng, thường là web. Bài hướng dẫn sau đây tập trung vào việc tạo một ứng dụng Restful với MySQL / SQLite.
#
2. Cài đặtChúng ta vẫn sẽ bắt đầu với một project chạy trên maven bình thường, và 2 thứ chúng ta sẽ dùng là ActiveWeb và ActiveJDBC, 2 framework con mà JavaLite tích hợp.
Do ActiveWeb
đã bao gồm ActiveJDBC
nên chúng ta sẽ không cần cái thứ 2, phiên bản mới nhất của ActiveWeb
có thể lên MavenCentral tìm.
Tiếp theo, chúng ta cần một connector (bộ kết nối) với MySQL (SQLite thì không cần, sẽ cài sau):
Và tiếp theo là một plugin cho JavaLite: Instrumentation
:
Sau khi đã có đủ đồ chơi, chúng ta cần chắc rằng có một DB nào đó đang chạy, trong ví dụ này là MySQL hoặc SQLite.
#
3. ORM#
3.1. Mapping và InstrumentationTa sẽ bắt đầu với bài tập truyền thống là làm 1 cái backend REST cho web bán hàng. Và để bán hàng thì đầu tiên cần có sản phẩm:
Tiếp theo, tạo bảng, chạy lệnh SQL:
và sau đó ta có thể biến cái Product kia thành model:
Cái hay ở đây là gì? Là chúng ta chỉ cần extend cái org.javalite.activejdbc.Model
. ActiveJDBC
tự đọc schema từ DB, do đó chúng ta không cần phải viết thêm getter setter gì cả.
Hơn thế nữa, ActiveJDBC
tự biết map cái model Product kia vào bảng PRODUCTS
luôn (dù có để số nhiều hay số ít theo tiếng Anh).
Cuối cùng là chạy Instrumentation
, đây là một bước mà ActiveJDBC
yêu cầu, để sinh code dạng getter setter cho các model. Chúng ta không cần làm gì thêm vì ở bước trên đã có plugin instrumentation
rồi. Khi chạy thì ở terminal sẽ hiện dạng như này:
Tiếp theo chúng ta sẽ chạy thử:
#
3.2. TestCách test thử rất đơn giản: Tạo kết nối đến database, tạo 1 product, và get nó về lại:
Vậy là chỉ cần 1 plugin và 1 model rỗng, chúng ta có thể có được những thứ như trên trong nháy mắt.
Tiếp theo, đến lượt controller, vì đơn giản là cần controller/routing thì mới gửi request được:
#
4. ControllerMở đầu với ProductsController
như sau:
Với đoạn code trên, ActiveWeb sẽ tự map thành địa chỉ như sau:
Các controller có annotation @Restful
sẽ tự động được đánh thêm các method như trong bảng:
Phương thức | Tên trong Java | Kiểu | URI |
---|---|---|---|
CREATE | create() | POST | http://host:port/products |
READ ONE | show() | GET | http://host:port/products/{id} |
READ ALL | index() | GET | http://host:port/products/ |
UPDATE | update() | PUT | http://host:port/products/{id} |
DELETE | delete() | DELETE | http://host:port/products/{id} |
Và nếu như thêm đầy đủ thì nó trông như này:
Chạy thôi... mà khoan. Trước khi chạy tiếp, chúng ta cần phải có thêm một bước cài đặt cho project.
#
5. ConfigActiveWeb là framework dựa trên tư tưởng convention over configuration, tức là cứ sắp xếp đúng theo nó muốn, là chạy được. Do đó, các file code cũng phải được sắp xếp theo mẫu như sau:
Trong package java.app.config
, chúng ta sẽ tạo 3 class:
Class trên sẽ tự động config kết nối với database, với thông tin lấy từ file database.properties
nằm trong thư mục gốc của project:
Class thứ hai cần tạo là AppControllerConfig
Class trên sẽ gán kết nối database mà ta đã tạo với controller tương ứng.
Class thứ 3 sẽ là class điều chỉnh context của app, cũng là class đảm nhiệm việc bootstrap ứng dụng:
Sau khi tạo xong 3 class, chúng ta cần 1 file config tên là web.xml ở ngoài (vì ActiveWeb
cũng dựa trên Java EE mà thôi):
Sau khi xong xuôi, ta sẽ bắt đầu thêm code logic chính cho CRUD dữ liệu.
#
6. Xử lý CRUDActiveWeb, phần nào như tên gọi, cũng sử dụng dạng tham chiếu dữ liệu ActiveRecord (thay vì datamapper như Spring), phù hợp với các dự án vừa và nhỏ. Sau đây là ví dụ CRUD cho cái Product đã tạo:
Nếu copy paste đoạn code trên, hiển nhiên là nó chưa trả về gì cả, mà chúng ta sẽ phải xử lý các view của ActiveWeb ngay sau đây.
#
7. ViewActiveWeb tích hợp Apache FreeMarker, một template engine cho việc hiển thị view. Đường dẫn chứa các view phải được đặt trong src/main/webapp/WEB-INF/views
Các view tương ứng sẽ được đặt vào folder con tương ứng. Trong ví dụ này là src/main/webapp/WEB-INF/views/products
. Giờ chúng ta sẽ tạo template đầu tiên có tên _product.ftl
:
Ta có thể nhận ra cái view này chính là một dạng json. Tuy nhiên dữ liệu trả về khi truy vấn product lại là dạng mảng, vậy nên sẽ cần một file nữa tên index.ftl
:
Và thế là chúng ta có được một array json, mỗi phần tử là một Product, định dạng bởi file _product.ftl
.
Cuối cùng, chúng ta cần gán dữ liệu từ controller đến view tương ứng:
Dễ thấy ở đây có 2 cái là index()
và show()
. Ở phương thức đầu tiên, chúng ta gán danh sách product cho template có tên products
.
Tiếp đó, do không để tên view ở hàm render, file index.ftl
sẽ được sử dụng.
Ở show()
, chúng ta gán trực tiếp product p cho phần tử product trong view, và chỉ định rõ luôn view nào render cái đó.
Ngoài ra chúng ta có thể thêm message.ftl
, dùng cho hiển thị các thông báo chung:
Sau đó gọi ra từ bất kì phương thức nào trong class ProductsController:
Class ProductsController.java
sẽ đầy đủ như sau:
Lúc này chương trình đã hoàn thành và có thể chạy thử:
#
8. Chạy thửTrước khi chạy thử, chúng ta thêm đoạn sau vào trong file pom.xml:
Để ứng dụng chạy được (vì không có file main để bootstrap), ta cần plugin trên. Có thể tìm phiên bản mới nhất của jetty-maven-plugin trên Maven.
Tiếp theo là chạy:
Chúng ta có thể kiểm tra các REST API bằng Postman hoặc dùng curl
. Các ví dụ sau sử dụng curl, có thể copy paste các payload trong cái -d
vào Postman để thử:
Sau khi tạo 2 sản phẩm, lấy về thử:
Update thử một sản phẩm:
Đọc sản phẩm vừa update:
Cũng như xóa thử:
#
9. Nhìn lạiJavaLite có khá nhiều công cụ để giúp tạo ứng dụng nhanh, tuy nhiên do dựa theo convention nên lúc đầu sẽ cần tìm hiểu quy định về tên và nơi đặt các file tương ứng. Mặt khác, đúng như cái tên “lite”, JavaLite phù hợp với các dự án nhỏ và vừa.
Ví dụ trên chỉ là giới thiệu hương hoa về ActiveWeb và ActiveJDBC. Tôi viết bài này khi đang tích hợp một framework web nhỏ cho con bot Discord, có hỗ trợ SQLite và JavaLite rất phù hợp cho việc đó. Các bạn có thể xem thêm hướng dẫn trên website. Code mẫu có thể tìm thấy tại link Github này.