Xử lý yêu cầu HTTP POST trong kbmMW Smart Services

Các dịch vụ REST dựa trên kbmMW Smart Service hỗ trợ nhiều cách tiếp nhận dữ liệu qua phương thức POST. Bài viết này trình bày chi tiết các kiểu dữ liệu phổ biến được gửi từ client và cách khai báo, xử lý tương ứng trong mã nguồn server.

Các dạng dữ liệu POST thường gặp

1. Giá trị đường dẫn (Path parameters)
Dữ liệu được nhúng trực tiếp vào URI dưới dạng phần tử đường dẫn:
POST http://localhost/myservice/process/42/1984 2. Tham số truy vấn (Query string)
Dữ liệu được truyền qua chuỗi tham số sau dấu chấm hỏi:
POST http://localhost/myservice/process?id=42&code=1984 3. Dữ liệu dạng form-urlencoded trong body
Body chứa cặp khóa–giá trị được mã hóa URL:
key1=value1&key2=value2 4. Dữ liệu JSON hoặc XML trong body
Body chứa cấu trúc dữ liệu có định dạng chuẩn:
{"key1":"value1","key2":"value2"} 5. Dữ liệu multipart – thường dùng cho upload file
Body được chia thành nhiều phần riêng biệt, mỗi phần có header riêng và phân tách bởi boundary.

Cách triển khai trong kbmMW

1. Xử lý giá trị từ đường dẫn
Sử dụng cú pháp `{tên}` trong thuộc tính `path`, kết hợp với annotation `value:"{tên}"`:
[kbmMW_Rest('method:post, path: "process/{id}/{code}"')]
function ProcessData(
  [kbmMW_Rest('value:"{id}"')] AId: Integer;
  [kbmMW_Rest('value:"{code}"')] ACode: Integer): string;
2. Lấy tham số từ query string
Dùng ký hiệu `$` để chỉ định tham số truy vấn:
[kbmMW_Rest('method:post, path: "process"')]
function ProcessData(
  [kbmMW_Rest('value:"$id"')] AId: Integer;
  [kbmMW_Rest('value:"$code"')] ACode: Integer): string;
3. Đọc toàn bộ body dạng form-urlencoded
Khai báo tham số nhận toàn bộ nội dung body, sau đó phân tích bằng TkbmMWHTTPQueryValues:
[kbmMW_Rest('method:post, path: "process"')]
function ProcessData([kbmMW_Rest('value:body')] ARawBody: string): string;
Triển khai hàm:
var
  qv: TkbmMWHTTPQueryValues;
begin
  qv := TkbmMWHTTPQueryValues.Create;
  try
    qv.AsEncodedString := ARawBody; // Dùng AsEncodedString nếu body đã được URL-encode
    Result := Format('ID=%s, Code=%s', [
      qv.ValueByName['id'],
      qv.ValueByName['code']
    ]);
  finally
    qv.Free;
  end;
end;
4. Xử lý JSON/XML bằng lớp dữ liệu mạnh kiểu
Định nghĩa class tương ứng với cấu trúc dữ liệu đầu vào:
[kbmMW_Root('payload', [mwrfIncludeOnlyTagged])]
TRequestPayload = class
private
  FId: Integer;
  FCode: string;
public
  [kbmMW_Attribute('id')]
  property Id: Integer read FId write FId;

  [kbmMW_Attribute('code')]
  property Code: string read FCode write FCode;
end;

[kbmMW_Rest('method:post, path: "process"')]
function ProcessData([kbmMW_Rest('value:body')] const APayload: TRequestPayload): string;
kbmMW tự động deserialize JSON/XML thành thể hiện của TRequestPayload, không cần viết logic phân tích thủ công. 5. Phân tích multipart body (upload file)
Sử dụng TkbmMWHTTPMultiParts để tách và xử lý từng phần:
[kbmMW_Rest('method:post, path: "upload"')]
function HandleUpload: string;

function TMyService.HandleUpload: string;
var
  mp: TkbmMWHTTPMultiParts;
  part: TkbmMWHTTPMultiPart;
  headers: TkbmMWHTTPMimeHeaderValueFields;
  boundary: string;
  fs: TFileStream;
  fileName: string;
  helper: TkbmMWHTTPTransportStreamHelper;
begin
  Result := 'No upload detected';

  helper := TkbmMWHTTPTransportStreamHelper(RequestTransportStream.Helper);
  headers := helper.Header.ValueFields['Content-Type'];
  if not Assigned(headers) then Exit;

  boundary := headers.ValueByName['boundary'];
  if boundary = '' then Exit;

  mp := TkbmMWHTTPMultiParts.Create(RequestStream, boundary);
  try
    for var i := 0 to mp.Count - 1 do
    begin
      part := mp.Parts[i];
      headers := part.Headers.ValueFields['Content-Disposition'];
      fileName := headers.ValueByName['filename'];
      if fileName <> '' then
      begin
        fileName := '.\uploads\' + TPath.GetFileName(fileName);
        TDirectory.CreateDirectory('.\uploads');
        fs := TFileStream.Create(fileName, fmCreate);
        try
          part.SaveToStream(fs);
          Result := Format('File saved: %s', [fileName]);
        finally
          fs.Free;
        end;
        Break;
      end;
    end;
  finally
    mp.Free;
  end;
end;

Thẻ: kbmMW Delphi REST http-post multipart-form-data

Đăng vào ngày 4 tháng 7 lúc 12:36