delphi自动生成资源的REST CRUD工具

delphi自动生成资源的REST CRUD工具

该工具同样,还可以将资源生成GOOGLE PROTOBUF CRUD。

运行tableTool.exe工具,设置参数,连接数据库。

以“计量单位”资源为例,选择“tunit”数据表,点击“查询”按钮,点击“生成REST CRUD”按钮,点击“保存成文件”按钮,选择中间件源码所在目录,文件名就用自动生成的。

查看生成的rest.tunit.pas

unit rest.tunit;
//代码由代码工厂自动生成
//2022-07-10
{$I def.inc}
interface

uses
  {$IFDEF firedac}  db.firedac, db.firedacPool, {$ENDIF}
  {$IFDEF unidac}db.unidac, db.unidacpool,  {$ENDIF}
  classes, db,
  system.JSON.Serializers, yn.log, system.JSON, SysUtils, json.help;

type
  Ttunit = record
    [Serialize(1)] unitid: string;
    [Serialize(2)] unitname: string;
  end;

  TtunitArray = record
    [Serialize(1)] status: integer;
    [Serialize(2)] exception: string;
    [Serialize(3)] message: string;
    [Serialize(4)] tunits: TArray<Ttunit>;
  end;

  TRes = record
    [Serialize(1)] status: integer;
    [Serialize(2)] exception: string;
    [Serialize(3)] message: string;
  end;

function select(url: string; body: TBytes): string;

function insert(url: string; body: TBytes): string;

function update(url: string; body: TBytes): string;

function delete(url: string; body: TBytes): string;

implementation

function select(url: string; body: TBytes): string;
var
  db: tdb;
  pool: tdbpool;
  arr: TArray<string>;
  serial: TJsonSerializer;
  rows: TtunitArray;
  i, h: integer;
  res: TRes;
begin
  serial := TJsonSerializer.Create;
  try
    try
      arr := url.Split(['/']);
      pool := GetDBPool(arr[4]);
      db := pool.Lock;
      db.qry.Close;
      db.qry.SQL.Clear;
      db.qry.SQL.Text := 'select * from tunit';
      db.qry.Open;
      SetLength(rows.tunits, db.qry.RecordCount);
      db.qry.First;
      i := 0;
      while not db.qry.Eof do
      begin
        rows.tunits[i].unitid := db.qry.fieldbyname('unitid').asstring;
        rows.tunits[i].unitname := db.qry.fieldbyname('unitname').asstring;
        rows.status := 1;
        rows.message := 'success';
        inc(i);
        db.qry.Next;
      end;
      result := serial.Serialize<TtunitArray>(rows);
    except
      on E: Exception do
      begin
        res.status := 0;
        res.exception := E.message;
        result := serial.Serialize<TRes>(res);
      end;
    end;
  finally
    pool.Unlock(db);
    serial.Free;
  end;
end;

function insert(url: string; body: TBytes): string;
var
  db: tdb;
  pool: tdbpool;
  arr: tarray<string>;
  serial: TJsonSerializer;
  res: TRes;
begin
  serial := TJsonSerializer.Create;
  try
    try
      var rows: TtunitArray;
      rows := serial.Deserialize<TtunitArray>(TEncoding.UTF8.GetString(body));
      arr := url.Split(['/']);
      pool := GetDBPool(arr[4]);
      db := pool.Lock;
      db.startTrans;
      for var row: Ttunit in rows.tunits do
      begin
        db.qry.Close;
        db.qry.SQL.Clear;
        db.qry.SQL.Text := 'insert into tunit (unitid,unitname) values (:unitid,:unitname)';
        db.qry.ParamByName('unitid').AsString := row.unitid;
        db.qry.ParamByName('unitname').AsString := row.unitname;
        db.qry.ExecSQL;
      end;
      db.commitTrans;
      res.status := 1;
      res.message := 'success';
      Result := serial.Serialize<TRes>(res);
    except
      on E: Exception do
      begin
        db.rollbackTrans;
        res.status := 0;
        res.exception := E.Message;
        Result := serial.Serialize<TRes>(res);
      end;
    end;
  finally
    pool.Unlock(db);
    serial.Free;
  end;
end;

function update(url: string; body: TBytes): string;
var
  db: tdb;
  pool: tdbpool;
  arr: tarray<string>;
  serial: TJsonSerializer;
  res: TRes;
begin
  serial := TJsonSerializer.Create;
  try
    try
      var rows: TtunitArray;
      rows := serial.Deserialize<TtunitArray>(TEncoding.UTF8.GetString(body));
      arr := url.Split(['/']);
      pool := GetDBPool(arr[4]);
      db := pool.Lock;
      db.startTrans;
      for var row: Ttunit in rows.tunits do
      begin
        db.qry.Close;
        db.qry.SQL.Clear;
        db.qry.SQL.Text := 'update tunit set unitid=:unitid,unitname=:unitname where unitid=:key0';
        db.qry.ParamByName('unitid').AsString := row.unitid;
        db.qry.ParamByName('key0').AsString := row.unitid;
        db.qry.ParamByName('unitname').AsString := row.unitname;
        db.qry.ExecSQL;
      end;
      db.commitTrans;
      res.status := 1;
      res.message := 'success';
      Result := serial.Serialize<TRes>(res);
    except
      on E: Exception do
      begin
        db.rollbackTrans;
        res.status := 0;
        res.exception := E.Message;
        Result := serial.Serialize<TRes>(res);
      end;
    end;
  finally
    pool.Unlock(db);
    serial.Free;
  end;
