#1 2020-08-13 10:29:50

squirrel
Member
Registered: 2015-08-13
Posts: 155

Adding parameters to interface functions in a backwards compatible way

We need to add parameters to the interface functions in our Mormot service.  Since all parameters for interface functions are required values, adding an extra parameter breaks backwards compatibility.  I remember that there is a property that can be set to make parameters not required, but can't remember its name, so can't find it in the documentation (I know it is there somewhere, just don't know how to search for it).

To ensure some form of backward compatibility for future changes to these interface functions, I can see 4 options:
1) Make all parameters for all interface functions optional (using the property mentioned above).  This will have a big impact, since all the interface functions will then need to be changed to manually check whether all the parameters have been supplied and are of the correct type.
2) Add default values for new parameters which will apply if they are not supplied (doesn't look possible)
3) Add a versioning scheme (maybe with url rewrites?) which will add missing parameters with default values before calling the real function ie /v1/User/CreateUser will execute /User/CreateUser after adding the new (if not supplied) parameters to the input
4) Basically replace the input parameters for all interface functions with something generic like:

function TUser.CreateUser(const Parameters: RawJson):integer;

which has the same impact as 1)

I'm sure I'm missing something obvious, but would anybody have suggestions as to what is the correct route to take here?  This service is used by third parties, so ensuring backwards compatibility is all I'm interested in.  However, if I am going to break backwards compatibility with a major version bump, I should apply it to every function.

Offline

#2 2020-08-13 12:27:56

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,656
Website

Re: Adding parameters to interface functions in a backwards compatible way

If you use the JSON object format, not the JSON array, then parameters can be added in the future, and missing parameters will just be ignored and left void (0/''/nil).
See e.g. TSQLRestClientURI.ServiceDefineSharedAPI().

Offline

#3 2020-08-13 13:10:29

squirrel
Member
Registered: 2015-08-13
Posts: 155

Re: Adding parameters to interface functions in a backwards compatible way

That solves about 99% of the issues I was facing.  big_smile Thanks @ab!

Offline

#4 2020-08-14 05:19:36

edwinsn
Member
Registered: 2010-07-02
Posts: 1,218

Re: Adding parameters to interface functions in a backwards compatible way

This thread is useful. For the same requirement (backward compatibility), I had to gone further than you #4 option - I resorted to method-based service - everything is JSON and you'll have to process it.


Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.

Offline

#5 2020-10-22 12:07:39

edwinsn
Member
Registered: 2010-07-02
Posts: 1,218

Re: Adding parameters to interface functions in a backwards compatible way

@ab,

A little issue with using the methods on the client side:
- Called ServiceRegister then ServiceDefineSharedAPI, mORMot will complain about 'interface already registered'.
- use ServiceDefineSharedAPI only mORMot will complain about 'interface not registered'.
- Use "TServiceFactoryClient(ServiceRegister(...)).ParamsAsJSONObject := True" will cause  access violation

Not sure why. had to use the following code instead:

  svcFactory := (Services['ApiForClient'] as TServiceFactoryClient);
  svcFactory.ParamsAsJSONObject := True;
  svcFactory.ResultAsJSONObjectWithoutResult := True;

Last edited by edwinsn (2020-10-22 12:09:23)


Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.

Offline

Board footer

Powered by FluxBB