RIAs: the domain is not in the server side

Rich internet applications bring a powerful user experience. But in order to achieve that, they must be written totally different from traditional webs. The paradigm is totally different and so the architecture.  There is no "server side" as such. In some cases it's just a deployment site, where you have to browse in order to load the app. In some other cases you also need a centralized site to:

  • Initializing the application (deployment).
  • Storing data to be shared among instances/users (persistence).  
  • Connecting instances/users to each other (communication). 
Rather than calling it "server side", let's call it the hub. Its architecture must contemplate mainly:
  • Security
  • Concurrency
  • Scalability 
But everything else, lives in the application. The business domain, lives in the desktop application (which is inside the browser). There might be some security constraints related to the business that need to be tackled by the hub. In those cases, that particular bit of the business lives in the hub.

In order to be productive, the hub must understand JSON very well (assuming the data is sent/loaded via JSON) and serialize/deserialize it to objects automatically, without the need for hand-written mappings. This is one of the reasons why using Node.js in the backend makes sense, because you don't have to rewrite your objects in two different languages. Anyway, I am using C# and Python as the backend languages in two of my projects and the idea is the same.
If there are no particular security constraints, hub must accept data sent from the application and store it without objection.  The best way to avoid objections is using schemaless databases like Mongo.
Fortunately C# with ASP.Net is fantastic for JSON serialization/deserialization. For Python we've had to write code ourselves to get some automated conversion working.

As the hub is not the core, its functional requirements emerge from the incremental design. Such a design starts in the application side which eventually might need to send or retrieve some data to the hub. So my Cucumber scenarios, talk to JavaScript in the application side, specially if they are end to end.

Examples:
- Adding a "comment" to a "merchant" (where merchant is an entity, and comment is a value object): is done by the application. The hub just stores the entity as sent by the app. It  might have a security check to make sure the logged user can make changes in the merchant.  If there is any additional specific security constraint saying that comments can be made only by certain users, then we need to check that in the hub too, for the sake of data consistency. But that validation would go into the security rule's code. The hub's "merchant service/repository" won't know anything about comments.
- When listing merchants, show only those from  a particular country: is done in the hub. If the security constraint says that logged users from the UK can only work with merchants from the UK, we can't send all the merchants to the app for it to filter them out. Instead, the hub makes sure that only the information that can be seen in the app is sent.

So for rich internet applications, the hub is there just to support the architecture. Don't start the implementation of a feature in the hub, because you don't know if you are going to need it.  Keep your hub layer as thin as possible,  adding complexity only when proven necessary.
This will be probably a  chapter in my upcoming book where I will explain it in more detail.

