REST easy with kbmMW #1
kbmMW 5.0支持REST服务器的开发,并且非常简单,下面看看如何实作一个REST服务器。
首先我们制作一个服务器应用程序,增加一个简单的Form,并放置kbmMW组件。
在Delphi中单击File - New - VCL Forms Application
然后将以下kbmMW组件添加到Form中:
- TkbmMWServer
- TkbmMWTCPIPIndyServerTransport
将kbmMWTCPIPIndyServerTransport1的Server属性设置为kbmMWServer1。
设置组件kbmMWTCPIPIndyTransport1的Streamformat属性为REST,如下图:
保存项目,Delphi将自动填加引用的单元,双击Form,建立OnCreate事件:
procedure TForm7.FormCreate(Sender: TObject); begin kbmMWServer1.AutoRegisterServices; kbmMWServer1.Active:=true; end;
定位到单元的interface段,手工填加引用的单元kbmMWRESTTransStream.
再次保存,得到如下的单元:
unit Unit7; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, kbmMWCustomTransport, kbmMWServer, kbmMWTCPIPIndyServerTransport, kbmMWRESTTransStream; type TForm7 = class(TForm) kbmMWServer1: TkbmMWServer; kbmMWTCPIPIndyServerTransport1: TkbmMWTCPIPIndyServerTransport; procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form7: TForm7; implementation {$R *.dfm} procedure TForm7.FormCreate(Sender: TObject); begin kbmMWServer1.AutoRegisterServices; kbmMWServer1.Active:=true; end; end.
现在,一个实现REST服务器的基础功能具备了,接下来,我们来填加一些可以从任意REST客户端调用的具体功能.
在Delphi中,单击File-New-Other-Components4Developers wizard:
在继续选择我们要添加的kbmMW Service的类型之前,需要确定要创建什么类型的REST服务器。它可以是一个纯粹的REST服务器,只提供自己的代码中的数据,也可以是常规的Web服务器,可以从磁盘上的文件(如html模板,图像,CSS文件等)提供数据。
这里,我们只想做一个纯粹的REST服务器,所以选择了Smart service / kbmMW_1.0。
如果你希望能够从磁盘提供文件,甚至可以将代理请求提供给其他FastCGI兼容服务器(如PHP等),那么您将选择HTTP智能服务。
点击下一步,输入REST服务的默认名称,在这个例子中,我称之为MyREST。
接下来一路Next,直到下面显示的页面,然后点击绿色的勾号按钮
现在已经生成了没有功能的Service。表面看,这个Service就像一个TDataModule,可以放在TDataModule上的任意组件这里都可以用,但是现在我们对它的代码更感兴趣,所以按F12切换到代码视图,浏览顶部的注释,直到找到实际的代码。
type [kbmMW_Service('name:MyREST, flags:[listed]')] [kbmMW_Rest('path:/MyREST')] // Access to the service can be limited using the [kbmMW_Auth..] attribute. // [kbmMW_Auth('role:[SomeRole,SomeOtherRole], grant:true')] TkbmMWCustomSmartService8 = class(TkbmMWCustomSmartService) private { Private declarations } protected { Protected declarations } public { Public declarations } // HelloWorld function callable from both a regular client, // due to the optional [kbmMW_Method] attribute, // and from a REST client due to the optional [kbmMW_Rest] attribute. // The access path to the function from a REST client (like a browser)+ // is in this case relative to the services path. // In this example: http://.../MyREST/helloworld // Access to the function can be limited using the [kbmMW_Auth..] attribute. // [kbmMW_Auth('role:[SomeRole,SomeOtherRole], grant:true')] [kbmMW_Rest('method:get, path:helloworld')] [kbmMW_Method] function HelloWorld:string; end; implementation uses kbmMWExceptions; {$R *.dfm} // Service definitions. //--------------------- function TkbmMWCustomSmartService8.HelloWorld:string; begin Result:='Hello world'; end;
如果您现在编译和运行应用程序,就得到了只有一个REST功能的Web服务器,这个功能叫HelloWorld,不带参数,并返回一个字符串。
打开你最喜欢的浏览器,并通过在地址栏中输入这个功能的地址来测试该功能:
http://localhost/MyREST/helloworld
确保地址的大小写是正确的,因为HTTP标准描述地址的URL部分必须区分大小写。如果你写的是http://localhost/MyREST/HelloWorld,你会被告知请求无效。
这看起来已经很好了,但我的REST客户端期望接收一个JSON对象,而不仅仅是简单的文本。
现在我准备展示三种方法来做到这一点:
- 手动方式
- 半自动化方式
- 全自动化的方式
1.手动方式,将HelloWorld函数更改为如下所示:
function TkbmMWCustomSmartService8.HelloWorld:string; begin Result:='{''result'':''Hello world''}'; end;
REST客户端将收到一个名为result的属性的匿名对象,其中包含“Hello world”。
2.半自动化方式:
uses kbmMWExceptions ,kbmMWObjectNotation ,kbmMWJSON; {$R *.dfm} // Service definitions. //--------------------- function TkbmMWCustomSmartService8.HelloWorld:string; var o:TkbmMWONObject; jsonstreamer:TkbmMWJSONStreamer; begin o:=TkbmMWONObject.Create; jsonstreamer:=TkbmMWJSONStreamer.Create; o.AsString['result']:='Hello world'; Result:=jsonstreamer.SaveToUTF16String(o); jsonstreamer.Free; o.Free; end;
这样可以很容易地创建复杂的JSON文档,更爽的是,由于我们使用kbmMW的object notation framework,因此可以选择XML或YAML或BSON或MessagePack等格式进行传输。
3.全自动化方式:
type TMyResult = class private FResult:string; public property Result:string read FResult write FResult; end; [kbmMW_Service('name:MyREST, flags:[listed]')] [kbmMW_Rest('path:/MyREST')] // Access to the service can be limited using the [kbmMW_Auth..] attribute. // [kbmMW_Auth('role:[SomeRole,SomeOtherRole], grant:true')] TkbmMWCustomSmartService8 = class(TkbmMWCustomSmartService) private [kbmMW_Rest('method:get, path:helloworld, anonymousResult:true')] [kbmMW_Method] function HelloWorld:TMyResult; end; implementation uses kbmMWExceptions; {$R *.dfm} // Service definitions. //--------------------- function TkbmMWCustomSmartService8.HelloWorld:TMyResult; begin Result:=TMyResult.Create; Result.Result:='Hello world'; end; initialization TkbmMWRTTI.EnableRTTI(TkbmMWCustomSmartService8); kbmMWRegisterKnownClasses([TMyResult]); end.
全自动化方式简单的实现返回具有所需信息的对象,kbmMW自动将对象转换为JSON(因为我们正在使用REST streamformat)。
为了确保kbmMW知道对象类型,我们通过kbmMWRegisterKnownClasses进行注册。如果我们没有,kbmMW会抱怨它不知道该对象。
还要注意,kbmMW_Rest属性设置现在包括:anonymousResult:true。这告诉kbmMW我们希望生成的JSON是匿名的,结果如下:
{“TMyResult”:{“Result”:“Hello world”}}
是否匿名输出json,没有对错,取决你的需要,但是一定要记得,输出结果是不同的。
有很多控制选项可以通过设置对象的各种属性来流式传输对象。例如可以选择要以不同的名称返回Result属性。
kbmMW还能返回TkbmMemTable实例,数组和许多其他类型的信息,因此几乎不用其他代码行就可以轻松地实现您的kbmMW业务功能。
作为最后的评论,由于HelloWorld方法也被标记为属性[kbmMW_Method],它也可以由kbmMW客户端调用。
你可以随意转发、评论、点赞、推荐这篇文章 🙂