Sie sind auf Seite 1von 25

Delphi

MVC Framework

Table of Contents
Introduction 0
Getting Started: the 5 minutes guide 1
Controllers and routing 2
Renders 3
Server Side Views 4
Middlewares 5
Handling parameters 6
Session handling 7
Using MySQL as state server 7.1
Using Redis as state server 7.2
Using REST Client 8
The amazing RESTAdapter 8.1
Deploy as Apache module 9
Deploy as Microsoft IIS module 10
Deploy as Windows Service module 11

2
Delphi MVC Framework

Developer Guide
Delphi MVC Framework (DMVCFramework for short) is a popular and powerful framework
for web solution in Delphi.

Introduction 3
Delphi MVC Framework

Getting Started: 5 minutes guide


DMVCFramework allows to create powerful RESTful servers without effort. You can create a
full-flagged RESTful server in a couple of clicks.

Installation from the git repository


You can install DMVCFramwork using the zip package or cloning the git repository. This
tutorial uses the git cloning approach.

Install a command line git client (follow these instructions)


Open the command prompt
mkdir C:\dmvc

cd c:\dmvc

git clone https://github.com/danieleteti/delphimvcframework.git .

wait git finish its job


Launch RAD Studio and open C:\dmvc\ideexpert\DMVC_IDE_Expert_D10Seattle.dproj
Install the package
Close all
Now, DMVCFramework expert is installed and you are able to create DMVCFramework
project
go to File->New->Other select Delphi Project->DMVC->DelphiMVCFramework Project

Getting Started: the 5 minutes guide 4


Delphi MVC Framework

From the resultant dialog, leave all the default settings and click OK
If you try to compile the project now, you will get compiler errors because we've to
configure the library paths to let the compiler finds the needed source files
go to Tools->Options->Environment Options->Delphi Options->Library and add in the
Library Path edit the following paths:

C:\DMVC\sources\

C:\DMVC\lib\dmustache\

C:\DMVC\lib\iocpdelphiframework\Base\

C:\DMVC\lib\delphistompclient\

Run the project ( F9 )


A webbrowser is launched and a new console application is running serving you first
DMVCFramework server. Simple, isn't it?
Now you can follows the rest of the guide to learn all the nice things about
DMVCFramework.

Installation from the zip file


You can install DMVCFramwork using the zip package or cloning the git repository. This
tutorial uses the zip file approach.

Getting Started: the 5 minutes guide 5


Delphi MVC Framework

Download the master zip file containing the current version of the repository
Unzip it in a folder named C:\dmvc
Launch RAD Studio and open C:\dmvc\ideexpert\DMVC_IDE_Expert_D10Seattle.dproj
Install the package
Close all
Now, DMVCFramework expert is installed and you are able to create DMVCFramework
project
go to File->New->Other select Delphi Project->DMVC->DelphiMVCFramework Project

From the resultant dialog, leave all the default settings and click ok
If you try to compile the project now, you will get compiler errors because we've to
configure the library paths to let the compiler finds the needed source files
go to Tools->Options->Environment Options->Delphi Options->Library and add in the
Library Path edit the following paths:

C:\DMVC\sources\

C:\DMVC\lib\dmustache\

C:\DMVC\lib\iocpdelphiframework\Base\

C:\DMVC\lib\delphistompclient\

Run the project ( F9 )


A webbrowser is launched and a new console application is running serving you first

Getting Started: the 5 minutes guide 6


Delphi MVC Framework

DMVCFramework server. Simple, isn't it?


Now you can follows the rest of the guide to learn all the nice things about
DMVCFramework.

Getting Started: the 5 minutes guide 7


Delphi MVC Framework

Controllers and routing


TODO

Controllers and routing 8


Delphi MVC Framework

Renders
Renders are the mechanism used by DMVCFramework to serialize your data (objects,
strings, dataset, JSON structure) into a format suitable for the network transfer as a string.
This process is called "Serialization" while the opposite process (create an objects from a
string rapresentation) is called "Deserialization". For instance if you want to serialize a
dataset you can call withing a controller Render(LMyDataset) and your client will get a
serialized version of dataset data. By default the serialization format is JSON but this can be
changed and customized according to your needs. Remember, all the
serialization/deserialization activities should be happens within the controller actions.

