Releases: danieleteti/delphimvcframework
DelphiMVCFramework 3.2.0-boron-RC7
DelphiMVCFramework 3.2.0-boron-RC7
-
New! Added Nullable support in MVCActiveRecord (nullables defined in
MVCFramework.Nullables.pas)! Check activerecord_showcase sample. -
New! Added non autogenerated primary keys in MVCActiveRecord! Check activerecord_showcase sample.
-
New! Complete support for nullable types in the default serializer (nullables defined in
MVCFramework.Nullables.pas) -
New! Added
ncCamelCaseandncPascalCaseto the available attribute formatters.MVCNameCase Property/Field Name Rendered Name ncUpperCase Cod_Article COD_ARTICLE ncLowerCase Cod_Article cod_article ncPascalCase Cod_Article CodArticle ncPascalCase CodArticle CodArticle ncPascalCase _WITH__UNDERSCORES_WithUnderscores ncCamelCase Cod_Article codArticle ncCamelCase CodArticle codArticle ncCamelCase _WITH__UNDERSCORES_WithUnderscores -
New! Added Swagger support (thanks to João Antônio Duarte and Geoffrey Smith)
-
New! Attribute
MVCDoNotDeserialize. If marked with this RTTI attribute, a property or a field is not deserialized and its value remain the same as was before the object deserialization. -
New! ObjectDict function is the suggested way to render all the most common data types. It returns a
IMVCObjectDictionarywhich is automatically rendered by the renders. Check therenders.dprojsample. Here's some example of the shining newObjectDict()
Example 1: Rendering a list of objects not freeing them after rendering
Classic
procedure TRenderSampleController.GetLotOfPeople;
begin
Render<TPerson>(GetPeopleList, False);
end;
New approach with ObjectDict
procedure TRenderSampleController.GetLotOfPeople;
begin
Render(ObjectDict(False).Add('data', GetPeopleList));
end;
Example 2: Rendering a list of objects and automatically free them after rendering
Classic
procedure TRenderSampleController.GetLotOfPeople;
begin
Render<TPerson>(GetPeopleList);
end;
New approach with ObjectDict
procedure TRenderSampleController.GetLotOfPeople;
begin
Render(ObjectDict().Add('data', GetPeopleList));
end;
Example 3: Rendering a list of objects adding links for HATEOAS support
Classic
procedure TRenderSampleController.GetPeople_AsObjectList_HATEOAS;
var
p: TPerson;
People: TObjectList<TPerson>;
begin
People := TObjectList<TPerson>.Create(True);
{$REGION 'Fake data'}
p := TPerson.Create;
p.FirstName := 'Daniele';
p.LastName := 'Teti';
p.DOB := EncodeDate(1979, 8, 4);
p.Married := True;
People.Add(p);
p := TPerson.Create;
p.FirstName := 'John';
p.LastName := 'Doe';
p.DOB := EncodeDate(1879, 10, 2);
p.Married := False;
People.Add(p);
p := TPerson.Create;
p.FirstName := 'Jane';
p.LastName := 'Doe';
p.DOB := EncodeDate(1883, 1, 5);
p.Married := True;
People.Add(p);
{$ENDREGION}
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);
end;
New approach with ObjectDict
procedure TRenderSampleController.GetPeople_AsObjectList_HATEOAS;
var
p: TPerson;
People: TObjectList<TPerson>;
begin
People := TObjectList<TPerson>.Create(True);
{$REGION 'Fake data'}
p := TPerson.Create;
p.FirstName := 'Daniele';
p.LastName := 'Teti';
p.DOB := EncodeDate(1979, 8, 4);
p.Married := True;
People.Add(p);
p := TPerson.Create;
p.FirstName := 'John';
p.LastName := 'Doe';
p.DOB := EncodeDate(1879, 10, 2);
p.Married := False;
People.Add(p);
p := TPerson.Create;
p.FirstName := 'Jane';
p.LastName := 'Doe';
p.DOB := EncodeDate(1883, 1, 5);
p.Married := True;
People.Add(p);
{$ENDREGION}
Render(ObjectDict().Add('data', People,
procedure(const APerson: TObject; const Links: IMVCLinks)
begin
Links
.AddRefLink
.Add(HATEOAS.HREF, '/people/' + TPerson(APerson).ID.ToString)
.Add(HATEOAS.REL, 'self')
.Add(HATEOAS._TYPE, 'application/json')
.Add('title', 'Details for ' + TPerson(APerson).FullName);
Links
.AddRefLink
.Add(HATEOAS.HREF, '/people')
.Add(HATEOAS.REL, 'people')
.Add(HATEOAS._TYPE, 'application/json');
end));
end;
ObjectDict is able to render multiple data sources (datasets, objectlists, objects or StrDict) at the same time using different casing, HATEOAS callbacks and modes.
procedure TTestServerController.TestObjectDict;
var
lDict: IMVCObjectDictionary;
begin
lDict := ObjectDict(false)
.Add('ncUpperCase_List', GetDataSet, nil, dstAllRecords, ncUpperCase)
.Add('ncLowerCase_List', GetDataSet, nil, dstAllRecords, ncLowerCase)
.Add('ncCamelCase_List', GetDataSet, nil, dstAllRecords, ncCamelCase)
.Add('ncPascalCase_List', GetDataSet, nil, dstAllRecords, ncPascalCase)
.Add('ncUpperCase_Single', GetDataSet, nil, dstSingleRecord, ncUpperCase)
.Add('ncLowerCase_Single', GetDataSet, nil, dstSingleRecord, ncLowerCase)
.Add('ncCamelCase_Single', GetDataSet, nil, dstSingleRecord, ncCamelCase)
.Add('ncPascalCase_Single', GetDataSet, nil, dstSingleRecord, ncPascalCase)
.Add('meta', StrDict(['page'], ['1']));
Render(lDict);
end;
ObjectDict is the suggested way to renders data. However, the other ones are still there and works as usual.
- New! Added SQLGenerator and RQL compiler for PostgreSQL, SQLite and MSSQLServer (in addition to MySQL, MariaDB, Firebird and Interbase)
- New! MVCNameAs attribute got the param
Fixed(default: false). IfFixedis true, then the name is not processed by theMVCNameCaseattribute assigned to the owner type. - 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)
- New! Added
OnRouterLogevent to log custom information for each request (thanks to Andrea Ciotti for the first implementation and its PR) - New! Optionally load system controllers (those who provide
/describeserver.info,/describeplatform.infoand/serverconfig.infosystem actions) settingConfig[TMVCConfigKey.LoadSystemControllers] := 'false';in the configuration block. - Improved! Now the router consider
Accept:*/*compatible for everyMVCProducesvalues - 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 by default if the record is not found - optionally can returnsnilusing new parameterRaiseExceptionIfNotFound - 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! `TMVCActiv...
DelphiMVCFramework 3.2.0-boron-RC6
- New! Added Nullable support in MVCActiveRecord! Check activerecord_showcase sample.
- New! Added non autogenerated primary keys in MVCActiveRecord! Check activerecord_showcase sample.
- New! Complete support for nullable types in the default serializer.
- 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)
- New! Added
OnRouterLogevent to log custom information for each request (thanks to Andrea Ciotti for the first implementation and its PR) - Added
TMVCJSONRPCExecutor.ConfigHTTPClientto fully customize the innerTHTTPClient(e.g.ConnectionTimeout,ResponseTimeoutand so on) - Improved! Now the router consider
Accept:*/*compatible for everyMVCProducesvalues - 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 by default if the record is not found - optionally can returnsnilusing new parameterRaiseExceptionIfNotFound - 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!
TMVCActiveRecord.Storewhich automatically executes Insert or Update considering primary key value. - New!
TMVCActiveRecordallows to use table name and field name with spaces (currently supported only by the PostgreSQL compiler). - 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! All
ActiveRecordmethods which retrieve records can now specify the data type of each parameter (using Delphi'sTFieldTypeenumeration). - Improved! In case of unhandled exception
TMVCEngineis compliant with the default response content-type (usually it did would reply usingtext/plain). - 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. -
New! JSONRPC Hooks for published objects
//Called before as soon as the HTTP arrives procedure TMyPublishedObject.OnBeforeRouting(const JSON: TJDOJsonObject); //Called before the invoked method procedure TMyPublishedObject.OnBeforeCall(const JSONRequest: TJDOJsonObject); //Called just before to send response to the client procedure TMyPublishedObject.OnBeforeSendResponse(const JSONResponse: TJDOJsonObject);
-
SSL Server support for
TMVCListener(Thanks to Sven Harazim) -
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!
TMVCActiveRecordcan handle non autogenerated primary key. -
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 Render201Created(const Location: String = ''; const Reason: String = 'Created'); virtual;procedure Render202Accepted(const HREF: String; const ID: String; const Reason: String = 'Accepted'); virtual;- `procedure...
DelphiMVCFramework 3.2.0-boron-RC5
WARNING! This release fixes a serious vulnerability which affects some deployments which use the built-in WebServer. It doesn't add new features and fix only this issue. However, it is a strongly raccomended update for all dmvcframework users which use the built-in webserver to serve static files.
Many thanks to Stephan Munz to have discovered the bug.
- New! Added Nullable support in MVCActiveRecord! Check activerecord_showcase sample.
- New! Complete support for nullable types in the default serializer.
- 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! Now the router consider
Accept:*/*compatible for everyMVCProducesvalues - 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 by default if the record is not found - optionally can returnsnilusing new parameterRaiseExceptionIfNotFound - 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!
TMVCActiveRecord.Storewhich automatically executes Insert or Update considering primary key value. - 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). - 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. - SSL Server support for
TMVCListener(Thanks to Sven Harazim) - 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;
...
DelphiMVCFramework 3.2.0-boron-RC4
DelphiMVCFramework 3.2.0-boron-RC4
WARNING! Considering the huge amount of features added in 3.1.1-beryllium during its RC phase, the
dmvcframework-3.1.1-berylliumhas been renamed todmvcframework-3.2.0-boron.
If no critical bugs will be found, this version will become the final release
Features added, features improved and bug fixes
- New! Added Nullable support in MVCActiveRecord! Check activerecord_showcase sample.
- New! Complete support for nullable types in the default serializer.
- 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! Now the router consider
Accept:*/*compatible for everyMVCProducesvalues - 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 by default if the record is not found - optionally can returnsnilusing new parameterRaiseExceptionIfNotFound - 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!
TMVCActiveRecord.Storewhich automatically executes Insert or Update considering primary key value. - 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). - 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. - SSL Server support for
TMVCListener(Thanks to Sven Harazim) - 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;...
DelphiMVCFramework 3.2.0-boron-RC2
DelphiMVCFramework 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 `ActiveRecordMappingRegi...
DelphiMVCFramework 3.2.0-boron-RC1
DelphiMVCFramework 3.2.0-boron-RC1 RELEASE NOTES
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)
- 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! - 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
- 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>andTArray<Integer>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 deserializing 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. -
Fixed! issue184
-
Fixed! issue278
-
Fixed! issue164
-
Fixed! issue182
-
Fixed! issue232 (Thanks to Thank you 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)- `...
DelphiMVCFramework 3.1.1-beryllium-RC6
DelphiMVCFramework 3.1.1-beryllium (currently in RC phase)
- New! Added SQLGenerator and RQL compiler for PostgreSQL, SQLite and MSSQLServer (in addition to MySQL, MariaDB, Firebird and Interbase)
- 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 ActiveRecord and RQL (thanks to one of the biggest Delphi based company in Italy which heavily uses DMVCFramework)
- New! SQLite Support in MVCActiveRecord and RQL, so that MVCActiveRecord can be used also for Delphi mobile projects!
- 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). - Fix! issue184.
- Breaking Change! In
MVCActiveRecordattributeMVCPrimaryKeyhas been removed and merged withMVCTableField, so nowTMVCActiveRecordFieldOptionis a set offoPrimaryKey,foAutoGenerated,foTransient(checkactiverecord_showcase.dprojsample). - Added! New overloads for all the Log* calls. Now it is possibile to call
LogD(lMyObject)to get loggedlMyObjectas JSON (custom type serializers not supported in log). - Fixed! issue164
- Fixed! issue182
- 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 explicitely defined with
MVCInheritableattribute. - Improved! Datasets serialization speed improvement. In some case the performace 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
- Improved! New consts defined in
HTTP_STATUSto better describe the http status response. - Improved! Now Firebird RQL' SQLGenerator can include primary key in "createinsert" if not autogenerated.
- New! Added support for
TArray<String>andTArray<Integer>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 funtionalities at each build!
- 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;
- New Installation procedure! Just open the project group, build all and install the design-time package (which is
dmvcframeworkDT)
| 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 |
| Delphi XE8 | packages\dxe8\dmvcframework_group.groupproj |
| Delphi XE7 | packages\dxe7\dmvcframework_group.groupproj |
DelphiMVCFramework 3.1.1-beryllium-RC5
DEAR RC USERS: If no critical bugs will be found in this RC, it will become the official 3.1.1-beryllium final version
- New! Added SQLGenerator and RQL compiler for PostgreSQL and MSSQLServer (in addition to MySQL, MariaDB, Firebird and Interbase)
- 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 ActiveRecord and RQL (thanks to one of the biggest Delphi based company in Italy which heavily uses DMVCFramework)
- 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). - Fix! issue184.
- Breaking Change! In
MVCActiveRecordattributeMVCPrimaryKeyhas been removed and merged withMVCTableField, so nowTMVCActiveRecordFieldOptionis a set offoPrimaryKey,foAutoGenerated,foTransient(checkactiverecord_showcase.dprojsample). - Added! New overloads for all the Log* calls. Now it is possibile to call
LogD(lMyObject)to get loggedlMyObjectas JSON (custom type serializers not supported in log). - Fixed! issue164
- Fixed! issue182
- 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 explicitely defined with
MVCInheritableattribute. - Improved! Datasets serialization speed improvement. In some case the performace 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
- Improved! Now Firebird RQL' SQLGenerator can include primary key in "createinsert" if not autogenerated.
- New! Added support for
TArray<String>andTArray<Integer>in default json serializer (Thank you Pedro Oliveira) - Improved! DMVCFramework now has 130+ unit tests that checks its funtionalities at every build!
- New Installation procedure! Just open the project group, build all and install the design-time package (which is
dmvcframeworkDT)
| 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 |
| Delphi XE8 | packages\dxe8\dmvcframework_group.groupproj |
| Delphi XE7 | packages\dxe7\dmvcframework_group.groupproj |
DelphiMVCFramework 3.1.1-beryllium-RC3
DelphiMVCFramework 3.1.1-beryllium-RC3
- New! Added SQLGenerator and RQL compiler for PostgreSQL (in addition to MySQL, MariaDB, Firebird and Interbase)
- Improved! Greatly improved support for HATEOAS in renders. Check
TRenderSampleController.GetPeople_AsObjectList_HATEOSinrenders.dprojsample)
//Now is really easy to add "_links" property automatically for each collection element while rendering
Render<TPerson>(People, True,
procedure(const Person: TPerson; const Dict: TMVCStringDictionary)
begin
Dict['x-ref'] := '/api/people/' + Person.ID;
Dict['x-child-ref'] := '/api/people/' + Person.ID + '/child';
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 ActiveRecord and RQL (thanks to one of the biggest Delphi based company in Italy which heavily uses DMVCFramework)
- 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). - Fix! issue184.
- Breaking Change! In
MVCActiveRecordattributeMVCPrimaryKeyhas been removed and merged withMVCTableField, so nowTMVCActiveRecordFieldOptionis a set offoPrimaryKey,foAutoGenerated,foTransient(checkactiverecord_showcase.dprojsample). - Added! New overloads for all the Log* calls. Now it is possibile to call
LogD(lMyObject)to get loggedlMyObjectas JSON. - Fixed! issue164
- Fixed! issue182
- New Installation procedure! Just open the project group, build all and install the design-time package (which is
dmvcframeworkDT)
| 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 |
For older Delphi versions still there aren't complete packages available, but DMVCFramework is usable from XE7 without any issues. If you use a version previous of Delphi 10.1 Berlin and you want to contribute, please provide your group project using the distributed packages as example.
DelphiMVCFramework 3.1.0-lithium
What's New in 3.1.0 lithium
- New! Added
TMVCActiveRecordframework (check sampleactiverecord_showcaseandactiverecord_crud) - New! Added
TMVCActiveRecordController(check sampleactiverecord_crud) - Automatic permissions handling for
TMVCActiveRecordController(check sampleactiverecord_crud) - EntityProcessor for
TMVCActiveRecordController(check sampleactiverecord_crud) Config[TMVCConfigKey.FallbackResource]is served only if request path is empty or/.- New! Now the JSON-RPC executor provides methods to handle HTTP headers for JSON-RPC requests and notifications.
TDataSetHolderis a new render that is able to render a dataset with a set of custom metadata (egcount,pageetc). Check issue #137404and500status code returns always atext/plaincontent-type- Refactored ISAPI sample
- Speed improvement! Removed enhanced visibility for action methods. Now only public and published methods can be used as actions.
TMVCController.Createisvirtual! Now on your base controllers can be even more powerful!- New! Added
MAX_REQUEST_SIZEfor limiting the size of the incoming HTTP requests. IDE Expert is updated too! - New! Added method
TMVCJsonDataObjectsSerializer.ListToJsonArray - New!
TMVCResponsefor handle generic (non error) response - New!
TMVCErrorResponsefor handle generic error response - New! Added class
TMVCActiveRecordListused in the manualTMVCActiveRecordprogramming - New! Added
gzipcompression support in addition todeflateinTCompressionMiddleware - FIX for issue #143
- FIX for issue #141
- Removed deprecated methods in
IRESTResponse - FIX misspelled header name in
IRESTResponse - New! Added
gzipanddeflatesupport inTRestClientwhen reading responses TCompressionMiddlewarehas been renamed inTMVCCompressionMiddleware- New!
TMVCCompressionMiddlewareis added by IDE Expert by default - Removed the old JSON serializer based on `System.JSON.pas', now the only available JSON serializer is based on JsonDataObjects parser (Thank you Andreas Hausladen).
- Changed! Custom Types Serializer must be registered by media-type only, without charset definition (e.g. just
application/jsonand notapplication/json;charset=utf-8) - Changed!
IMVCTypeSerializeris more powerful and simple to use! - Sending wrongly formatted JSON now returns a more correctly
400 Bad Requestand not500 Internal Server Erroras in the previous versions - New! Support for Spring4d nullable types (check
samples\renders_spring4d_nullables) - New!
TMVCJSONRPCPublisherallows to easily expose plain Delphi objects (and even datamodules) through a JSON-RPC 2.0 interface! - Breaking Change! The JSON RPC Client layer is now interface based.