vaadin / hilla

Build better business applications, faster. No more juggling REST endpoints or deciphering GraphQL queries. Hilla seamlessly connects Spring Boot and React to accelerate application development.
https://hilla.dev
Apache License 2.0
901 stars 57 forks source link

Add framework level support for detecting when you have different versions of client-side app and server-side endpoints #268

Open mhosio opened 3 years ago

mhosio commented 3 years ago

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.

haijian-vaadin commented 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.

Legioth commented 3 years ago

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.

platosha commented 3 years ago

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:

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.

Legioth commented 3 years ago

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.