DelphiMVCFramework 3.2.0-boron-RC2
Pre-releaseDelphiMVCFramework 3.2.0-boron (currently in RC phase)
WARNING! Considering the huge amount of features added in 3.1.1-beryllium during its RC phase, the dmvcframework-3.1.1-beryllium has been renamed to dmvcframework-3.2.0-boron
- New! Added Swagger support (thanks to João Antônio Duarte and Geoffrey Smith)
- New! Added SQLGenerator and RQL compiler for PostgreSQL, SQLite and MSSQLServer (in addition to MySQL, MariaDB, Firebird and Interbase)
- New! Added support for interfaces serialization - now it is possible to serialize Spring4D collections (thanks to João Antônio Duarte)
- New! Added support for Spring4D Nullable Types - check (thanks to João Antônio Duarte)
- Added
TMVCJSONRPCExecutor.ConfigHTTPClientto fully customize the innerTHTTPClient(e.g.ConnectionTimeout,ResponseTimeoutand so on) - Improved! Greatly improved support for HATEOAS in renders. Check
TRenderSampleController.GetPeople_AsObjectList_HATEOSand all the others actions end withHATEOSinrenders.dprojsample)
//Now is really easy to add "_links" property automatically for each collection element while rendering
Render<TPerson>(People, True,
procedure(const APerson: TPerson; const Links: IMVCLinks)
begin
Links.AddRefLink
.Add(HATEOAS.HREF, '/people/' + APerson.ID.ToString)
.Add(HATEOAS.REL, 'self')
.Add(HATEOAS._TYPE, 'application/json')
.Add('title', 'Details for ' + APerson.FullName);
Links.AddRefLink
.Add(HATEOAS.HREF, '/people')
.Add(HATEOAS.REL, 'people')
.Add(HATEOAS._TYPE, 'application/json');
end);
//Datasets have a similar anon method to do the same thing
Render(lDM.qryCustomers, False,
procedure(const DS: TDataset; const Links: IMVCLinks)
begin
Links.AddRefLink
.Add(HATEOAS.HREF, '/customers/' + DS.FieldByName('cust_no').AsString)
.Add(HATEOAS.REL, 'self')
.Add(HATEOAS._TYPE, 'application/json');
Links.AddRefLink
.Add(HATEOAS.HREF, '/customers/' + DS.FieldByName('cust_no').AsString + '/orders')
.Add(HATEOAS.REL, 'orders')
.Add(HATEOAS._TYPE, 'application/json');
end);
//Single object rendering allows HATEOAS too!
Render(lPerson, False,
procedure(const AObject: TObject; const Links: IMVCLinks)
begin
Links.AddRefLink
.Add(HATEOAS.HREF, '/people/' + TPerson(AObject).ID.ToString)
.Add(HATEOAS.REL, 'self')
.Add(HATEOAS._TYPE, TMVCMediaType.APPLICATION_JSON);
Links.AddRefLink
.Add(HATEOAS.HREF, '/people')
.Add(HATEOAS.REL, 'people')
.Add(HATEOAS._TYPE, TMVCMediaType.APPLICATION_JSON);
end);
- Better packages organization (check
packagesfolder) - New!
TMVCActiveRecord.Countmethod (e.g.TMVCActiveRecord.Count(TCustomer)returns the number of records for the entity mapped by the classTCustomer) - Change!
TMVCACtiveRecord.GetByPK<T>raises an exception if the record is not found - New!
containsclause has been added in the RQL compiler for Firebird and Interbase - New!
TMVCAnalyticsMiddlewareto do automatic analytics on the API (generates a CSV file). Based on an idea by Nirav Kaku (https://www.facebook.com/nirav.kaku). Check the sample in\samples\middleware_analytics\ - New!
TMVCActiveRecord.DeleteAlldeletes all the records from a table - New!
TMVCActiveRecord.DeleteRQLdeletes records using anRQLexpression aswhereclause. - New! Microsoft SQLServer Support in
MVCActiveRecordand RQL (thanks to one of the biggest Delphi based company in Italy which heavily uses DMVCFramework and DMSContainer) - New! SQLite support in
MVCActiveRecordand RQL, so thatMVCActiveRecordcan be used also for Delphi mobile projects! - Default JSON Serializer can verbatim pass properties with type
JsonDataObjects.TJSONObjectwithout usingstringas carrier of JSON - Improved!
ActiveRecordShowCasesample is much better now. - Improved! In case of unhandled exception
TMVCEngineis compliant with the default response content-type (usually it did would reply usingtext/plain). - Breaking Change! In
MVCActiveRecordattributeMVCPrimaryKeyhas been removed and merged withMVCTableField, so nowTMVCActiveRecordFieldOptionis a set offoPrimaryKey,foAutoGenerated,foTransient(checkactiverecord_showcase.dprojsample). - Breaking Change!
TDataSetHolderdoesn't renders dataset in a property calleditemsbut in a property nameddata(to be more standard) - Added! New overloads for all the Log* calls. Now it is possible to call
LogD(lMyObject)to get loggedlMyObjectas JSON (custom type serializers not supported in log). - New!
StrDict(array of string, array of string)function allows to render a dictionary of strings in a really simple way. See the following action sample.
procedure TMy.GetPeople(const Value: Integer);
begin
if Value mod 2 <> 0 then
begin
raise EMVCException.Create(HTTP_STATUS.NotAcceptable, 'We don''t like odd numbers');
end;
Render(
StrDict(
['id', 'message'],
['123', 'We like even numbers, thank you for your ' + Value.ToString]
));
end;- New! Custom Exception Handling (Based on work of David Moorhouse). Sample "custom_exception_handling" show how to use it.
- Improved! Exceptions rendering while using MIME types different to
application/json. - Improved! JSONRPC Automatic Object Publishing can not invoke inherited methods if not explicitly defined with
MVCInheritableattribute. - Improved! Datasets serialization speed improvement. In some case the performance improves of 2 order of magnitude. (Thanks to https://github.com/pedrooliveira01)
- New! Added
inoperator in RQL parser (Thank you to João Antônio Duarte for his initial work on this) - New! Added
TMVCActiveRecord.Count<T>(RQL)to count record based on RQL criteria - New! Calling
<jsonrpcendpoint>/describereturns the methods list available for that endpoint. - New! Experimental (alpha stage) support for Android servers!
- New! Added support for
X-HTTP-Method-Overrideto work behind corporate firewalls. - New Sample! Server in DLL
- Added new method in the dataset helper to load data into a dataset from a specific JSONArray property of a JSONObject
procedure TDataSetHelper.LoadJSONArrayFromJSONObjectProperty(const AJSONObjectString: string; const aPropertyName: String); - Improved! New constants defined in
HTTP_STATUSto better describe the http status response. - Improved! Now Firebird RQL' SQLGenerator can include primary key in
CreateInsertif not autogenerated. - New! Added support for
TArray<String>,TArray<Integer>andTArray<Double>in default JSON serializer (Thank you Pedro Oliveira) - Improved JWT Standard Compliance! Thanks to Vinicius Sanchez for his work on issue #241
- Improved! DMVCFramework now has 130+ unit tests that checks its functionalities at each build!
- New!
StrToJSONObjectfunction to safely parse a string into a JSON object. - New! Serialization callback for custom
TDataSetdescendants serialization inTMVCJsonDataObjectsSerializer.
procedure TMainForm.btnDataSetToJSONArrayClick(Sender: TObject);
var
lSer: TMVCJsonDataObjectsSerializer;
lJArray: TJSONArray;
begin
FDQuery1.Open();
lSer := TMVCJsonDataObjectsSerializer.Create;
try
lJArray := TJSONArray.Create;
try
lSer.DataSetToJsonArray(FDQuery1, lJArray, TMVCNameCase.ncLowerCase, [],
procedure(const aField: TField; const aJsonObject: TJSONObject; var Handled: Boolean)
begin
if SameText(aField.FieldName, 'created_at') then
begin
aJsonObject.S['year_and_month'] := FormatDateTime('yyyy-mm', TDateTimeField(aField).Value);
Handled := True;
end;
end);
//The json objects will not contains "created_at" anymore, but only "year_and_month".
Memo1.Lines.Text := lJArray.ToJSON(false);
finally
lJArray.Free;
end;
finally
lSer.Free;
end;
end;-
New! Shortcut render' methods which simplify RESTful API development
procedure ResponseCreated(const Location: String = ''; const Reason: String = 'Created'); virtual;procedure ResponseAccepted(const HREF: String; const ID: String; const Reason: String = 'Accepted'); virtual;procedure ResponseNoContent(const Reason: String = 'No Content'); virtual;
-
Added de/serializing iterables (e.g. generic lists) support without
MVCListOfattribute (Thank you to João Antônio Duarte).It is now possible to deserialize a generic class like this:
TGenericEntity<T: class> = class private FCode: Integer; FItems: TObjectList<T>; FDescription: string; public constructor Create; destructor Destroy; override; property Code: Integer read FCode write FCode; property Description: string read FDescription write FDescription; // MVCListOf(T) <- No need property Items: TObjectList<T> read FItems write FItems; end;
Before it was not possible because you should add the
MVCListOfattribute to theTObjectListtype property. -
New! The MVCAREntitiesGenerator can optionally register all the generated entities also in the
ActiveRecordMappingRegistry(Thanks to Fabrizio Bitti from bit Time Software) -
Fixed! issue184
-
Fixed! issue278
-
Fixed! issue164
-
Fixed! issue182
-
Fixed! issue232 (Thanks to João Antônio Duarte)
-
New Installation procedure!
- Open the project group (select the correct one from the following table)
- Build all
- Install the design-time package (
dmvcframeworkDT) - Add the following paths in the Delphi Library Path (here,
C:\DEV\dmvcframeworkis thedmvcframeworkmain folder)C:\DEV\dmvcframework\sourcesC:\DEV\dmvcframework\lib\loggerproC:\DEV\dmvcframework\lib\swagdoc\SourceC:\DEV\dmvcframework\lib\dmustache
| Delphi Version | Project Group |
|---|---|
| Delphi 10.3 Rio | packages\d103\dmvcframework_group.groupproj |
| Delphi 10.2 Tokyo | packages\d102\dmvcframework_group.groupproj |
| Delphi 10.1 Berlin | packages\d101\dmvcframework_group.groupproj |
| Delphi 10.0 Seattle | packages\d100\dmvcframework_group.groupproj |