5

If you're working on a client side mobile application, for a smoother UX, optimistic rendering is encouraged. This is where the application makes UI updates based on user requests that get sent to the server without waiting for the response assuming the response will be successful.

What this also means is that the requests need to be handled client-side to make corresponding updates which requires business logic that the server side uses. And this is duplication which in usual terms is bad.

Apart from that the business-logic might require information and resources which server readily has. For example, if the user rates a business, that rating must be aggregated and calculated to retrieve a "community rating". That process will be complex and inaccurate (obvious, as we're already making assumptions of the request success).

Are there any solutions to ease such complexity in implementation and yet make the experience smoother for the user? Is the duplication of logic the only way?

2
  • 5
    This is a false dichotomy: you may use the exact same code from both the server and the client (e.g using a shared library) and therefore achieve optimistic rendering without duplication at all. (Although web techs make this less easy than, say, Java or C) – user44761 Mar 27 '16 at 7:51
  • But the server is based on a different platform (client, Java and server, PHP). – razzledazzle Mar 27 '16 at 7:54
2

The strategy of using shared libraries to solve logic duplication as @Tibo discussed becomes more difficult as client and server platforms diverge.

Convenient solutions to avoid complexity or repetition, like sharing a language across a stack or between a client and a server, are ideal at the beginning of a project. Though, in some circumstances, there are libraries that have equivalent implementations in multiple languages but that's a bit more rare and harder to map to particular problems your existing project might be concerned with.

Isomorphic applications are very buzz-worthy now and many current examples utilize JavaScript on both client and server, but we're back to greenfield approaches or a major redesign.

If you're concerned with creating a more DRY approach utilizing existing code and disparate languages, maybe you can migrate specific important pieces of client functionality and create a new microservice matching the client language that can share libs with the client.

Barring the ability to share languages or distribute equivalent libraries, there are more simplistic design considerations that use graceful degradation and lazy/async updates on client UI to create some very basic (crude?) optimistic rendering and avoid repeated business logic in many places. This certainly adds complexity and requires other design decisions but may avoid simply repeating behavior in both places.

The best solutions probably involve knowing how to profile and defer well, while making the best decisions on how to slice, dice, and degrade as they pertain to the use and performance of your app, rather than simply duplicating.

Without knowing some specific UX rendering goals/types/examples with an existing app that is tied to multiple languages across the stack, solutions can seem a little too vague to be useful.

0

This is a bit theoretical, but it might be an alternative to using shared logic.

Let's first assume that business logic is needed to sanitize user requests and convert them into operations on the database. Now let's try to work around that assumption.

For some applications, it might be possible to make the DB store and the client store have the same structure. In that case, we don't need to convert requests into any other form, so we don't need to apply business logic.

For example we could imagine that the DB state is a tree of data, and a user action is simply an update to one or more parts of the tree.

In a simple implementation, we could only allow users to make updates to their own isolated tree. In this case there would be no need for any business logic at all. Clients would read their user tree, and the public part of other users trees, and then do their best to render what those trees provide. Sanitising invalid or undesirable data could be done on the client.

In a more complex implementation, we might allow users to make updates to any part of the tree (including shared branches, or the branches of other users), but with an access layer on the server that would reject unauthorised updates.

In that case, there would be some access control logic on the server, and the client UI should try to only offer actions which the server will classify as legal. That can be seen as a form of duplication, but I believe that form of duplication is already common in many apps, before we even reach the question of optimistic updates.

So to reiterate, the idea is that the client's data store and the server's data store should have the same structure. Then the update operation can be constructed on the client, and performed at both ends. The server could approve or reject updates, but it would never need to convert them into a different form.

(Another somewhat related idea might be to retain a list of all user actions, and assume that the state of the DB would then be the accumulation of all legal user action requests. The DB would have logic to reject illegal actions, but for optimistic updates, a client would trust its own actions. This might have some nice features, but an obvious concern here would be scalability as the number of actions grows.)

This answer would be better if it could provide some more concrete examples. (I will have to get back to you on that!) But I hope at least this might offer an alternative perspective.

I had these musings while thinking about "offline first" design and PouchDB, a client-side DB that can be used offline, and which syncs (catches up) with the server-side DB when online.

1
  • Partially related, here is a nice talk about event sourcing, which means keeping all your app events in a log, and deriving the current state from those events. – joeytwiddle Apr 4 '18 at 7:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.