Skip to content

Commit

Permalink
Improved enum and set parameters handling in JSONRPC API
Browse files Browse the repository at this point in the history
  • Loading branch information
danieleteti committed Aug 10, 2022
1 parent de6e796 commit f79f472
Show file tree
Hide file tree
Showing 10 changed files with 340 additions and 96 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ The current beta release is named 3.2.2-nitrogen. If you want to stay on the-edg

- ⚡New `TMVCRESTClient` implementation based on *Net components, the previous one was based on INDY Components (thanks to [João Antônio Duarte](https://github.com/joaoduarte19)).

- ⚡New! `MVCJSONRPCAllowGET` attribute allows a remote JSON-RPC published object, or a specific method, to be called using GET HTTP Verb as well as POST HTTP Verb. POST is always available, GET is available only if explicitly allowed. `IMVCJSONRPCExecutor` allows to specify which HTTP Verb to use when call the server JSON.RPC methods. The default verb can be injected in the constructor and each `ExecuteRequest`/`ExecuteNotification` allows to override od adhere to the instance default.
- ⚡New! `MVCJSONRPCAllowGET` attribute allows a remote JSON-RPC published object, or a specific method, to be called using GET HTTP Verb as well as POST HTTP Verb. POST is always available, GET is available only if explicitly allowed. `IMVCJSONRPCExecutor` allows to specify which HTTP Verb to use when call the server JSON-RPC methods. The default verb can be injected in the constructor and each `ExecuteRequest`/`ExecuteNotification` allows to override od adhere to the instance default.

- ⚡New! eLua server side view support added! The View engine requires Lua's dlls so it is not included in the main package but in a sampl project. Check `serversideviews_lua` sample.

Expand Down Expand Up @@ -573,6 +573,8 @@ The current beta release is named 3.2.2-nitrogen. If you want to stay on the-edg
- ✅ Improved error handling for JSON-RPC APIs (Thanks to [David Moorhouse](https://github.com/fastbike)). More info [here](https://github.com/danieleteti/delphimvcframework/issues/538).
- ✅ Improved parameter handling for enum and set in JSON-RPC APIs.
- ⚡ New! Added `ActiveRecordConnectionRegistry.AddDefaultConnection(const aConnetionDefName: String)`. The connection definition **must** be known by FireDAC. This method simplifies the most common scenario shown below.
```delphi
Expand Down
3 changes: 3 additions & 0 deletions samples/commons/BusinessObjectsU.pas
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ interface

type

TEnumTest = (etValue1, etValue2, etValue3);
TSetOfEnumTest = set of TEnumTest;

[MVCNameCase(ncLowerCase)]
TPerson = class
private
Expand Down
15 changes: 15 additions & 0 deletions samples/jsonrpc_with_published_objects/MyObjectU.pas
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ TMyObject = class
procedure RaiseCustomException;
function RaiseGenericException(const ExceptionType: Integer): Integer;
function SaveObjectWithJSON(const WithJSON: TJsonObject): TJsonObject;
//enums and sets support
function PassingEnums(Value1: TEnumTest; Value2: TEnumTest): TEnumTest;

//records support
function SavePersonRec(PersonRec: TTestRec): TTestRec;
function GetPeopleRecDynArray: TTestRecDynArray;
Expand Down Expand Up @@ -123,6 +126,18 @@ procedure TMyObject.DoSomething;

end;

function TMyObject.PassingEnums(Value1, Value2: TEnumTest): TEnumTest;
begin
if Value1 = Value2 then
begin
Result := TEnumTest.ptEnumValue4;
end
else
begin
Result := TEnumTest.ptEnumValue3;
end;
end;

function TMyObject.EchoComplexArrayOfRecords(
PeopleList: TTestRecDynArray): TTestRecDynArray;
begin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ var
begin
Writeln('** DMVCFramework Server ** build ' + DMVCFRAMEWORK_VERSION);
Writeln('JSON-RPC Server with Published Objects');
Writeln('Listening on port ', APort);

LServer := TIdHTTPWebBrokerBridge.Create(nil);
try
Expand Down
47 changes: 41 additions & 6 deletions sources/MVCFramework.JSONRPC.pas
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,13 @@ interface
uses
System.Classes,
Data.DB,
System.SysUtils,
jsondataobjects,
MVCFramework,
MVCFramework.Commons,
System.Rtti,
System.Generics.Collections,
MVCFramework.Serializer.Commons,
MVCFramework.Serializer.JsonDataObjects;
MVCFramework.Serializer.JsonDataObjects, System.SysUtils;

const
JSONRPC_VERSION = '2.0';
Expand Down Expand Up @@ -878,6 +877,7 @@ procedure JSONDataValueToTValueParam(
end;

procedure JSONDataValueToTValueParamEx(
const JSONSerializer: TMVCJsonDataObjectsSerializer;
const JSONDataValue: TJsonDataValueHelper;
const RTTIParameter: TRttiParameter;
var ParamValue: TValue;
Expand Down Expand Up @@ -940,13 +940,34 @@ procedure JSONDataValueToTValueParamEx(
end;
end
end;
tkSet:
begin
if JSONDataValue.Typ <> jdtString then
begin
RaiseDeSerializationError('Cannot deserialize type ' + RTTIParameter.ParamType.Name);
end;
I := StringToSet(
RTTIParameter.ParamType.Handle,
StringReplace(JSONDataValue.Value, ' ', '', [rfReplaceAll]));
TValue.Make(I, RTTIParameter.ParamType.Handle, ParamValue);
end;
tkEnumeration:
begin
if JSONDataValue.Typ <> jdtBool then
if JSONDataValue.Typ = jdtBool then
begin
raise EMVCJSONRPCInvalidRequest.Create(BuildDeclaration(RTTIParameter));
ParamValue := JSONDataValue.BoolValue;
end
else
begin
JSONSerializer.ParseStringAsTValueUsingMetadata(
JSONDataValue.Value,
RTTIParameter.ParamType.Handle,
'type ' + RTTIParameter.ParamType.Name,
RTTIParameter.ParamType.GetAttributes,
ParamValue
);
end;
ParamValue := JSONDataValue.BoolValue;

end;
tkInteger:
begin
Expand Down Expand Up @@ -1594,6 +1615,18 @@ procedure TMVCJSONRPCController.Index;
lJSONResp := CreateError(lReqID, E.JSONRPCErrorCode, E.Message, E.JSONRPCErrorData);
LogE(Format('[JSON-RPC][CLS %s][ERR %d][MSG "%s"]', [E.ClassName, E.JSONRPCErrorCode, E.Message]));
end;
on ExDeSer: EMVCDeserializationException do
begin
ResponseStatus(400);
lJSONResp := CreateError(lReqID, JSONRPC_ERR_INVALID_REQUEST, ExDeSer.Message, ExDeSer.DetailedMessage);
LogE(Format('[JSON-RPC][CLS %s][ERR %d][MSG "%s"]', [ExDeSer.ClassName, JSONRPC_ERR_INVALID_REQUEST, ExDeSer.Message]));
end;
on ExSer: EMVCSerializationException do
begin
ResponseStatus(400);
lJSONResp := CreateError(lReqID, JSONRPC_ERR_INTERNAL_ERROR, ExSer.Message, ExSer.DetailedMessage);
LogE(Format('[JSON-RPC][CLS %s][ERR %d][MSG "%s"]', [ExSer.ClassName, JSONRPC_ERR_INTERNAL_ERROR, ExSer.Message]));
end;
on Ex: Exception do // use another name for exception variable, otherwise E is nil!!
begin
//lJSONResp := CreateError(lReqID, 0, Ex.Message);
Expand All @@ -1608,7 +1641,7 @@ procedure TMVCJSONRPCController.Index;
try
if not lExceptionHandled then
begin
lJSONResp := CreateError(lReqID, 0, Ex.Message);
lJSONResp := CreateError(lReqID, 0, Ex.Message, Ex.ClassName);
end
else
begin
Expand Down Expand Up @@ -1750,6 +1783,7 @@ function TMVCJSONRPCController.InvokeMethod(const fRPCInstance: TObject;
for I := 0 to lJSONParams.Count - 1 do
begin
JSONDataValueToTValueParamEx(
fSerializer,
lJSONParams[I],
lRTTIMethodParams[I],
lParamsArray[I],
Expand All @@ -1765,6 +1799,7 @@ function TMVCJSONRPCController.InvokeMethod(const fRPCInstance: TObject;
for I := 0 to lJSONNamedParams.Count - 1 do
begin
JSONDataValueToTValueParamEx(
fSerializer,
GetJsonDataValueHelper(lJSONNamedParams, lRTTIMethodParams[I].Name.ToLower),
lRTTIMethodParams[I],
lParamsArray[I],
Expand Down
1 change: 1 addition & 0 deletions sources/MVCFramework.Serializer.Commons.pas
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,7 @@ function ObjectDict(const OwnsValues: Boolean = True): IMVCObjectDictionary;
function GetPaginationMeta(const CurrPageNumber: UInt32; const CurrPageSize: UInt32;
const DefaultPageSize: UInt32; const URITemplate: string): TMVCStringDictionary;
procedure RaiseSerializationError(const Msg: string);
procedure RaiseDeSerializationError(const Msg: string);

implementation

Expand Down
Loading

0 comments on commit f79f472

Please sign in to comment.