Until now I was mainly using Struts 2
, Spring
, JQuery
technology stack for building web applications. The point is, that mentioned stack uses server side MVC
pattern. The main role of web browsers was limited to a request/response cycle (+ client side validation). Data retrieval, business logic, wiring and validation were mainly responsibilities of the server side.
I have few questions regarding AngularJS framework that were inspired by following quotes I've read:
From the AngularJS tutorial:
For Angular apps, we encourage the use of the Model-View-Controller (MVC) design pattern to decouple the code and to separate concerns.
From the Wikipedia Model–view–controller:
Model–View–Controller (MVC) is an architecture that separates the representation of information from the user's interaction with it. The model consists of application data and business rules, and the controller mediates input, converting it to commands for the model or view
AngularJS uses client side MVC
pattern. So I guess there is no other option then to include validation logic also to the client side in some way?
What would be the best way to write a robust AngularJS application? MVC on client side and some kind of MC (model, controller) on server side?
Does that mean, that MODEL and CONTROLLER are in one way duplicated (client/server)?
I know my question is somehow weird, but I think the reason is, that I am somehow acustomed to traditional server side MVC pattern. I am sure there is someone, that have already done same transition.
Not at all a weird question - I've been trying to sell Angular to a lot of java developers and they ask this. I asked it myself when I was learning (I'm still learning, btw)
If you take a 'conventional' java webapp as you've described and Angular-ize it, you've got to first take your server and make it a RESTful API. Remove the JSPs, etc. This is actually the hard part, IMO, of writing an Angular app - getting the REST API right. The key for me to deciding what logic needed to go into the server was thinking of it as a pure api and forgetting for the moment that it will have a front end.
That question really helped me - if someone tries to save a given resource and that resource doesn't have valid data there's no front end to tell them - they're hitting the API directly so the API needs to reject it. So, the back end is responsible for the deep validation. This applies to your business logic as well. Assume someone is using just the API and it will become clear what your server needs to do.
The server needs also to vend data in (probably) json format (I use Spring MVC + Jackson), so it's responsible for exposing the model to Angular, and communication with the database.
So what's the MVC then on the Angular side?
Model: The data that comes from the REST API. If the API is vending JSON, then these objects will already be 1st class javascript objects.
View: HTML, and directives when you need to manipulate the DOM
Controller: (and custom services that you've factored out of your controllers..) Queries the REST API and puts what's necessary for the View on the $scope Provides callbacks for directives to respond to events that might then require calls back to the server. Validation: usually via a callback to a directive. Will likely overlap some of the validation you've already put in the server, but you don't want your user to wait for the server to validate everything - the client should know something about the validation to give the user immediate feedback. Business logic: Pretty much the same story as validation.
Queries the REST API and puts what's necessary for the View on the $scope
Provides callbacks for directives to respond to events that might then require calls back to the server.
Validation: usually via a callback to a directive. Will likely overlap some of the validation you've already put in the server, but you don't want your user to wait for the server to validate everything - the client should know something about the validation to give the user immediate feedback.
Business logic: Pretty much the same story as validation.
But why the duplication of logic in the client and in the server? Mostly because you're not writing one app, you're writing two independent things:
a REST API that needs to be robust and usable without a front end a GUI that needs to give immediate feedback to a user and not necessarily wait for a server.
So, short answer - get the REST API right by forgetting that there will be a UI, and what goes into Angular will be much clearer.
I think the term "business logic" is a bit of a misnomer here. The "business" of a clientside app is the business of handling the user interface. It's not going to be things like security rules and proprietary logic or other sensitive intellectual property.
So in Angular the division is (generally):
Controller (controller): for manipulating the data (scope) behind your UI.
Directives : for setting up the DOM to communicate with the controller via scope, and for manipulating the DOM.
Templates (view): To assign directives to elements of the DOM.
Scope (model or viewmodel): for carrying data between all pieces of the system.
Services : Injectable, reusable bits of code. Usually for dependencies like handling Ajax, cookies, or other I/O.
It's really almost MVVM and not MVC.
As for your "business" logic or rules... anything requiring security must always be secured at the server level.
It's important to understand that in some versions of the MVC pattern, the data as well as the logic that manipulates the data both reside in the "model" layer (with the "controller" layer doing nothing but binding). In AngularJS, however, the data ($scope) alone resides in the "model" layer, while the logic that manipulates the data ($scope) resides in the "controller" layer.
https://i.stack.imgur.com/LBqIG.png
I love what @Roy TrueLove says. But let me say that this is the ultimate way of using angularjs. Of course, you have to learn to do your applications this way, if you want to get the most benefit of angular. I pray to be there some day.
In the meanwhile, during your learning, and during your transition to fully using angularjs as your client side main way of doing things, you can start using it for some small mission here and there, and gradually get accustomed to it and to its way of thinking.
I encourage to gradually embracing it and to go slowly slowly, but surely, I guaranty, sure.
Angularjs is designed to serve this approach, as it can work on the smallest task as good as it can do the biggest one. For example, this first time I used angular was just to show names while the user types ids.
I agree with the answers here. Some more comments. When you write an applicacion, you first need to concentrate on the problem domain. And create a software model of some real business. For example, if your problem domain is a shopping, some requirements that you need to model might include:
The credit card should be valid.
If you pay with a credit card of brand X, you will receive a 10% of discount.
The shop cart should contain at least one item to perform the checkout
The items must have stock before allow users to add them to the shop cart
The implementation of these requirements will model your problem domain, this is your business logic.
Angular is a frontend framework and toolkit. It is a web frontend. If you implement this in a web frontend, you will miss the oportunity to reuse your model from other frontend or interface, like a mobile or a desktop application. So, ideally, your business logic implementation needs to be decoupled from any user interface framework and decoupled from any persistent framework also. Then, you will have your interface objects that will deal with user interface problems and will comunicate with your business logic objects. This can be a Spring MVC controller, and/or an Angular controller or service.
There is a sample application you can take a look at, that follow the principles mentioned here.
I seems to be having this question as well, as some organizations just craze for new technologies - "I want cloud...wait, I want lightweight", its hard to justify whether it deserve for the switch to a lighther framework.
I develop webapplications using Spring/JBoss seam/JSF and on MVC framework all the time. Most of the time java scripts will reside for the presentation layer validations and the main action classes/entities and business logic will reside in Java code. After some basic hands-on on Angular, I started to get what they meant by MVC as they abstracted another level on the presentation layer, where we can have our own views and controllers on the front end. To answer your question, just like everyone's comment the best way is to lay it on the presentation layer.
As for security point of view, I believe heavy or sensitive business rules should reside on the server side as we do not want to expose it to the world. If the business logic is developed poorly, one can easily find the weakness on our code and exploit it.
Here's my thought for framework like Angular is like a small shop/SOHO handling customer, and they have a few people and really efficient and fast.They cater well for customers facing business and delivery/receive goods efficiently(REST, JSON). They do have designated roles and tasks, but some worker perform more than a tasks. The shop also vulnerable to thief or robbers as usually they don't emphasize heavy security.
As for server side framework like Spring/Struts 2, imagine a modern corporation(CMM Level 5) with different level of management and capable of handling bigger business(batch jobs, web services, enterprise bus). They do handle customer, but not directly, often go through brokers or even retail shops. Security wise a corporation is more robust, and often securities on the front door, or important information are protected in a safe(encryption/sign-on).
My approach is always the bottom-up approach. Starting from the Database Design, with properly constructed / related tables, stored procedures when needed, then add the Entity Framework to the solution or use ADO.Net if EF is not an option. Then develop the Business Logic, and the Models to get the data in and out the database.
With the Models established, we can now go two routes: Developing MVC Controller, and / or developing WebAPI controller. Both controllers can have access to the Models, it's just a matter of instantiating the classes and invoking the methods.
You now have the option of setting up MVC Views that are controlled by the MVC controller, or, entirely separate set of HTML pages or SPA (Single-Page Application hosted on NodeJS).
With the entirely separate set of HTML page, you will need to use WebAPI controllers, with Get, Post, Put, and Delete methods, and be sure to include token back and forth to identify your client, and enable CORS (for Cross Origin Request)
With MVC Views, you can identify your clients using the controller attributes, and / or sessions and no need to worry about CORS, and, you can even make your Views Strongly-Typed if needed. Unfortunately if you have a set of UI developers they will have to work on the same MVC solution.
In both cases, you can use AngularJS to transport data back and forth from / to the controllers.
IMHO the concept of AngularJS controller is not the same with C# MVC or C# WebAPI controller. AngularJS controller house all the javascript logic as well as the calls to endpoints via the "ApiFactory", whereas C# controllers are nothing but Endpoints in the server side that accept and respond to UI requests.
Success story sharing
But why the duplication of logic in the client and in the server? Mostly because you're not writing one app, you're writing two independent things: 1) a REST API that needs to be robust and usable without a front end 2) a GUI that needs to give immediate feedback to a user and not necessarily wait for a server. So, short answer - get the REST API right by forgetting that there will be a UI, and what goes into Angular will be much clearer.
Thank you!