httpAPI null value Handling

Hi,

I used sjoson.WriteDataset(cdsResult, [ woRows], -1) to stream data to restclient.

That dataset contain a TDatetime field but it is null value. I’ve defined a TComplexType return back the data say:

function updatedata(srcData : TmyComplexType);

As one of the data member(TDateTime) is null, it already raise exception on parsing the srcData before step into function call. It is exception of cannot convert null variants error.

Then I need at client side to check any null member and set a predefined datatime for null value.

At Server-Side I need check that value and change back to null.

Please advise any better Handling. Say all handling at server side , client side only get the value and return the value only.

Joe

Hi,

are you using TDAJSONDataStreamer, is it correct? if yes, you can use events like OnBeforeFieldValueSerialization/OnWriteFieldValue/OnWriteFieldValueEx for writing 0 instead of null for such fields.

Thanks it work.

However, I hit one issue is as some client is web site or even for outside people to call.

function updatedata(srcData : TmyComplexType);

Like this function, any chance I convert the datamember value first ?
For example:
web client : “post” updatedata (srcData)
RO server: Convert null value
RO server: process updatedata call

as someone may skip somedatamember( i.e use did not input any value) , it because null, when calling it go to exception again.

any chance I can convert it instead of throwing exception?

joe

Hi,

as I understand, you can check values for null at the beginning of your method like

procedure TMyService.updatedata(srcData : TmyComplexType);
begin
  // check srcData's members for null and replace null values with accepted values
  // process std update 
end;

The exception is before enerting the function. during the parsing of the parameter srcdata.

You can define TmyComplexType with TdateTime data member inside.

Then use postman to put null value to that datatime member. Then you can get the case.

please advise

Hi,

HttpApi calls is configured to initialize missing fields with default values.
Can you give to me example of your call with CURL, pls?

you can drop message to support@ for keeping this info in privacy

You can refer below case:

KB_STRUCT = class(TROComplexType)
private
fKB_ID_PK: UnicodeString;
fKB_DT: DateTime;
published
property KB_ID_PK: UnicodeString read fKB_ID_PK write fKB_ID_PK;
property KB_DT: DateTime read fKB_DT write fKB_DT;

end;

C:\Auto-Dvp\Tools\curl-7.63\bin>C:\Auto-Dvp\Tools\curl-7.63\bin\curl -verbose -X POST “http://10.18.18.64:8099/api/getentity” -H “accept: application/json” -H “Content-Type: application/json” -d “{ "IN_KB":{ "KB_DT": "null", "KB_ID_PK": "ID001" }}”
Error reading parameter IN_KB: ‘null’ is not a valid integer value

Why I put KB_DT is null it is becase this value is from DA server json.WriteDataset( (cdsTmpDataset as IDADataset), [woRows], -1);

Below is the call stack for that function.

Also the attached the sample project for reference:
HttpAPITestServer.zip (185.5 KB)

if I use writedataex, it can change all null value however this let client side do many extra work, like null value presentation in UI and null value post back to the server.

Is it any way that I can check value in server side when client post back before parsing the value into the server function call?

Please advise.

Hi,

better solution is omit null values for HTTPApi calls, like

>curl -verbose -X POST "http://localhost:8099/api/getentity" -H  "accept: application/json"  -H  "Content-Type: application/json" -d "{  \"IN_KB\":{ \"KB_ID_PK\": \"ID001\" }}"
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 127.0.0.1:8099...
* Connected to localhost (127.0.0.1) port 8099 (#0)
> POST /api/getentity HTTP/1.1
> Host: localhost:8099
> User-Agent: curl/7.72.0
> Referer: rbose
> accept: application/json
> Content-Type: application/json
> Content-Length: 35
>
* upload completely sent off: 35 out of 35 bytes
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Connection: close
< Content-Type: application/json; charset=utf-8
< Content-Length: 51
< Date: Thu, 03 Mar 2022 14:36:14 GMT
< Accept-Encoding: gzip, identity
<
{"KB_DT":"1899-12-29T21:00:00Z","KB_ID_PK":"ID001"}* Closing connection 0

here is a small difference - datastreamer treats all fields values as variants so those fields can have null values. in your case, you are using Datatime field that cannot be nullable.