Using backbone with sequelize/postgres - backbone.js

I'm working on creating a model in backbone to interact with my postgres database. I'm using backbone.js for the client side and node.js/sequelize.js for the server side. The code given in the backbone tutorial says this:
var UserModel = Backbone.Model.extend({
urlRoot: '/user',
defaults: {
name: '',
email: ''
}
});
Here they are interacting with a users sql database using a RESTful url (I have no idea what that is). Does anyone have any ideas how I can refer to my postgres table? I am beyond confused and have no idea what's going on (this is all really new to me)
Thanks.

A RESTful URL is just a URL for a webservice that uses RESTful principles. Google can explain that better than I can here, but the basic idea is to integrate the various REST "verbs" (GET, POST, DELETE, etc.) in to the API. For instance, here's a set of RESTful verbs + urls for an imaginary user API:
GET /user - returns a list of users
POST /user - creates a new user
DELETE /user/5 - deletes the user with ID 5
PUT /user/5 - updates/edits the user with ID 5
Backbone works particularly well if your server-side is designed similarly, but it's not a requirement.
If your server-side API isn't RESTful, you just need to override certain methods on your Models and Collections (most likely destroy, fetch, save, url, parse, sync, and toJSON) to do whatever is appropriate for your server.
For instance, you might want to override the url method of your model to make it return your server's (unRESTful) URL:
url: function() {
return 'www.example.com/some/very/not/RESTful/' + this.id + '/URL/example';
}
Or, if your server returns your objects with an "envelope", for instance:
{
type: 'envelope',
payload: {
type: 'user',
name: 'Bob',
id: 5,
}
}
you can modify parse to strip it out:
parse: function(original) {
return original.payload;
}
As for "how do I refer to my postgres table", if you override the appropriate methods, then call the appropriate Backbone action methods (fetch/save/destroy) on your models and collections, Backbone will make AJAX requests to the URL you define in your url override. Your server can then use any language you want to interpret that request and perform the appropriate operation on your PostgreSQL database.

Related

CouchDB _security PUT with angularJS

I am using couchDB and angular for a small project. I am trying to make my database more secure and would like to know how to place, or PUT/POST, a new member to the _security document of a database without replacing the existing values. I understand the process of doing this with something like curl however do not understand how to do it using angular without overriding the existing values.
The curl would be:
curl -u admin -X PUT $HOST/database/_security -d '{"admins": {"names":[], "roles":[]}, "members": {"names": ["example"], "roles": []}}'
In angular I have this code:
$http({
url: 'http://ip:5984/guestbook/_security',
method: 'PUT',
withCredentials: true,
headers: {
'Authorization': auth_hash('adminAccount', 'adminPassword')
},
data: {
admins: {
names: [],
roles: []
},
members: {
names: [self.user.name],
roles: []
}
}
})
Like I said the problem is that it is over riding what is already there, would using a different request mean it will not? the only way I can think to do this is to pull the existing _security document to the client, append and re put. surely this would create security issues as well as a large number of http requests being made.
A PUT will overwrite the document and as you mentioned you would have to pull down the existing document before.
The security doc also has no _rev field for versioning which will lead to race conditions when multiple requests happen simultaneously. A slower request that arrives later may then overwrite the change of another request. Jan Lehnardt wrote a nice article regarding conflicts.
Did you take a look at the users-db of CouchDB? It is build into CouchDB designed for the authentication of the users an application has. You can use the users-db to create users for your application without altering the configuration of admins and members (which is dangerous from a client for a guestbook).

AngularJS load data from server

