Open mhosio opened 3 years ago
One option @mhosio proposed is to have a callback method that will be invoked in such cases. Kind of like the ErrorHandler
in Flow.
For some apps, using the callback to reload the app would probably be enough.
There's two sides to this: detecting the situation and dealing with it.
For detection, we should probably somehow look at signature of the endpoint methods rather than e.g. just looking at whether the server has been redeployed.
Once the situation has been detected, the next question is how to deal with it. Throwing an exception that explicitly tells that it's a version mismatch is already one step better than letting the call fall through and e.g. cause a validation error that doesn't make sense based on what the user is seeing in their application.
An additional optional step could then be to make it easy for the application developer to run application logic when this has happened. Reloading the application without warning sounds quite dangerous since that might discard data that the user has entered into the application. It might indeed make sense to model this as a generic error handler for endpoints so that you can in one place define logic to handle various types of errors that can come from any endpoint (e.g. offline, logged out, version mismatch) rather than creating an API specifically for only this purpose.
After discussing in the team, we don’t have a clear idea on what is a good way of detecting a mismatch. Several approaches were discussed:
Using method signatures alone, as suggested by @Legioth above, feels not reliable enough: the change detection would have a false pass in case if the behaviour of the endpoint was changed, while the signature remained the same.
Using an automatic build number: every application build involves both building client-side and server-side counterparts, a common generated (either auto-increment or random) build number is included in both of them. For every endpoint call, we match the build number from the client with the one on the server, and throw in case of a mismatch.
Pros:
Cons:
Using explicit version annotation: application developers have control over the endpoints version number. The number should be increased manually during development when making incompatible changes on endpoints.
Pros:
Cons:
These approaches could also be combined, for example, defaulting to using an automatic build number check, unless a version is explicitly declared for the particular endpoint class or method. We are not sure if the approaches here are sufficient, and may consider even more ideas, such as using content hash functions.
Personally, I’m inclined to take the automatic build number approach, for its simplicity and reliability, and because it could provide a ground for further enhancements, if needed. Users could workaround false failures, for example, implementing an explicit version check (calling a getVersion
endpoint) in the handler for the automatic build number mismatch error.
Suggestions and comments are welcome.
Regarding the dealing part, as a first step, we should throw an error. It is not yet clear whether we need a specific API for this use case, apart from adding an EndpointVersionError
subclass. We have ways of handling endpoint errors in Fusion already, for example, one might add a client middleware to handle all the endpoint errors of a particular kind in a generic way. The form binder and the offline submission features should be taken into account, as they also involve dealing with endpoint errors.
I assume that a build number would be way too sensitive - we don't want to cause a situation when a simple typo fix cannot be deployed because it might cause disruption for users.
It's also not reasonable to require that application developers explicitly add a version annotation to all their endpoints just so that they could deploy typo fixes without disruption - we could then just as well always require the annotation to be present, which would defeat the purpose of automatic detection.
Fusion enables implementation of most of the application logic using TS. This creates a scenario where the version of the client-side app may differ from the version of the server-side endpoints. Especially so in offline capable apps and PWAs. The version mismatch may make the app fail randomly since the method signatures could differ between client and the server. Would be nice if the framework would provide some help in detecting the situation on the client-side and give the programmer a feasible way to handle the problem.