DelphiMVCFramework

DelphiMVCFramework Logo

You can find updated information on the DMVCFramework github repo

What's DMVCFramework

DelphiMVCFramework (or DMVCFramework for short) is a popular and powerful framework for web solution in Delphi. With DMVCFramework you can create RMM3 REST services, JSON-RPC services, server side pages, web sites, web applications, mobile backends and more. If you need to comunicate over the network, even Internet, is a standard and simple way, DMVCFramework is for you. In addition, DMVCFramework is very simple to use and is used in production since 2010. Some of the most heavy traffic Delphi systems are powered by DMVCFramework.

Daniele (the project leader) is working on the DelphiMVCFramework Handbook! Stay tuned!

DelphiMVCFramework is the most popular Delphi project on github!

As revealed by an Embarcadero analisys, DMVCFramework is the most popular Delphi project on github since 2017. You can find more info reading the nice article "Top 10 Most Popular Open Source Delphi Projects On GitHub By Star Rating".

DelphiMVCFramework Main Features

  • Simple to use, check the "Getting Started: 5 minutes guide" and you will be up and running in 5 minutes or less!
  • Project Roadmap is always public
    • More than 40 samples to learn all the features and be proficient and productive
  • RESTful (RMM Level 3) compliant
  • JSON-RPC 2.0 Support with automatic objects remotization
  • Stable and solid, used by small/mid/big projects since 2010
  • Very fast! (3.x is 60% faster than the 2.x)
  • Support group at https://www.facebook.com/groups/delphimvcframework with more than 2100 active members
  • Can be used in load balanced environment
  • Wizard for the Delphi IDE. It makes DelphiMVCFramework even more simple to use!
  • Optional session support
  • JSON Web Token Support (JWT)
  • Extendable using middlewares (simple hooks to handle request/response)
  • Flexible yet simple to use, authorization/authentication framework based on industry standards.
    • HTTP Basic Authentication
    • JWT Authentication
    • Custom Authentication
  • CORS support
  • Controllers inheritance! You can define your own base controller and inherith from it.
  • Fancy URL with parameter mappings
  • Specialied renders to generate text, HTML, JSON.
  • Powerful and customizable mapper to serialize/deserialize data.
  • Can be packaged as stand alone server, apache module (XE6 or better) and ISAPI dll
  • Integrated RESTClient
  • Works with XE7, XE8, Delphi 10 Seattle, Delphi 10.1 Berlin, Delphi 10.2 Tokyo
  • Works on Linux (Delphi 10.2 Tokyo or better)
  • Completely unit tested
  • There is a sample for each functionality
  • There is a complete set of trainings about it, but the samples are included in the project
  • Server side generated pages using Mustache (https://mustache.github.io/) for Delphi (https://github.com/synopse/dmustache)
  • Specific trainings are available (email to professionals@bittime.it for a date and a place)
  • Messaging extension using ServerSentEvents
  • Automatic documentation through /system/describeserver.info
  • Driven by its huge community (Facebook group https://www.facebook.com/groups/delphimvcframework)
  • Semantic Versioning
  • Simple and documented

Trainings, consultancy or custom development service

As you know, good support on open source software is a must for professional users. 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 on bittimeprofessionals website. bit Time Professionals is the company behind DelphiMVCFramework, al the main developers works there.

Getting Started

Below the is a basic sample of a DMVCFramework server wich can be deployed as stand-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).

To create this server, you have to create a new Delphi Projects -> WebBroker -> WebServerApplication. Then add the following changes to the webmodule.

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);
  MVC.Config[TMVCConfigKey.DocumentRoot] := 'public_html'; //if you need some static html, javascript, etc (optional)
  MVC.AddController(TUsersController); //see next section to know how to create a controller
end;

procedure TWebModule1.WebModuleDestroy(Sender: TObject);
begin
  MVC.Free;
end;

end.

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. That's it! You have just created your first DelphiMVCFramework. Now you have to add a controller to respond to the http request.

Sample Controller

Below a basic sample of a DMVCFramework controller with 2 action

unit UsersControllerU;

interface

uses 
  MVCFramework;

type 
   [MVCPath('/users')]
   TUsersController = class(TMVCController)
   public

    //The following action will be with a GET request like the following
    //http://myserver.com/users/3
    [MVCPath('/($id)')]
    [MVCProduces('application/json')]
    [MVCHTTPMethod([httpGET])]
    [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])]
    [MVCDoc('Returns the users list as a JSON Array of JSON Objects')]
    procedure GetUsers;

    //The following action will be with a PUT request like the following
    //http://myserver.com/users/3
    //and in the request body there should be a serialized TUser
    [MVCPath('/($id)')]
    [MVCProduce('application/json')]
    [MVCHTTPMethod([httpPUT])]
    [MVCDoc('Update a user')]    
    procedure UpdateUser(id: Integer);

    //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])]
    [MVCDoc('Create a new user, returns the id of the new user')]
    procedure CreateUser;

  end;

implementation

uses
  MyTransactionScript; //contains actual data access code

{ TUsersController }

procedure TUsersController.GetUsers;
var
  Users: TObjectList<TUser>;
begin
  Users := GetUsers;
  Render(Users);
end;

procedure TUsersController.GetUser(id: Integer);
var
  User: TUser;
begin
  User := GetUserById(id);
  Render(User);
end;

procedure TUsersController.UpdateUser(id: Integer);
var
  User: TUser;
begin
  User := Context.Request.BodyAs<TUser>;
  UpdateUser(id, User);
  Render(User);
end;    

procedure TUsersController.CreateUser;
var
  User: TUser;
begin
  User := Context.Request.BodyAs<TUser>;
  CreateUser(User);
  Render(User);
end;    

end.

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)

Quick Creation of DelphiMVCFramework Server

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:

uses
  MVCFramework.Server,
  MVCFramework.Server.Impl;

var
  LServerListener: IMVCListener;
begin
  LServerListener := TMVCListener.Create(TMVCListenerProperties.New
     .SetName('Listener1')
     .SetPort(5000)
     .SetMaxConnections(1024)
     .SetWebModuleClass(YourServerWebModuleClass)
   );  

  LServerListener.Start;
  LServerListener.Stop;
end;

If you want to add a layer of security (in its WebModule you should add the security middleware):

uses
  MVCFramework.Server,
  MVCFramework.Server.Impl,
  MVCFramework.Middleware.Authentication;

procedure TTestWebModule.WebModuleCreate(Sender: TObject);
begin
  FMVCEngine := TMVCEngine.Create(Self);

  // Add Yours Controllers
  FMVCEngine.AddController(TYourController);

  // 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
        )
    ));
end;  

In stand alone mode you can work with a context that supports multiple listeners servers:

uses
  MVCFramework.Server,
  MVCFramework.Server.Impl;

var
  LServerListenerCtx: IMVCListenersContext;

begin
  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;
end;  

Links

Feel free to ask questions on the Delphi MVC Framework group on facebook.