The rationale behind:
The reason why desktop applications provide much better user experience than server-side web apps, is because they react immediately to user input. They interact in real time. When the user asks the application to save some data, the app should immediately tell the user data is saved, even if it hasn't got confirmation from the hub. If the hub doesn't respond or informs about a problem storing the data, then the application should inform the user, handling that somehow. But it should not make the user wait. So the application must have all the business knowledge to implement this solution.
Imagine a desktop application, a text editor for example. Now imagine it runs in the browser. All you need the hub for, is to load the application. If you want to access your text documents from different machines, then you need a hub to store and serve that information. Why do you need any business logic in the hub? What for?
In a later version, we decide to implement a new feature: collaboration with other users. There might be security restrictions. You might not want to have all the users opening your documents, but just some. Then you go and add a filter in the hub.
So it's not that you design some kind of service in the hub first and then call it from the application. It's the other way around, like in TDD, I might write a call to a centralized service that doesn't exist yet, once I know I need it in my application and once I know how I want it to behave. Then I add that behavior in the hub if necessary.
Eventually if the interaction among users is very complex, the hub will become complex and will contain important business logic, but its design will emerge according to the needs of the application and not the other way around.
Enjoyed reading this post?
Subscribe to the RSS feed and have all new posts delivered straight to you.
  • franreyes

    Hello Carlos!

    I think that for this architecture is in armony with DDD & Hexagonal architecture, you are forced to use NodeJS in your domain declaration, because the web (RIA or not) is only one delivery mechanism of the many others. So your domain can serve for others delivery mechanisms as Mobile or a Rest api. You don’t think so?

  • carlosble

    Hi Fran!
    I am not sure I understand what you mean. But you and me among others are doing this with a C# backend and it is working fine without Node. Of course, we are duplicating efforts sometimes, but it is a trade-off in order to work with technology we know well and it’s stable.
    If you need to expose a Rest API, you can always do it.
    Thank you 🙂

  • franreyes

    Oh! Maybe the mess comes from the “domain” word. In our case the “business domain” lives in the server. When you said “The domain is not in the server side”, what you mean? If the “business domain” is the server side then “the server is there just to support the architecture” is a false assertion.

    I think that in RIAs, the client should interacts with the “business processes”, but not contain the “business domain”.

    Sorry for my cambrigde’s english 😛

  • carlosble

    My comment was confusing because we are working in several apps together. Some have the logic in the server, that is true, because they are not full RIAs. Forget about them. Let’s use LiveTeamApp.com as an example. The server side is about 150 lines of code, everything else in the the client app. So yes, the business is in the client, the app, not in the server side. That is the whole point of my post actually 🙂

  • Andrés Viedma

    I wasn’t sure if I had understood the post, I think it’s not very clear what you mean with “the domain”, but reading the comments I confirmed what I though.

    And… sorry, but I must say I fully disagree with your vision. I don’t know if having the logic in the client is a requisite to be considered “RIA” (if it’s the case I don’t see why), but anyway I think that can be a big mistake for big applications and mantainability. In small applications it can seem fast to program… easy… tempting. But what will you do when requirements change or evolve and some whole part of code wich is already working in the client MUST be now in the server? For security, transactional, consistency, accesibility or SEO reasons, for example. If the server is written in a different language, you have to rewrite it all. If it’s also JS, you must make a big refactoring, which wouldn’t be a problem if we were dealing with any other language more “serious” than javascript, but with JS… well, it’s not so easy (I’m not a big friend of JavaScript, I must say).

    Of course, you can still make great applications with your approach, I’m sure… but I don’t think it helps to make applications easy to maintain.

    All this IMHO, and anyway I’m not sure if I missed any point, so I’ll be glad to hear your opinion.

  • carlosble

    When you say…

    “if we were dealing with any other language more “serious ” than javascript, but with JS… well, it’s not so easy (I’m not a big friend of JavaScript, I must say)”

    You are exposing your ignorance, which is good. But that is the reason you think JS is not maintainable. It is as maintainable as you write it. Have you tried test-driving your JS code?

    Thanks

  • Andrés Viedma

    Sorry if I seemed unrespectful and/or agressive, that wasn’t my intention. If I’m reading this blog is because I think it’s interesting, not to be a troll.

    Refactoring in a dynamic typing language is always harder than in a static typing one. That’s a fact. You can argue that the difference is very small, that’s an opinion. But I don’t think you can say that mi opinion is based in ignorance. Of course, code can be maintainable in every language, not only by test driving (I even doubt seriously it really helps in maintainability, although that’s not what I’m debating now). Can you make maintainable code programming in machine code? Yes (I can talk about that, I’ve done it maaaany years ago). Is it easier to make maintainable code in machine code? Absolutely not.

    Anyway, although I don’t really like JavaScript, that wasn’t rather my point. I was talking about difficulties of mainteinance when you make the business logic in the client side, even if it wasn’t JS. Even if it wasn’t a web, though.

    I suggest you to think about this issue beyond your initial feeling of being based on ignorance, specially if you’re writing about this in a book. Although if you’re strong in your opinions you’re also invited to ignore it, of course.

    Thanks and good luck with your book

  • carlosble

    Thank you Andres, I see your point now. For this reason I have updated the post. Replacing the words “client” for “application” and “server” for “hub”, in order to avoid confusion. I have also added a new paragraph that hopefully will clarify my explanation.

    Different opinions are always welcome, specially because I am working on the book as you said.

    Cheers 🙂

  • franreyes

    Ahá, this is the point! LiveTeamApp.com is a RIA where you don’t reused the domain knowledge for others application types (as a console application).

    In that scenario the server side can work as a repository and the domain can live in the client side.

    This a interesting topic to discuss with a nice cold beer 🙂

  • carlosble

    There you go my friend, you got my point now 🙂