Related
I get the general idea at this point, angular.js is client-side, so any attempts to do database communication is done via initiating get/post requests to a server-side script on the server (via node, php, asp.net, whatever you're using)...
Only thing I haven't been able to determine is what's the proper practice for this in both conventions/security : do you make specialized pages for many of your particular queries, or 1 to a few general purpose pages that run whatever passed in as parameters. That latter option seems like a security nightmare but at the same time making a page for each table's select,insert,update, etc also seems nonviable.
To be clear and try and focus this back to a single question, it feels like I'm missing a concept here. How do you structure the database calls for an angular.js application?
From a security standpoint it isn't very different than a traditional web app. Your web server sends and receives json (most likely) instead of html. This means using something like rails-api instead of full rails. It's best to think of your Angular app as completely disconnected from your web server like an Android or iOS app is.
You might use token based authentication instead of cookies (nothing would preclude you from using token based auth in a traditional web app but I wouldn't say it's commonplace in traditional web apps). Other than that any concepts that apply to securing a traditional web application apply to securing an API.
What database do you use? Structure depends on the app you're building and if DB is relational or not. It's a strategic question, for example it may be better to have nested documents, or not.
We are working on a RoR project implementing an LMS. We need to send data to an external REST service provided by an external server. The data is sent when certain events are accomplished, it is possible that some of those are not triggered by the client (clicks, etc.).
Also, we need to keep consistency in our rails models, because we need to keep record of the user activities.
There is a library provided to work with the API, written in JavaScript. It makes most of the work easy, so we would like to use instead of creating our own implementation for the API requests.
What are the differences between each of the following approaches? Would one be preferable to another?
Use javascripts to send the data, inserting the snippets in the
views, from the client, but having the client execute this might have
some serious implications (scores changed, false success, etc).
Use a NodeJS server to execute the Javascript but we don't really know how to communicate with our main server (Rails)
And finally, use a HTTP client from the Rails app to send the requests to the service. However we don't know exactly how to do it, also there is the question of where this code goes in the MVC pattern.
Option #1, as you've likely realized, is out of the question. For the client to make API calls on your behalf, you would need to send them your secret key/token/whatever you need to authenticate with the API. But once they have that, they could just use a script console to make whatever API calls they want "as you". This would be pretty disastrous.
Option #2 might be prohibitively complex -- I'm personally not sure how you'd go about it. It is possible, using a library like therubyracer, to execute JavaScript code from Ruby code, but there is some degree of sandboxing and this may break code that requires network access.
That leaves you with Option #3, writing your own Ruby library to interact with the API. This could be easy or difficult, depending on how hairy the API is, but you already have a JavaScript version on hand (and hopefully docs for the REST service itself), so combined with something like RestClient or HTTParty the path forward should be clear.
As for where the API calls would fit in your Rails code: If you have models that are basically mirroring the resources you're interacting with through the REST service, it might make sense to add the relevant API calls as methods or callbacks on those models. Otherwise it might be fine to put them in the relevant controller actions, but keep an eye on your code complexity and extract to a separate class or module if things are getting ugly.
(In cases where you don't need to wait for the response from the API before sending something back to the user, you may want to use DelayedJob or similar to queue your API calls in the background.)
I have built several Backbone apps and appreciate the client-side code structure and organization. I'm moving into Node development, using Express, and I'm uncertain as to how Express and Backbone can work together in the handling of routes.
You need to understand that Node and Backbone are independent from each other.
Node is for server-side (e.g working with a database, api serving etc. ) .
Backbone is a client-side Javascript MVC framework which gives you a structure for organizing your client-side Javascript application. (the application in the browser)
You can have a Backbone application in your client-side and it can hook up to any back-end either Node, Rails, PHP etc...
For more info check MVVM pattern and Javascript frameworks on the client-side.
http://backbonetutorials.com/why-would-you-use-backbone/
http://addyosmani.com/blog/understanding-mvvm-a-guide-for-javascript-developers/
A friend gave me the answer:
Backbone uses hash routes. For instance http://yoursite.com/#foo
Express will use the traditional http://yoursite.com/foo
You can use the routers independent of one another based one which address you path to - a hash route for client-side functions and the traditional route for server side functionality.
Both routers can coexist.
Your question on how Backbone and Express can work together cannot really be answered precisely, because there are really countless ways on which they can work together. Hopefully some of the info below can help you do what you want to do.
First of all, you can use www.example.com/foo (no #) routes on the client side (Backbone) - see the pushState option in Backbone.history.start() documentation. It is possible to integrate the routes on the client side and on the server side. It is not easy to find exactly how to do, though.
Some of the info under those links may help you:
https://github.com/developmentseed/bones
https://github.com/SC5/backbone-serverside
https://github.com/tysoncadenhead/backbone-on-express
http://nerds.airbnb.com/weve-launched-our-first-nodejs-app-to-product
http://blog.andyet.com/2011/feb/15/re-using-backbonejs-models-on-the-server-with-node/
You wrote that you have experience with Backbone but you're moving to Node recently so I assume that you are open to other frameworks than only Express. You may consider using eg. restify (in addition to Express) to make a RESTful service which you can integrate with Backbone.
There are also entire frameworks like Derby or Meteor that cover both client side and server side using one code base and you can share much more than just the routers.
(Also, I've just found this year's (2013) HTML5DevConf talk: Surviving Robots and Old Browsers by Server-side Backbone. I haven't watched it yet but it seems very relevant to your problem.)
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.
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.
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.
I am just starting to look at MVC structure, first i looked at how backbone.js worked, and now I have just completed rails for zombies, by Code School. I know that I haven't delved too far into any of this, but I had a question to begin with.
Can you use these libraries together?
I have learned how to create models, views, etc in both, but when creating a real application do you use both backbone and rails?
If so...
When do you use a backbone.js model vs. a rails model?
Maybe I am just getting ahead of myself and need to keep practicing and doing tutorials but I couldn't seem to find anything directly on this.
Thanks!
Before anything else I'd suggest taking a look at thoughtbot's Backbone.js on Rails book, which is a great starting point, although aimed at an intermediate to advanced audience. I bought this book having already worked with rails but as a total backbone.js beginner and it has served me very well.
Beyond that, there are some fundamental issues with combining these frameworks which go beyond the details covered in this book and other books. Below are some things I'd suggest you think about, from my own experiences pairing RoR and backbone.js. This is a long answer and strays a bit from the specifics of your question, but I hope it might help you out in the "big picture" sense of understanding the problem you're facing.
Rails: Web Framework vs API
The first thing you confront when using backbone.js on top of a rails application is what to do about views, but this is really just the surface of a much deeper issue. The problem goes to the very heart of what it means to create a RESTful web service.
Rails is set up out of the box to encourage its users to create RESTful services, by structuring routing in terms of a set of resources accessed at uniform URIs (defined in your routes.rb file) through standard HTTP actions. So if you have a Post model, you can:
Get all posts by sending GET request to /posts
Create a new post by sending a GET request to /posts/new, filling out the form and sending it (a POST request) to /posts
Update a post with id 123 by sending a GET request to /posts/123/edit, filling out the form and sending it (a PUT request) to posts/123
Destroy a post with id 123 by sending a DELETE request to /posts/123
The key thing to remember about this aspect of Rails is that it is fundamentally stateless: regardless of what I was doing previously, I can create a new Post simply by sending a POST request with a valid form data to the correct URI, say /posts. Of course there are caveats: I may need to be logged in (have a session cookie identifying me), but in essence Rails doesn't really care what I was doing before I sent that request. I could follow it up by updating another post, or by sending a valid action to whatever other resources are made available to me.
This aspect of how Rails is designed makes it relatively easy to turn a (Javascript-light) Rails web application into an API: the resources will be similar or the same, the web framework returning HTML pages while the API (typically) returns data in JSON or XML format.
Backbone.js: A new stateful layer
Backbone is also based on RESTful resources. Whenever you create, update or destroy a backbone.js model, you do so via the standard HTTP actions sent to URIs which assume a RESTful architecture of the kind described above. This makes it ideal for integrating with RESTful services like RoR.
But there is a subtle point to be stressed here: backbone.js integrates seamlessly with Rails as an API. That is to say, if you strip away the HTML views and just use Rails for serving RESTful resources, integrating with the database, performing session management, etc., then it integrates very nicely with the structure that backbone.js provides for client-side code. Many people argue that there's nothing wrong with using rails this way, and I think in many ways they are right.
The complications arise though from the issue of what to do with that other part of Rails that we've just thrown away: the views and what they represent.
Stateful humans, stateless machines
This is actually more important than it may initially seem. HTML views represent the stateless interface that humans use for accessing the RESTful resources your service provides. Doing away with them leaves you with two access points:
For humans: a rich, client-side interface provided by the backbone.js layer (stateful)
For machines: a resource-oriented RESTful API provided by the rails layer (stateless)
Notice that there is no longer a stateless (RESTful) interface for humans. In contrast, in a traditional rails app with an API, we had something closer to this:
HTML resources for humans (stateless)
JSON/XML resources (API) for machines (stateless)
The latter two interfaces for accessing resources are much closer in nature to each other than the previous two. Just think for example of rails' respond_with, which takes advantage of the similarities to wrap various RESTful responders in a unified method.
Working together
This might all seem very abstract and beside the point, I know. To try to make it more concrete, consider the following problem, which gets back to your question about getting rails and backbone.js to work together. In this problem, you want to:
Create a web service with a rich client-side experience using backbone.js, with rails as the back end serving resources in JSON format.
Use pushState to give each page in the app a URL (e.g. /posts/123) which can be accessed directly (by entering it into the browser bar).
For each of these URLs, also serve an HTML page for clients without javascript.
These are not unusual demands for a modern web service, but they create a complex challenge. To make a long story short, you now have to create two "human-oriented" layers:
Stateful client-side interface (backbone.js templates and views)
Stateless HTML resources (Rails HTML views)
The complexity of actually doing this leads many nowadays to abandon the latter of these two and just offer a rich client-side interface. What you decide to do depends on your goals and what you want to achieve, but it's worth thinking about this problem carefully.
As another possible reference for doing that, I'd suggest having a look at O'Reilly's RESTful Web Services. It might seem odd to be recommending a book on REST in a question about Rails and Backbone.js, but actually I think this is the key piece that fits these very different frameworks together, and understanding it more fully will help you take advantage of the strengths of both.
Yes, you can use both side by side. Backbone is for storing and manipulating data within the client browser. It generally needs a server to talk to and fetch the data from. This is where Rails comes in. You can have a web application without heavy client-side code. Backbone is for building out sites that feel more like apps--think of Gmail or Pandora.
I advise just learning Rails first. Once you can get static pages loading and styled as you wish, then understanding Backbone's place will make more sense
I've used rails as a backend server to serve a fairly large website, which included a few one-page apps (built in backbone).
I'd suggest the backbone-on-rails gem. The idea is that your rails server will serve up the backbone app as a script tag in one of your views. You keep your backbone app itself in the rails app/assets folder.
Backbone understands rails routing conventions, and you just need to give it a path to a json api that rails can almost generate for you with rails generate resource.
Other than the syncing between the models, your backbone apps and rails apps are fairly separate. Backbone and Rails don't have quite the same MVC model, but getting them to cooperate is pretty easy.