Rendering JSON data


Here's a controller action which returns JSON data string serializing a native Delphi JSON
object.

procedure TRenderSampleController.GetPerson(CTX: TWebContext);


var
LPerson: TJSONObject;
begin
LPerson := TJSONObject.Create;
try
LPerson.AddPair('FirstName', 'Daniele');
LPerson.AddPair('LastName', 'Teti');
LPerson.AddPair('DOB', ISODateToString(EncodeDate(1975, 5, 2)));
LPerson.AddPair('Married', TJSONTrue.Create);
Render(LPerson);
except
LPerson.Free; //in case of exception, avoid memory leaks
raise; //re-raise the exception
end;
end;

Rendering TDataset

Rendering objects and list of objects


Here's a controller action which returns JSON data string serializing a native Delphi object.

Renders 9
Delphi MVC Framework

procedure TRenderSampleController.GetCustomerByID(CTX: TWebContext);


var
Cust: TCustomer;
begin
Cust := TCustomer.Create;
try
Cust.Name := 'bit Time Professionals';
Cust.ContactFirst := 'Daniele';
Cust.ContactLast := 'Teti';
Cust.AddressLine1 := 'Rome Street 12';
Cust.AddressLine2 := '00100';
Cust.City := 'ROME';
{The following line renders a TObject descendant as JSON.
The object memory is automatically freed however,
you can override this behaviour using other parameters}
Render(Cust);
except
Cust.Free; //in case of exception, avoid memory leaks
raise; //re-raise the exception
end;
end;

Rendering raw data as streams

Renders 10
Delphi MVC Framework

Server Side Views


TODO

Server Side Views 11


Delphi MVC Framework

Delphi MVCFramework Middleware


Middleware is a powerful and flexible api/layer within the DMVC Framework. With this layer
you can write SOLID code by separate code which would be repeatedly implemented in
each controller method. It is the perfect layer for cross cutting concerns or for controlling
HTTP requests/response. Here are some examples for the usage of Middleware:

Redirect calls to another url (URL Rewrite; if you are not using a webserver like Apache
or IIS)
Add some required parameter if the REST interface has changed (another version of
the REST interface)
Enable CORS
HTTP Authentication
Logging
Caching

The basis of this api/layer is the interface IMVCMiddleware declared in MVCFramework.pas.


You have to create a class which implements the IMVCMiddleware and all the methods.
Middleware classes (classes that implement the IMVCMiddleware) can be added to the
MVCEngine at startup. You can add as many as you want Middleware classes. Internally
there is a list of IMVCMiddleware. The life time of this Middleware classes is handled by the
MVCEngine.

Here is an example of how to add a Middleware object/interface to the MVCEngine:

procedure TWebModule1.WebModuleCreate(Sender: TObject); begin MVC :=


TMVCEngine.Create(Self); MVC.AddController(TMyController);
MVC.AddMiddleware(TMyMiddleware.Create); end;

Middleware classes has to implement the following methods:

procedure OnBeforeRouting(
Context: TWebContext;
var Handled: boolean);
procedure OnBeforeControllerAction(
Context: TWebContext;
const AControllerQualifiedClassName: string;
const AActionNAme: string;
var Handled: boolean);
procedure OnAfterControllerAction(
Context: TWebContext;
const AActionNAme: string;
const Handled: boolean);

Middlewares 12
Delphi MVC Framework

Because of the nature of a class that implements an interface you have to implement all of
the procedures. But you can leave the procedure empty, if you don't have anything to
implement in this step. But you must add the procedure to your class.