end;

function delete(url: string; body: TBytes): string;
var
  db: tdb;
  pool: tdbpool;
  arr: tarray<string>;
  serial: TJsonSerializer;
  res: TRes;
begin
  serial := TJsonSerializer.Create;
  try
    try
      arr := url.Split(['/']);
      pool := GetDBPool(arr[4]);
      db := pool.Lock;
      db.qry.Close;
      db.qry.SQL.Clear;
      db.qry.SQL.Text := 'delete from tunit where unitid=:key0';
      db.qry.ParamByName('key0').AsString := arr[5];
      db.qry.ExecSQL;
      res.status := 1;
      res.message := 'success';
      Result := serial.Serialize<TRes>(res);
    except
      on E: Exception do
      begin
        res.status := 0;
        res.exception := E.Message;
        Result := serial.Serialize<TRes>(res);
      end;
    end;
  finally
    pool.Unlock(db);
    serial.Free;
  end;
end;

end.

  到sock.router.pas增加路由方法。

运行服务端

 

clientRest客户端uses  rest.tunit;

rest.tunit是工具自动生成的。

增加CRUD代码

procedure TForm1.Button1Click(Sender: TObject);
//新增json
begin
  var t: rest.tunit.TtunitArray;
  SetLength(t.tunits, 1);
  t.tunits[0].Unitid := '10';
  t.tunits[0].Unitname := '新增';
  var res: string := TRest.inJson<rest.tunit.TtunitArray>('/rest/unit/insert/1', t);
  var r: TRes := TRest.unmarshal<TRes>(res);
  if r.Status = 0 then
    ShowMessage('err: ' + r.Exception)
  else
    ShowMessage('ok');
end;

  

procedure TForm1.Button3Click(Sender: TObject);
//修改json
begin
  var t: rest.tunit.TtunitArray;
  SetLength(t.tunits, 1);
  t.tunits[0].Unitid := '10';
  t.tunits[0].Unitname := '修改';
  var res: string := TRest.inJson<rest.tunit.TtunitArray>('/rest/unit/update/1', t);
  var r: TRes := TRest.unmarshal<TRes>(res);
  if r.Status = 0 then
    ShowMessage('err: ' + r.Exception)
  else
    ShowMessage('ok');
end;

  

procedure TForm1.Button5Click(Sender: TObject);
//json查询
begin
  var t: rest.tunit.TtunitArray := TRest.outJson<rest.tunit.TtunitArray>('/rest/unit/select/1');
  if t.Status = 0 then
  begin
    ShowMessage(t.Exception);
    Exit;
  end;
  FDMemTable1.EmptyDataSet;
  FDMemTable1.DisableControls;
  for var dw: rest.tunit.Ttunit in t.tunits do
    FDMemTable1.AppendRecord([dw.Unitid, dw.Unitname]);
  FDMemTable1.First;
  FDMemTable1.EnableControls;
end;

  

procedure TForm1.Button7Click(Sender: TObject);
//删除json
begin
  var res: string := TRest.inUrl('/rest/unit/delete/1/10');
  var r: TRes := TRest.unmarshal<TRes>(res);
  if r.Status = 0 then
    ShowMessage('err: ' + r.Exception)
  else
    ShowMessage('ok');
end;

  

运行tableTool.exe生成REST接口的在线文档

 

unit server.Resources.tunit;
//代码由代码工厂自动生成
//2022-07-10
interface

uses
  System.SysUtils, WiRL.Core.Registry, WiRL.Core.Attributes,  WiRL.Core.MessageBody.Default,
  WiRL.http.Accept.MediaType;

type
  Ttunit = record
    [Serialize(1)] unitid: string;
    [Serialize(2)] unitname: string;
  end;

  TtunitArray = record
    [Serialize(1)] status: integer;
    [Serialize(2)] exception: string;
    [Serialize(3)] message: string;
    [Serialize(4)] tunits: TArray<Ttunit>;
  end;

  TRes = record
    [Serialize(1)] status: integer;
    [Serialize(2)] exception: string;
    [Serialize(3)] message: string;
  end;

  [Path('tunit')]
  TtunitAPI = class
    [post, path('/select/{dbid}'), Produces(TMediaType.APPLICATION_JSON)]
    function select([PathParam('dbid')] dbid: string): TtunitArray; virtual; abstract;
    [post, path('/insert/{dbid}'), Consumes(TMediaType.APPLICATION_JSON), Produces(TMediaType.APPLICATION_JSON)]
    function insert([PathParam('dbid')] dbid: string; [BodyParam] body: TtunitArray): TRes; virtual; abstract;
    [post, path('/update/{dbid}'), Consumes(TMediaType.APPLICATION_JSON), Produces(TMediaType.APPLICATION_JSON)]
    function update([PathParam('dbid')] dbid: string; [BodyParam] body: TtunitArray): TRes; virtual; abstract;
    [post, path('/delete/{dbid}/{unitid}'), Produces(TMediaType.APPLICATION_JSON)]
    function delete([PathParam('dbid')] dbid: string; [PathParam('unitid')] unitid: string): TRes; virtual; abstract;
  end;

implementation

initialization
  TWiRLResourceRegistry.Instance.RegisterResource<TtunitAPI>;

end.

  openApi工程中添加上面用工具生成的单元

 

编译,运行openApi.exe

 

posted @ 2022-07-10 13:44  delphi中间件  阅读(426)  评论(1编辑  收藏  举报