Việc xây dựng một máy chủ REST với kbmMW trong Delphi trở nên cực kỳ đơn giản nhờ cơ chế attribute-driven và khả năng tự động hóa mạnh mẽ. Bắt đầu bằng việc tạo ứng dụng máy chủ, bạn có thể dùng giao diện đồ họa hoặc chạy nền dưới dạng service.
Trong môi trường Delphi, chọn File → New → VCL Forms Application. Sau đó kéo thả hai thành phần sau vào form:
TkbmMWServerTkbmMWTCPIPIndyServerTransport
Thiết lập thuộc tính Server của kbmMWTCPIPIndyServerTransport1 trỏ đến kbmMWServer1. Tiếp theo, mở bộ chỉnh sửa Bindings và thêm binding mới với địa chỉ 0.0.0.0, cổng 80 – cổng HTTP mặc định. Bạn có thể thay đổi cổng nếu cần, nhưng hãy đảm bảo thông báo cho client.
Quan trọng: Đặt thuộc tính StreamFormat của transport thành REST để kích hoạt xử lý yêu cầu theo chuẩn REST.
Thêm sự kiện OnCreate cho form để khởi động máy chủ:
procedure TForm7.FormCreate(Sender: TObject);
begin
kbmMWServer1.AutoRegisterServices;
kbmMWServer1.Active := True;
end;
Đảm bảo khai báo unit kbmMWRESTTransStream trong khối uses của interface, vì đây là unit xử lý định dạng dữ liệu REST:
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
kbmMWCustomTransport, kbmMWServer, kbmMWTCPIPIndyServerTransport,
kbmMWRESTTransStream; // Cần thiết để hỗ trợ REST
Bây giờ, hệ thống đã sẵn sàng tiếp nhận yêu cầu REST. Tiếp theo, ta sẽ thêm các phương thức dịch vụ có thể được gọi từ bên ngoài.
Sử dụng File → New → Other → Components4Developers Wizards → kbmMW Service Wizard. Chọn mẫu Smart Service / kbmMW_1.0 để tạo dịch vụ thuần REST (không phục vụ file tĩnh như HTML, CSS…).
Đặt tên dịch vụ là MyREST, sau đó wizard sẽ sinh ra một unit mới dựa trên TDataModule. Nhấn F12 để xem mã nguồn và tìm đến đoạn khai báo lớp dịch vụ:
[kbmMW_Service('name:MyREST, flags:[listed]')]
[kbmMW_Rest('path:/MyREST')]
TkbmMWCustomSmartService8 = class(TkbmMWCustomSmartService)
public
[kbmMW_Method]
[kbmMW_Rest('method:get, path:helloworld')]
function HelloWorld: string;
end;
function TkbmMWCustomSmartService8.HelloWorld: string;
begin
Result := 'Hello world';
end;
Khi chạy chương trình, truy cập qua trình duyệt với địa chỉ:
http://localhost/MyREST/helloworld
Lưu ý: URL phân biệt chữ hoa/thường, nên phải nhập chính xác.
Mặc định, kết quả trả về là chuỗi văn bản thuần. Tuy nhiên, hầu hết client hiện đại mong đợi dữ liệu ở định dạng JSON. Có ba cách để xử lý điều này:
1. Trả về JSON thủ công
Chỉnh sửa phương thức để trả về chuỗi JSON đúng cú pháp:
function TkbmMWCustomSmartService8.Helloworld: string;
begin
Result := '{"result":"Hello world"}';
end;
2. Dùng bộ tạo JSON bán tự động
Thêm các unit hỗ trợ ký hiệu đối tượng:
uses
kbmMWObjectNotation, kbmMWJSON;
Sau đó sử dụng TkbmMWONObject để xây dựng cấu trúc dữ liệu linh hoạt:
function TkbmMWCustomSmartService8.HelloWorld: string;
var
obj: TkbmMWONObject;
jsonStreamer: TkbmMWJSONStreamer;
begin
obj := TkbmMWONObject.Create;
jsonStreamer := TkbmMWJSONStreamer.Create;
try
obj.AsString['result'] := 'Hello world';
Result := jsonStreamer.SaveToUTF16String(obj);
finally
obj.Free;
jsonStreamer.Free;
end;
end;
Cách này cho phép bạn dễ dàng mở rộng sang XML, YAML hay MessagePack bằng cách thay đổi streamer.
3. Tự động hóa hoàn toàn bằng class và RTTI
Định nghĩa một lớp dữ liệu:
TMyResult = class
private
FResult: string;
published
property Result: string read FResult write FResult;
end;
Thay đổi kiểu trả về của phương thức:
[kbmMW_Method]
[kbmMW_Rest('method:get, path:helloworld, anonymousResult:true')]
function HelloWorld: TMyResult;
Và cài đặt:
function TkbmMWCustomSmartService8.HelloWorld: TMyResult;
begin
Result := TMyResult.Create;
Result.Result := 'Hello world';
end;
Thêm đoạn khởi tạo để đăng ký kiểu dữ liệu với kbmMW:
initialization
kbmMWRegisterKnownClasses([TMyResult]);
Thuộc tính anonymousResult:true giúp loại bỏ tên lớp trong JSON trả về. Nếu không dùng tùy chọn này, kết quả sẽ là:
{"TMyResult": {"Result": "Hello world"}}
Ngược lại, khi bật anonymousResult, kết quả sẽ gọn gàng hơn:
{"Result": "Hello world"}
Hệ thống tự động giải phóng bộ nhớ đối tượng trả về. Nếu muốn giữ quyền kiểm soát, thêm freeResult:false vào thuộc tính kbmMW_Rest.
Ngoài string và object, kbmMW còn hỗ trợ trả về TkbmMemTable, mảng, record, dataset và nhiều kiểu dữ liệu khác mà không cần viết thêm mã chuyển đổi.
Thêm điểm mạnh nữa: phương thức có đánh dấu [kbmMW_Method] cũng có thể được gọi từ client kbmMW truyền thống (ví dụ: TkbmMWSimpleClient), cho phép tái sử dụng logic nghiệp vụ trên cả hai nền tảng – REST và RPC.