I have the following scenario, a page that will show different widgets with different data, the back-end is ASp.NET Web API 2 with SQL Server and EF + Repository Pattern + Unit Of Work.
If I have to show quite some data, including user profile and other information on top of the widgets information, what will you recommend:
make one big $http.get request that will return a big json and bind that one to the UI
or
each controller (service) when it loads will make it's unique call to back-end and get's the data it needs to display, that means each widget will make a call to back-end and retrieve it's values.
I just want to know what do you recommend as a best practice.
IMHO the best way is to separate every request into single service methods that way you can reuse just a part of it and not make server calls to load to whole data, check the angular-resource $resource to have a clean reusable service of server calls and not a bunch of $https arround your code:
example:
A service that points some url of your backend server
.factory('ClientService', ['$resource', function($resource){
return $resource('http://some_url/:controller/:method', null, {
"agents": { method: 'GET', params: { controller: 'agent', method: 'search' }, cache: false },
"query": { method: 'GET', params: { controller: 'client', method: 'search' }, cache: false },
"save": { method: 'POST', params: { controller: 'client', method: 'save' } },
"delete": { method: 'POST', params: { controller: 'client', method: 'delete' } }
})
}])
The use in the controller (Injecting ClientService as dependency)
// If i want to query the agents into a scope element
// that will call the url = http://some_url/agent/search
$scope.agents = ClientService.agents();
// If i want to query a single client i cant send adtional params
// as is a get request it will call http://some_url/client/search?id=5
$scope.client = ClientService.query({id:5});
// and you can event manage callbacks if you want to
// This will send the client object to the url = http://some_url/client/save
ClientService.save($scope.client).$promise.then(function(response){ alert(response) })
As you can see this way you can access just the things you need from the backend server not having to do all the callback response if you dont need to and in a reusable cleaner way
Info Angular Resource Docs
I think it depends...
If performance might be a problem you should think about what is best for your User... Will the overhead of making 4 HTTP requests affect the user experience in anyway? Also, would a one big request take too much time to retrieve info from the database?
However if you want just to use a developer perspective of the problem, I'd prefer doing 1 generic API call then calling it 4 times in Angular with different parameters for each Widget.
It is likely that making 4 requests will actually be faster. Not to mention the data can start being populated on the screen as it comes back, instead of needing to wait for the slowest service.
For the max number of concurrent AJAX requehttp://www.coderanch.com/t/631345/blogs/Maximum-concurrent-connection-domain-browsers

AngularJS best practice REST / CRUD

