XDefault with nil-Object

Hello,

is there a way to do something like the following line in implementing a XData service?
I would like to default the parameter object "config" to an nil pointer.

    [HttpPost][URIPathSegment('CheckUser')]function CheckUser(kpid: Integer; [XDefault(nil)]const config: TkshCheckConfig): TList<TkshCheckData>; overload;

Regards
Harald

I don't think that would be possible, default parameters are only available for scalar types.

Thank You for Your answer. I understand that it would be difficult to define a default object. Without knowing what lies behind all this: Would it be possible to have an attribute something like this [XDefaultNil]. Even if it is not possible to define a whole object as a default - maybe it would be possible to define a default "nil"-object?
It would be nice to be able to omit the whole object when there is nothing of it to be set.

Background of my request is that I'm looking for a possibility to add an optional parameter (in fact, many optional parameters) to some requests, maybe for configuring the output. Imagine a method that looks for some Data - and format these as a csv-file. There are default parameters and You do not have to configure the whole request. But if You like you can add some parameters to configure the csv-format like delimiter char... Of course it would be possible to do this in a lot of optional parameters, but it would be more elegant to do this in an object with all the possible parameters.

So for default requests it would be a very simple format like

look_for_something(parentid);

and for more advanced requests it would look like

look_for_something(parentid, delimiterchar, linebreak, escapechar...);

Regards
Harald

My suggestion is that you wrap all parameters inside a bigger DTO object.
So instead of declaring the method like this:

look_for_something(parentid, delimiterchar, linebreak, escapechar...);

You would do something like this:

TSomethingParams = class
   parentid: Integer;
   delimiterchar: Nullable<string>;
   linebreak: Nullable<string>;
   escapechar: Nullable<string>;

look_for_something(SomethingParams);

If it makes sense you can even wrap chars and line breaks in a separate class, like TCharOptions which you can reuse in other methods.

Hello Wagner,

thank You for Your suggestion. This would indeed be an elegant way to solve my "problem". I can document this even in swagger - and then everything is ok.

Kind regards
Harald

What I've done in these situations, similar to Wagner's suggestion, is to have a parameter called "Parameters" that is a JSON string - the caller can pass in whatever key-value pairs they like this way, or anything else, really, and the list of keys that are accepted/expected can be documented. There have also been instances where I've just created multiple endpoints with different parameters where some additional clarity or control might be helpful.

1 Like

Thank You for this interesting idea. This way it would even be possible to make the string parameter with XDefault and omit it then totally. I will check this - how easy it is to encode the json to a string and decode it again.

Just a bit of knowledge I gained while experimenting with the different options:

Using a GET-method, You can do something like this:

[HttpGet]  function BackupTableToFile(const tablename: string; const param: TTableBackupParams): TJSONObject;

type
  TTableBackupParams = class
    filename: string;
    stamp: string;
  end;

with this definition you can call the method with these variants:

  • BackupTableToFile?tablename='customers'&filename='customers.backup' // WORKS!
  • BackupTableToFile?TableName='customers'&FileName='customers.backup' // WORKS! - note the upper and lower case letters
  • BackupTableToFile?tablename='customers' // WORKS! - omitting the filename
  • BackupTableToFile?filename='customers.backup' // DOES NOT WORK! - omitting the tablename

Using a POST-method you can do something like this

[HttpPost]  function BackupTableToFile(const tablename: string; const param: TTableBackupParams): TJSONObject;
  • BackupTableToFile - POST-DATA: { “tablename": "customers", “param”: { "filename": "customers.backup" } } // WORKS!
  • BackupTableToFile - POST-DATA: { “TableName": "customers", “Param”: { "Filename": "customers.backup" } } // DOES NOT WORK! - note the upper and lower case letters
  • BackupTableToFile - POST-DATA: { “tablename": "customers", “param”: { } } // WORKS!
  • BackupTableToFile - POST-DATA: { “param”: { "filename": "customers.backup" } } // DOES NOT WORK!
  • BackupTableToFile - POST-DATA: { “tablename": "customers" } // WORKS!
2 Likes

Exactly. All assumptions/tests correct, and all is expected behavior.