[Business-]Apps of the future? An idea to cross-platform logic

Recently I have been playing around with an idea, after a few discussions with different people, it seems to be a solution in search of a problem though.
Let me set the stage for how it started:

I was thinking about how it could be made easy to build generic business apps (forms, forms and more forms) better, faster, more flexible & cheaper.

A proven method

What has often been done and implemented in various ways is something like this:

  • The actual apps people are working with are basically thin-clients.
  • The apps interpret some simple declarative language that describes the UI.
  • For all actions/choices etc. they call out to some central server.

How may such a declarative language look like?

view:
elements:
- type: title
label: Purchase order
- type: textfield
id: product
label: Article
- type: textfield
id: amount
label: Amount
- type: button
id: submit
label: Place order
action: /api/businessclient/order/new

How this would work is that the client would interpret this list of elements and basically draw up this:

UI rendered from declarative description

It would work just like simple HTML pages with forms. When you hit the button, the content is sent to the server which can respond with a new page. Just like we did in the early days of webpages before webapps became a thing.

Variations of this have been implemented over and over again.

Limitations

While this works great for simple cases it has some downsides:

  • Needs to call the server for every action to get the reaction.
  • Any kind of logic that should be evaluated on the client has to be either hard-coded on the client (NO) or you have to come up with new declarative elements (see below)
view:
elements:
...
actions:
- type: flashscreen
for: 1000
- type: beep
times: 2
  • If you start going down the declarative actions route you need to implement them in every client-implementation you have.
  • If you want more dynamic behavior you probably end up with actions that take lots of parameters and/or trying to specify certain relationships between elements in a declarative way

So this can be limiting when you need more dynamic behavior without involving the server and have multiple client implementations — or plan to have them in the future.

The idea

Some time ago I realized that today almost all platforms have JavaScript engines by now:

Using the HTML analogy again: at some point static HTML pages with forms weren’t good enough in the web world any longer either, and what did we do there? We turned to JavaScript to introduce dynamic behavior.

My proposal is therefore to not only send declarative view-descriptions, but also include JavaScript code, like so:

view:
elements:
...
- type: textfield
id: product
...
script: >
function onProductExit() {
if (!model.getValue('product')) {
util.log('product field must be filled');
ui.setFocus('product');
}
}

The client app would wire up event handlers to the native UI elements and pass on certain events (like field-exits) to the JavaScript code. For field-exits it would try to invoke a function matching the following name:

“on” + capitalize(fieldName) + “Exit”

The model, ui and util objects would be objects provided by the client app as well. This API that the JS code can rely on needs to be defined up-front of course and available in all client apps.

So given the wide availability of JS engines, it should definitely be possible to build your own client-apps on all the previously mentioned platforms.
Then you can ship the UI-description & the behavior scripts from the server and have the same behavior on every platform with totally native look & feel (well at least look, the “feel” part depends a bit on what you are doing).

Why this is cool:

  • Write once, run anywhere ;)
  • Testing: you can run the script parts of the client code with automated tests on the server.

You can find some demo code here that shows that this is working with a small Server and a (really ugly) Java8 Swing client. It even includes tests that will start failing when you change/remove the script part of the response.

Looking for the problem

As mentioned in the beginning, I’ve “pitched” this idea to a few people by now, and I’ve shown a demo in a session at the SoCraTes Day Linz 2016.

The responses were for the most part … unenthusiastic. Here’s the feedback & my own thoughts that I collected on this:

Alternatives:

  • ReactNative / NativeScript: these already allow you to build client-code in JavaScript and have it run in a native shell application. You can even exchange basically the whole app by providing new scripts/resource from a server.
  • HTML/Hybrid apps: most modern mobile ecosystems have pretty strong browser-engines as well, so if you are able to build all your code in HTML+JS you have an extremely flexible solution. Even if you need access to the phones APIs, there are other technologies that allow you to do that (Apache Cordova, …)

Arguments for using it anyway:

  • Sometimes hybrid apps are just not acceptable/desired. And maybe you/the client is skeptical of technologies like ReactNative etc. The argument may be: exposing an object with 5–10 callbacks to a JavaScript engine is easy and will be easy in 5 years also, supporting a ReactNative app may no longer be easy by then.
  • You may consider that code to be part of the business-logic (e.g. a certain field must match a very specific criteria) so keeping it close to your business logic and testing it in together with the rest of it sounds reasonable. At least I’d prefer that to having parts of it suddenly in some completely separate client-project.

Using it in slightly different ways:
During the discussions when people actually found it interesting, there were often suggestions of how else it could be used — instead of building a fully-generic-client kind of thing with it:

  • Using it only to share some logic, without any generic UI. Especially useful for small algorithms that you want to be able to iterate on quickly and use on Android & iOS clients. One example that was brought up is: deciding when to show “Do you want to rate this app?”-dialogs to the user. The product-team may want to try out new, more complex combinations of conditions when to show this dialog, but you’re not able to release a new client version every week (especially on iOS).
  • Just for client-side validation. This could be useful if you want to share client-side validation code between a web-app, Android & iOS clients.

To sum it up, I still think putting the JavaScript engines to good use is something to keep in mind, especially since we have them on all these platforms nowadays. However, I clearly see that this won’t be the go-to solution for many problems, rather a nice tool to keep in your tool-belt which can be very effective when you actually have the need for it.


If you have more suggestions on what this would be useful for or a completely different opinion, let me & others know in the comments. Thanks!