This three procedures will be called at the right time during a call to the DMVC Server. For
example if you call http://localhost/mycontroller/mymethod the MVCEngine will "execute" this
url. First it will check for static files. If the requested url is a static file it will be rendered and
the execution is finished. If the url is not a static file the OnBeforeRouting procedure of all
added Middleware objects will be fired. During this call you could make a redirect to another
url like in the middleware example (TMVCRedirectAndroidDeviceOnPlayStore) or you can
add special html headers like in the MVCFramework.Middleware.CORS.pas unit. At this
point the complete request is "on the server". You have full access to the complete
TWebRequest object with all parameter and header values. After this the MVCEngine
search for a controller/method that matches the request. If a controller method is found the
OnBeforeControllerAction procedure is fired. During this call you can ask for an
authentication like in the MVCFramework.Middleware.Authentication.pas unit. The next step
is the execution of the real controller method. This means the controller is created, the
corresponding method is executed and the controller is destroyed. Than the
OnAfterControllerAction of each registered Middleware class is fired. This procedure is fired
before the content is send to the client. This means you can add or modify HTML headers or
the content itself. You can also cancel the execution by sending a 404 not found or 500
internal server error. During all this calls you have full access to the TWebContext which
contains both the request and the response. You have also the possibility to cancel/finish the
execution by setting the Handled parameter to true.

The DMVC Framework provides some ready to use Middleware implementations and also a
simple example.

MVCFramework.Middleware.CORS.pas
With the help of this Middleware class you can enable Cross-origin resource sharing.
(https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) CORS is a mechanism that
allows restricted resources (e.g. fonts) on a web page to be requested from another domain
outside the domain from which the resource originated.

Usage: Add the following line of code to the WebModule OnCreate event in which you
create an instance of TMVCEngine. MVC.AddMiddleware(TCORSMiddleware.Create);

MVCFramework.Middleware.Authentication.pas

Middlewares 13
Delphi MVC Framework

With the help of this Middleware class it is possible to make basic HTTP Authentication.
TODO...

Usage: Add the following line of code to the WebModule OnCreate event in which you
create an instance of TMVCEngine.

MVC.AddMiddleware(
TMVCBasicAuthenticationMiddleware
.Create(AMVCAuthenticationHandler));

Samples\middleware\MiddlewareSamples.dpr

This demo shows the implementation of two Middleware classes.

1. TMVCSalutationMiddleware -> This Middleware add a custom HTTP header to each


response.
2. TMVCRedirectAndroidDeviceOnPlayStore -> This Middleware makes under certain
circumstances (the HTTP header 'User-Agent' contains 'Android') a redirect to another
url. (URL Rewrite)

Middlewares 14
Delphi MVC Framework

Handling parameters
TODO

Handling parameters 15
Delphi MVC Framework

Using MySQL as state server

Using MySQL as state server 16


Delphi MVC Framework

Using Redis as state server

Using Redis as state server 17


Delphi MVC Framework

Using REST Client

Using REST Client 18


Delphi MVC Framework

The amazing RESTAdapter


What is RESTAdapter? RESTAdapter turn your REST API into a Delphi Interface. In practice
you can declare an interface that represents your REST API and the RESTAdapter does all
work for you. You have to declare a Delphi interface and then use RTTI attributes to describe
the request:

1. RESTResource: to describe URI and REST verb of resource


2. Headers: a key-value pair that represents a Header of HTTP request
3. MapperListOf: to specify the Object Type of the List
4. Param: to specify that a method parameter is a param of HTTP Request
5. Body: to specify that a method parameter is the body of HTTP Request

[Headers('User-Agent', 'RESTAdapter-Test')]
IRESTAPIService = interface(IInvokable)
['{58B9FA23-92F4-4B8E-814B-05232F32A41F}']

[RESTResource(HttpGet, '/persons')]
[MapperListOf(TPerson)]
function GetListPerson: TObjectList<TPerson>;

[RESTResource(HttpGet, '/persons/{personid}')]
function GetPersonByID([Param('personid')] APersonID: integer): TPerson;

[RESTResource(httpPOST, '/persons')]
function SavePerson([Body] ABody: TPerson): TPerson;

end;

After you have declared the interface and described the HTTP request by attributes, you
have to use the TRestAdapter class to generate the real implementation of declared
interface:

RESTAdapter := TRESTAdapter<IRESTAPIService>.Create;
RESTAPIService := RESTAdapter.Build('localhost', 9999);

Here is the magic! By now, you can call your HTTP endpoints without adding code:

Person := RESTAPIService.GetPersonByID(1);

The amazing RESTAdapter 19


Delphi MVC Framework

The TRESTAdapter class inherits from TVirtualInterface. TVirtualInterface doesn't behave


