2016-10-14 12:27:52 +02:00
![DelphiMVCFramework Logo ](https://github.com/danieleteti/delphimvcframework/blob/master/docs/dmvcframework_logofacebook.png )
2016-10-14 12:28:44 +02:00
##DelphiMVCFramework Main Features
2016-02-27 10:27:01 +01:00
* Simple to use, check the ["Getting Started: 5 minutes guide" ](https://danieleteti.gitbooks.io/delphimvcframework/content/chapter_getting_started.html ) and you will be up and running in 5 minutes or less!
2016-09-10 15:52:56 +02:00
* [Project Roadmap ](delphimvcframework/roadmap.md ) is always public
2016-11-18 14:09:54 +01:00
* More than 40 samples to learn all the features and be proficient and productive
2015-05-28 14:34:33 +02:00
* RESTful (RMM Level 3) compliant
2016-02-19 12:09:14 +01:00
* Stable and solid, used by small/mid/big projects since 2010
2016-11-18 14:09:54 +01:00
* Support group at https://www.facebook.com/groups/delphimvcframework with more than 950 active members
2015-05-28 14:34:33 +02:00
* Can be used in load balanced environment using Redis (http://Redis.io) [dev]
2016-05-21 22:15:35 +02:00
* Can be used in load balanced environment using MySQL [user contrib]
* Wizard for the Delphi IDE. It makes DelphiMVCFramework even more simple to use!
2016-02-19 12:09:14 +01:00
* Optional session support
2016-05-21 22:15:35 +02:00
* JSON Web Token Support (JWT)
2016-02-19 12:09:14 +01:00
* Extendable using middlewares (simple hooks to handle request/response)
2016-05-21 22:15:35 +02:00
* CORS support
2016-02-19 12:09:14 +01:00
* Basic Authentication
* Controllers inheritance
2015-05-28 14:34:33 +02:00
* Fancy URL with parameter mappings
2016-05-21 22:15:35 +02:00
* Specialied renders to generate text, HTML, JSON
2015-05-28 14:34:33 +02:00
* Powerful mapper to map json to objects and datasets to objects
2015-10-12 14:17:59 +02:00
* Can be packaged as stand alone server, apache module (XE6 or better) and ISAPI dll
2015-05-28 14:34:33 +02:00
* Integrated RESTClient
2016-04-20 11:04:08 +02:00
* Works with XE3, XE4, XE5, XE6, XE7, XE8, Delphi 10 Seattle, Delphi 10.1 Berlin
2015-05-28 14:34:33 +02:00
* Completely unit tested
2016-02-19 12:09:14 +01:00
* There is a sample for each functionality
2015-05-28 14:34:33 +02:00
* There is a complete set of trainings about it, but the samples are included in the project
2015-11-15 18:37:14 +01:00
* Server side generated pages using Mustache (https://mustache.github.io/) for Delphi (https://github.com/synopse/dmustache)
2015-05-28 14:34:33 +02:00
* Specific trainings are available (ask me for a date and a place)
* Messaging extension using STOMP (beta)
2015-12-18 14:29:40 +01:00
* Automatic documentation through /system/describeserver.info
2016-02-19 12:09:14 +01:00
* Driven by its huge community (Facebook group https://www.facebook.com/groups/delphimvcframework)
2015-05-28 14:41:06 +02:00
* Simple and [documented ](https://github.com/danieleteti/delphimvcframework/blob/master/docs/ITDevCON%202013%20-%20Introduction%20to%20DelphiMVCFramework.pdf )
2016-02-27 10:27:01 +01:00
* Check the [DMVCFramework Developer Guide ](https://danieleteti.gitbooks.io/delphimvcframework/content/ ) (work in progress)
2015-05-28 14:34:33 +02:00
2016-09-06 10:55:41 +02:00
## How to correctly get the repository
DMVCFramework uses a couple of external open source projects, so whe you clone its repository you must retrieve also all the submodule. In the developers guide all the speps are explained, but the git procedure is also repeated below in the screenshot.
![How to get the repository ](https://raw.githubusercontent.com/danieleteti/delphimvcframework/master/docs/dmvcframework_installation.png )
2016-09-10 15:52:56 +02:00
## Roadmap
DelphiMVCFramework roadmap is always updated as-soon-as the features planned are implemented. Check the roadmap [here ](delphimvcframework/roadmap.md ).
2015-12-04 17:01:01 +01:00
## Trainings, consultancy or custom development service
2015-12-04 15:49:10 +01:00
As you know, good support on open source software is a must for professional users.
2015-12-04 17:01:55 +01:00
If you need trainings, consultancy or custom developments on DelphiMVCFramework, send an email to *dmvcframework at bittime dot it* . Alternatively you can send a request using the [contacts forms ](http://www.bittimeprofessionals.it/contatti ) on [bittimeprofessionals website ](http://www.bittimeprofessionals.it ). bit Time Professionals is the company behind DelphiMVCFramework, al the main developers works there.
2015-05-28 14:34:33 +02:00
2015-12-04 15:49:10 +01:00
## Sub Projects
2015-05-28 14:34:33 +02:00
DelphiMVCFramework contains also a lot of indipendent code that can be used in other kind of project.
These are the most notable:
2015-05-28 14:44:01 +02:00
* Mapper (convert JSON in Object and back, ObjectList in JSONArray and back, DataSets in JSONArray or ObjectList and back)
2015-11-15 18:37:14 +01:00
* DelphiRedisClient (https://github.com/danieleteti/delphiredisclient)
2016-09-06 10:55:41 +02:00
* LoggerPro (https://github.com/danieleteti/loggerpro)
2015-05-28 14:34:33 +02:00
##Samples and documentation
DMVCFramework is provided with a lot of examples focused on specific functionality.
2016-02-27 10:27:01 +01:00
All samples are in [Samples ](https://github.com/danieleteti/delphimvcframework/tree/master/samples ) folder.
Check the [DMVCFramework Developer Guide ](https://danieleteti.gitbooks.io/delphimvcframework/content/ ) (work in progress).
2015-05-28 14:34:33 +02:00
2016-09-06 10:55:41 +02:00
#Getting Started
Below the is a basic sample of a DMVCFramework server wich can be deployed as standa-alone application, as an Apache module or as ISAPI dll. This flexibility is provided by the Delphi WebBroker framework (built-in in Delphi since Delphi 4).
The project containes an IDE Expert which make creating DMVCFramework project a breeze. However not all the Delphi version are supported, so here's the manual version (which is not complicated at all).
2015-06-16 10:36:35 +02:00
To create this server, you have to create a new Delphi Projects -> WebBroker -> WebServerApplication. Then add the following changes to the webmodule.
```delphi
unit WebModuleUnit1;
interface
uses System.SysUtils, System.Classes, Web.HTTPApp, MVCFramework {this unit contains TMVCEngine class};
type
TWebModule1 = class(TWebModule)
procedure WebModuleCreate(Sender: TObject);
procedure WebModuleDestroy(Sender: TObject);
private
MVC: TMVCEngine;
public
{ Public declarations }
end;
var
WebModuleClass: TComponentClass = TWebModule1;
implementation
{$R *.dfm}
uses UsersControllerU; //this is the unit where is defined the controller
procedure TWebModule1.WebModuleCreate(Sender: TObject);
begin
MVC := TMVCEngine.Create(Self);
2016-09-06 10:55:41 +02:00
MVC.Config[TMVCConfigKey.DocumentRoot] := 'public_html'; //if you need some static html, javascript, etc (optional)
2015-06-16 10:36:35 +02:00
MVC.AddController(TUsersController); //see next section to know how to create a controller
end;
procedure TWebModule1.WebModuleDestroy(Sender: TObject);
begin
MVC.Free;
end;
end.
```
2015-06-16 10:49:53 +02:00
Remember that the files inside the redist folder *must* be in the executable path or in the system path. If starting the server whithin the IDE doesn't works, try to run the executable outside the IDE and check the dependencies.
2015-06-16 10:36:35 +02:00
That's it! You have just created your first DelphiMVCFramework. Now you have to add a controller to respond to the http request.
2015-05-28 14:34:33 +02:00
#Sample Controller
Below a basic sample of a DMVCFramework controller with 2 action
2015-06-15 23:39:39 +02:00
```delphi
2015-06-15 23:44:45 +02:00
unit UsersControllerU;
interface
uses
MVCFramework;
type
[MVCPath('/users')]
TUsersController = class(TMVCController)
public
2016-06-23 12:40:12 +02:00
2015-06-15 23:44:45 +02:00
//The following action will be with a GET request like the following
//http://myserver.com/users/3
[MVCPath('/($id)')]
2015-11-30 17:15:16 +01:00
[MVCProduces('application/json')]
2015-06-15 23:44:45 +02:00
[MVCHTTPMethod([httpGET])]
2016-06-23 12:40:12 +02:00
[MVCDoc('Returns a user as a JSON object')]
procedure GetUser(id: Integer);
//The following action will be with a GET request like the following
//http://myserver.com/users
[MVCPath('/')]
[MVCProduces('application/json')]
[MVCHTTPMethod([httpGET])]
2015-12-18 14:29:40 +01:00
[MVCDoc('Returns the users list as a JSON Array of JSON Objects')]
2016-06-23 12:40:12 +02:00
procedure GetUsers;
2015-06-15 23:44:45 +02:00
2015-06-16 10:39:46 +02:00
//The following action will be with a PUT request like the following
2015-06-15 23:44:45 +02:00
//http://myserver.com/users/3
//and in the request body there should be a serialized TUser
[MVCPath('/($id)')]
[MVCProduce('application/json')]
2015-06-16 10:39:46 +02:00
[MVCHTTPMethod([httpPUT])]
2015-12-18 14:29:40 +01:00
[MVCDoc('Update a user')]
2016-06-23 12:40:12 +02:00
procedure UpdateUser(id: Integer);
2015-06-16 10:39:46 +02:00
//The following action will respond to a POST request like the following
//http://myserver.com/users
//and in the request body there should be the new user to create as json
[MVCPath]
[MVCProduce('application/json')]
[MVCHTTPMethod([httpPOST])]
2015-12-18 14:29:40 +01:00
[MVCDoc('Create a new user, returns the id of the new user')]
2016-06-23 12:40:12 +02:00
procedure CreateUser;
2015-06-15 23:44:45 +02:00
end;
implementation
uses
MyTransactionScript; //contains actual data access code
{ TUsersController }
2016-06-23 12:40:12 +02:00
procedure TUsersController.GetUsers;
var
Users: TObjectList< TUser > ;
begin
Users := GetUsers;
Render(Users);
end;
2015-06-15 23:44:45 +02:00
2016-06-23 12:40:12 +02:00
procedure TUsersController.GetUser(id: Integer);
2015-06-15 23:44:45 +02:00
var
User: TUser;
begin
2016-06-23 12:40:12 +02:00
User := GetUserById(id);
2015-06-15 23:44:45 +02:00
Render(User);
end;
2016-06-23 12:40:12 +02:00
procedure TUsersController.UpdateUser(id: Integer);
2015-06-15 23:44:45 +02:00
var
User: TUser;
begin
2016-06-23 12:40:12 +02:00
User := Context.Request.BodyAs< TUser > ;
UpdateUser(id, User);
2015-06-15 23:44:45 +02:00
Render(User);
end;
2016-06-23 12:40:12 +02:00
procedure TUsersController.CreateUser;
2015-06-16 10:39:46 +02:00
var
User: TUser;
begin
2016-06-23 12:40:12 +02:00
User := Context.Request.BodyAs< TUser > ;
2015-06-16 10:39:46 +02:00
CreateUser(User);
Render(User);
end;
2015-06-15 23:44:45 +02:00
end.
2015-06-15 23:39:39 +02:00
```
2015-06-15 22:51:36 +02:00
2015-06-16 10:49:53 +02:00
Now you have a performant RESTful server wich respond to the following URLs:
- GET /users/($id) (eg. /users/1, /users/45 etc)
- PUT /users/($id) (eg. /users/1, /users/45 etc with the JSON data in the request body)
- POST /users (the JSON data must be in the request body)
2015-06-15 23:40:30 +02:00
###Quick Creation of DelphiMVCFramework Server
2015-06-15 22:51:36 +02:00
2016-06-16 22:13:35 +02:00
If you dont plan to deploy your DMVCFramework server behind a webserver (apache or IIS) you can also pack more than one listener application server into one single executable. In this case, the process is a bit different and involves the creation of a listener context. However, create a new server is a simple task:
2015-06-15 22:51:36 +02:00
2015-06-15 23:39:39 +02:00
```delphi
2015-06-15 23:44:45 +02:00
uses
2016-06-16 22:13:35 +02:00
MVCFramework.Server,
MVCFramework.Server.Impl;
2015-06-15 23:44:45 +02:00
var
2016-06-16 22:13:35 +02:00
LServerListener: IMVCListener;
2015-06-15 23:44:45 +02:00
begin
2016-06-16 22:13:35 +02:00
LServerListener := TMVCListener.Create(TMVCListenerProperties.New
.SetName('Listener1')
.SetPort(5000)
.SetMaxConnections(1024)
.SetWebModuleClass(YourServerWebModuleClass)
);
LServerListener.Start;
LServerListener.Stop;
2015-06-15 23:44:45 +02:00
end;
2015-06-15 23:39:39 +02:00
```
2015-06-15 22:51:36 +02:00
2016-06-16 22:13:35 +02:00
If you want to add a layer of security (in its WebModule you should add the security middleware):
2015-06-15 22:51:36 +02:00
2015-06-15 23:39:39 +02:00
```delphi
2015-06-15 23:44:45 +02:00
uses
2016-06-16 22:13:35 +02:00
MVCFramework.Server,
MVCFramework.Server.Impl,
MVCFramework.Middleware.Authentication;
2015-06-15 23:44:45 +02:00
procedure TTestWebModule.WebModuleCreate(Sender: TObject);
begin
2016-06-16 22:13:35 +02:00
FMVCEngine := TMVCEngine.Create(Self);
2015-06-15 22:51:36 +02:00
2016-06-16 22:13:35 +02:00
// Add Yours Controllers
FMVCEngine.AddController(TYourController);
2015-06-15 22:51:36 +02:00
2016-06-16 22:13:35 +02:00
// Add Security Middleware
FMVCEngine.AddMiddleware(TMVCBasicAuthenticationMiddleware.Create(
TMVCDefaultAuthenticationHandler.New
.SetOnAuthentication(
procedure(const AUserName, APassword: string;
AUserRoles: TList< string > ; var IsValid: Boolean;
const ASessionData: TDictionary< String , String > )
begin
IsValid := AUserName.Equals('dmvc') and APassword.Equals('123');
end
)
));
2015-06-15 23:44:45 +02:00
end;
2015-06-15 23:39:39 +02:00
```
2015-05-28 14:34:33 +02:00
2016-06-16 22:13:35 +02:00
In stand alone mode you can work with a context that supports multiple listeners servers:
2015-05-28 14:34:33 +02:00
2015-06-15 23:39:39 +02:00
```delphi
2016-06-16 22:13:35 +02:00
uses
MVCFramework.Server,
MVCFramework.Server.Impl;
2015-06-15 23:44:45 +02:00
var
2016-06-16 22:13:35 +02:00
LServerListenerCtx: IMVCListenersContext;
2015-06-15 23:44:45 +02:00
begin
2016-06-16 22:13:35 +02:00
LServerListenerCtx := TMVCListenersContext.Create;
LServerListenerCtx.Add(TMVCListenerProperties.New
.SetName('Listener1')
.SetPort(6000)
.SetMaxConnections(1024)
.SetWebModuleClass(WebModuleClass1)
);
LServerListenerCtx.Add(TMVCListenerProperties.New
.SetName('Listener2')
.SetPort(7000)
.SetMaxConnections(1024)
.SetWebModuleClass(WebModuleClass2)
);
LServerListenerCtx.StartAll;
2015-06-15 23:44:45 +02:00
end;
2015-06-15 23:39:39 +02:00
```
2015-05-28 14:34:33 +02:00
2015-06-15 22:51:36 +02:00
###Links
2015-05-28 14:34:33 +02:00
Feel free to ask questions on the "Delphi MVC Framework" facebook group (https://www.facebook.com/groups/delphimvcframework).
http://www.danieleteti.it/2013/04/18/sneak-peek-to-simple-integration-between-dmvcframework-and-dorm/