What is the best practice of doing CRUD operations via REST with AngularJS?
Specially what is the Angular-Way here. By this I mean the way using the least code and the most default angular settings to achive this.
I know $resource and it's default operations. Where I'm not sure is how to implement/name the endpoints and which controllers to use.
For this example I would like to implement a simple user-management system which creates / updates /deletes / lists users. Since I'm implementing the Server-Endpoints by myself I'm completely free in doing it in the most angular friendly way.
What I like as answer is something like:
Server-Endpoints:
GET /service/users -> array of users
GET /service/user/new -> return an empty user with default values which has no id
POST /service/user/new -> store a new user and create an id. return the saved user.
POST /service/user/:ID -> save an existing user. Return the saved user
DELETE /service/user/:ID -> delete an existing user
Angular-Services:
.factory( 'User', [ '$resource', function( $resource ){
return $resource( '/service/user/:userId', { userId: '#id' } )
[...]
}])
Routing:
.when( '/users', {
templateUrl: BASE + 'partials/user-list.html',
controller: 'UserListCtrl' } )
.when( '/user/new', {
templateUrl: BASE + 'partials/user-edit.html',
controller: 'UserNewCtrl' } )
.when( '/user/:userId', {
templateUrl: BASE + 'partials/user-edit.html',
controller: 'UserEditCtrl' } )
...
Controllers:
UserListCtrl:
$scope.data = User.get(...)
UserNewCtrl:
$scope.user = User.get( { userId: "new" } )
...
Note that I'm not interessted in opinion what is the best (tm) way to do this but I'd like to know what is the Angular intended way (which I think should produce the least code because it can use the most default).
EDIT:
I'm looking for the whole picture. What I would love would be an answer like e.g.: "You can do this using online 3 Endpoints [...], 2 routes [...] and 2 controllers [...] if you do it this way using that defaults ..."
There is no Angular prescribed way for what you are asking. It's up to you to determine the implementation detail.
Typically I only use two controllers and templates per resource:
ListController
FormController
The Form controller is used for both Edit and Create operations. Use the resolve option in your route definitions to pass in either User.get() or User.new() and a flag indicating if this is an edit or create operation. This flag can then be used inside your FormController to decide which save method to call. Here's a simple example:
.when( '/users', {
templateUrl: BASE + 'partials/user-list.html',
controller: 'UserListCtrl' } )
.when( '/user/new', {
templateUrl: BASE + 'partials/user-form.html',
resolve: {
data: ['User', function(User) { return User.new(); }],
operation: 'create'
}
controller: 'UserFormCtrl' } )
.when( '/user/:userId', {
templateUrl: BASE + 'partials/user-form.html',
resolve: {
data: ['User', '$route', function(User, $route) { return User.get($route.current.params.userId); }],
operation: 'edit'
}
controller: 'UserFormCtrl' } )
And your form controller:
app.controller('UserFormCtrl', ['$scope', 'data', 'operation', function($scope, data, operation){
$scope.data = data;
$scope.save = function() {
if (operation === 'edit') {
// Do you edit save stuff
} else {
// Do you create save stuff
}
}
}]);
You can go a step further and create a base list and form controller to move stuff like error handling, server-side validation notifications etc. In fact for the majority of CRUD operations you can even move the save logic to this base controller.
My research into a similar quest has lead me to this project "angular-schema-form" https://github.com/Textalk/angular-schema-form.
For this approach...
You make a JSON-Schema that describes your data. Then augment it with another little JSON-struct that describes a "form" (ie. view specific info that does not belong in the data schema) and it makes a UI (form) for you.
One cool advantage is that the Schema is also useful in validating the data (client and server side), so that is a bonus.
You have to figure out what events should fire off GET/POST/... back to your API. but that would be your preference, eg. Hit the API for every key stroke OR the classic [Submit] button POST back style OR something in between with a timed Auto Save.
To keep this idea going, I think that it is possible to use StrongLoop to make a quick API, which (again) uses your data's schema (augmented with some storage details) to define the API.
no <3 uses of that schema, see [http://json-schema.org/] which is central to this approach.
(read: no less than three :)
You maybe mixing things up. CRUD operations at API level are done using $resource and these may or may not map to UI.
So using $resouce if you define resource as
var r = $resource('/users/:id',null, {'update': { method:'PUT' }});
r.query() //does GET on /users and gets all users
r.get({id:1}) // does GET on /users/1 and gets a specific user
r.save(userObject) // does a POST to /users to save the user
r.update({ id:1 }, userObject) // Not defined by default but does PUT to /users/1 with user object.
As you see the API is resource full but is in no way linked to any UI view.
For view you can use the convention you have defined, but nothing specific is provided by Angular.
I think what you are looking for can be found in http://www.synthjs.com/
Easily create new RESTful API resources by just creating folders and
naming functions a certain way.
Return data or promises from these
functions and they'll be rendered to the client as JSON.
Throw an
error, and it'll be logged. If running in dev mode, the error will
also be returned to the client.
Preload angular model data on page load (saving an extra
roundtrip).
Preload html view on page load (saving another extra
roundtrip!)
A simplified project structure
where front-end code (angular code, html, css, bower packages, etc)
is in the 'front' folder and back-end code (node code and node
packages) are in the 'back' folder.
A command-line tool for
installing third party packages, using npm + bower, that auto-updates
manifest files.
Auto compilation of assets on request for dev, and
pre-compilation for prod (including minification and ngmin).
Auto-restarts the server when changes are detected.
Support for
various back-end and front-end templates to help get a new project
going quickly.

ExtJs Model Proxy vs. Store Proxy

OK, I'm stuck on what should be a basic task in ExtJs. I'm writing a simple login script that sends a user name and password combination to a RESTful web service and receives a GUID if the credentials are correct.
My question is, do I use a Model Proxy or a Store Proxy?
To my understanding, Models represent a single record, whereas Stores are for handling sets of data containing more than one record. If this is correct then it would seem that a Model proxy is the way to go.
Following Sencha's documentation at http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.data.Model the code would look something like this:
Ext.define('AuthenticationModel', {
extend: 'Ext.data.Model',
fields: ['username', 'password'],
proxy: {
type: 'rest',
url : '/authentication'
}
});
//get a reference to the authentication model class
var AuthenticationModel = Ext.ModelManager.getModel('AuthenticationModel');
So far everything is OK, until the next step:
//Use the configured RestProxy to make a GET request
AuthenticationModel.load('???', {
success: function(session) {
console.log('Login successful');
}
});
The load() method for the Model class is a static call expecting a single unique identifier. Logins typically depend upon two factors, username and password.
So it appears Store proxies are the only way to validate someone's username and password credential combination in ExtJS. Can someone verify and explain? Any help to understand this would be greatly appreciated.
You just need to know the following:
The store will use it's own proxy if you configured one for this
instance and if not he takes the proxy from the model.
So you can easily go with two proxy configurations to enable the multi-CRUD operations on the store and the single-CRUD operations on the Models. Note the the static load method of the Model expects the model id because it is supposed to load a model by just one Id (yes, composite keys are not supported). You will also have to fetch the model instance in the callback (As you did).
Back to your Username/password problem
You may apply your session Model with a custom 'loadSession' method
loadSession: function(username,password, config) {
config = Ext.apply({}, config);
config = Ext.applyIf(config, {
action: 'read',
username: username,
password: password
});
var operation = new Ext.data.Operation(config),
scope = config.scope || this,
callback;
callback = function(operation) {
var record = null,
success = operation.wasSuccessful();
if (success) {
record = operation.getRecords()[0];
// If the server didn't set the id, do it here
if (!record.hasId()) {
record.setId(username); // take care to apply the write ID here!!!
}
Ext.callback(config.success, scope, [record, operation]);
} else {
Ext.callback(config.failure, scope, [record, operation]);
}
Ext.callback(config.callback, scope, [record, operation, success]);
};
this.getProxy().read(operation, callback, this);
}
Now call this instead of load.
I found it in the documentation of sencha App Architecture Part 2
Use proxies for models:
It is generally good practice to do this as it allows you to load and
save instances of this model without needing a store. Also, when
multiple stores use this same model, you don’t have to redefine your
proxy on each one of them.
Use proxies for stores:
In Ext JS 4, multiple stores can use the same data model, even if the
stores will load their data from different sources. In our example,
the Station model will be used by the SearchResults and the Stations
store, both loading the data from a different location. One returns
search results, the other returns the user’s favorite stations. To
achieve this, one of our stores will need to override the proxy
defined on the model.

Writing store updates back to server

I have read the Sencha tutorials, API, and forums for awhile but am hitting a brick wall. I have a mySQL/PHP backend that is storing a web application's data. I have the following Sench/ExtJS construct:
App.stores.user = new Ext.data.Store({
model: 'User',
proxy: new Ext.data.AjaxProxy({
url: 'app/stores/scripts/connect.php',
extraParams: {
method:'user',
user_id: 3
},
reader: {
type:'json',
root:'root'
}
}),
autoLoad:true
});
Data is loaded into the store fine, but I have a form that directly updates a User instance.
App.controllers.account = new Ext.Controller({
save: function (options) {
options.user.set(options.data);
options.user.save(); // Generates error: Uncaught Error: You are using a ServerProxy but have not supplied it with a url.
}
});
How can I successfully implement/hook the functions to write the dirty records back to the server? How is the request prepared and passed?
Thank you.
Uptil Ext Js 3.3.1 the store needs to be configured with a writer when performing CRUD operations. It isn't needed for read only. That's why your store is loaded but you're getting an error during write operations. In your case you'll have to specify a JsonWriter. Also, if you're not using the store in a restful manner, then you'll also need to specify a HttpProxy object to tell the store at which url to publish the create/update/delete on the store.
Check the docs for Ext 4. I should be something similar here too.

Resources