like an ordinary class, each instance has an associated reference counter to automatically
free itself. In practice there isn't need to free the RESTAdapter object.

Attributes
More detailed information about the use of available attributes

RestResource
Allows you to describe the REST resource in terms of URI and REST verb (GET, POST,
PUT, DELETE).

[RESTResource(HttpGet, '/persons')]

You can also specify query parameters in the URL:

[RESTResource(HttpGet, '/persons?sort=desc')]

You can decide to manipulate the URL dynamically by surrounding a parameter with
brackets: {parameter}. Then put the Param attribute on the relative methods parameter
specifying the match in the URL (the value surrounded with brackets):

[RESTResource(HttpGet, '/persons/{personid}')]
function GetPersonByID([Param('personid')] APersonID: integer): TPerson;

Header
Allows you to set header for all requests (by put the attribute on the interface declaration) or
single method:

[Headers('User-Agent', 'RESTAdapter-Test')]
IRESTAPIService = interface(IInvokable)
['{58B9FA23-92F4-4B8E-814B-05232F32A41F}']

[Headers('Accept', 'application/json')]
[Headers('ContentType', 'application/json')]
[RESTResource(HttpGet, '/testconsumejson')]
function HeadersApplicationJSON: TJSONValue;

end;

The amazing RESTAdapter 20


Delphi MVC Framework

Both Headers, interface and method, will be included in the request.

Body
Allows you to specify an object for use as an HTTP request body by putting the Body
attribute.

[RESTResource(httpPOST, '/persons')]
function SavePerson([Body] ABody: TPerson): TPerson;

The object will be converted in JSON format.

The amazing RESTAdapter 21


Delphi MVC Framework

Deploy as Apache module

Deploy as Apache module 22


Delphi MVC Framework

Deploy as Microsoft IIS module


FIRST DRAFT

This is a step by step instruction for the deployment of an ISAPI DLL on Microsoft IIS Server.
It is applicable and tested with IIS version 7.5 and 8.5.

Install IIS
Open Server Manager - Server Roles - Add Server Role - Web Server (IIS) - Select
Role Service at least "ISAPI Extensions" and "ISAPI Filters"
See also: https://www.iis.net/learn/install/installing-iis-85/installing-iis-85-on-
windows-server-2012-r2 and https://www.iis.net/learn/install/installing-iis-
7/installing-iis-7-and-above-on-windows-server-2008-or-windows-server-2008-r2
Open the IIS Manager
Create a new web site or use the "Default Web Site"
Copy your ISAPI DLL to a folder on the web server (e.g. "C:\Inetpub\DMVC_ISAPI")
Create an application pool
Select "Application Pool" node on the left
Click "Add Application Pool ..."
Type in a name e.g. "my_domain_dmvc_isapi"
Set ".Net Framework version" to "No Managed Code"
Click OK
Right click on the created application pool "Advanced Settings..."
If you have a 64 Bit IIS/Windows and a 32 Bit ISAPI DLL you have to "Enable 32-
Bit Applications"
Add an application to your site
Select your web site node on the left (e.g. "Default Web Site")
Right click -> "Add Application..."
Type in an "Alias" (e.g. "api"); This is the url path to your ISAPI. e.g.
"http://www.mydomain.com/api"
Select previously created application pool "my_domain_dmvc_isapi"
Select the physical path to your ISAPI DLL (e.g. "C:\Inetpub\DMVC_ISAPI")
Allow dll execution on your web site.
Select the previously created application node ("api")
Double click "Handler Mappings"
Click "Edit Feature Permissions"
Enable "Execute" check box.
Allow your specific dll on IIS.
Select the "Server" node

Deploy as Microsoft IIS module 23


Delphi MVC Framework

Double click "ISAPI and CGI Restrictions"


Click "Add..."
Select your dll from "C:\Inetpub\DMVC_ISAPI" and check "Allow extension path to
execute"
Set Authentication.
Select the application node ("api")
Double click "Authentication"
Right click "Anonymous Authentication"
Click "edit"
Check "Application pool identity"

Deploy as Microsoft IIS module 24


Delphi MVC Framework

Deploy as Windows Service module

Deploy as Windows Service module 25

Das könnte Ihnen auch gefallen