Introduction
In this article, we will discuss how we can perform CRUD operations on a backbone model using a REST based HTTP service.
Background
In this article, we will look at performing the CRUD operations on backbone models using a REST based web service.
Link to complete series:
- BackBone Tutorial – Part 1: Introduction to Backbone.Js[^]
- BackBone Tutorial – Part 2: Understanding the basics of Backbone Models[^]
- BackBone Tutorial – Part 3: More about Backbone Models[^]
- BackBone Tutorial – Part 4: CRUD Operations on BackboneJs Models using HTTP REST Service[^]
- BackBone Tutorial – Part 5: Understanding Backbone.js Collections[^]
- BackBone Tutorial – Part 6: Understanding Backbone.js Views[^]
- BackBone Tutorial – Part 7: Understanding Backbone.js Routes and History[^]
- BackBone Tutorial – Part 8: Understanding Backbone.js Events[^]
Using the Code
The first thing we will do is that we will create a simple REST based web API that can be used to save the data on the server using our simple backbone application. For this, I have created a simple database with a single table as:
The ID
field is configured to auto increment and this is the primary key of the table. So, while creating a new model, we don't have to provide this to the server. Now on top of this model, I have written a simple ASP.NET web API that will provide us the RESTful API. This API is configured to run on my local machine at: http://localhost:51377/. The API details are as follows:
- Create:
POST
http://localhost:51377/api/values - Read:
GET
http://localhost:51377/api/values/{id} - Update:
PUT
http://localhost:51377/api/values/{id} - Delete:
DELETE
http://localhost:51377/api/values/{id}
Once we have the API running, we can start working on our backbone model. We had created the backbone model in our previous article as:
var Book = Backbone.Model.extend({
defaults: {
ID: "",
BookName: ""
},
idAttribute: "ID",
initialize: function () {
console.log('Book has been initialized');
this.on("invalid", function (model, error) {
console.log("Houston, we have a problem: " + error)
});
},
constructor: function (attributes, options) {
console.log('Book\'s constructor had been called');
Backbone.Model.apply(this, arguments);
},
validate: function (attr) {
if (!attr.BookName) {
return "Invalid BookName supplied."
}
}
});
The backbone models inherently support saving on the server using a restful web API. To save the model using a HTTP REST service, we need to specify the urlRoot
in the backbone model. To actually save the model, we can call the save
on the backbone model. The save
method will trigger the validations and if the validations are successful, it will try to identify the action to be performed, i.e., create or update and based on that action, it will use urlRoot
and call the appropriate REST API to perform the operation. Let us specify the URL root to enable this model to use our web API service.
var Book = Backbone.Model.extend({
defaults: {
ID: "",
BookName: ""
},
idAttribute: "ID",
initialize: function () {
console.log('Book has been initialized');
this.on("invalid", function (model, error) {
console.log("Houston, we have a problem: " + error)
});
},
constructor: function (attributes, options) {
console.log('Book\'s constructor had been called');
Backbone.Model.apply(this, arguments);
},
validate: function (attr) {
if (!attr.BookName) {
return "Invalid BookName supplied."
}
},
urlRoot: 'http://localhost:51377/api/Books'
});
Now let us try to perform CRUD operations on this model.
Create
To create a new entity on the server, we need to populate the non identity fields in the model (other than ID
in this case) and then call the Save
method on the model.
var book = new Book({ BookName: "Backbone Book 43" });
book.save({}, {
success: function (model, respose, options) {
console.log("The model has been saved to the server");
},
error: function (model, xhr, options) {
console.log("Something went wrong while saving the model");
}
});
Read
To read a single book
entity, we need to create the book
entity with the identity attribute populated, i.e., the ID
of the book
we want to read. Then, we need to call the fetch
method on the model
object.
var book1 = new Book({ ID: 40 });
book1.fetch({
success: function (bookResponse) {
console.log("Found the book: " + bookResponse.get("BookName"));
}
});
Update
Now let's say we want to update the name of the book retrieved in the earlier fetch call. All we need to do is set the attributes we need to update and call the save
method again.
var book1 = new Book({ ID: 40 });
book1.fetch({
success: function (bookResponse) {
console.log("Found the book: " + bookResponse.get("BookName"));
bookResponse.set("BookName", bookResponse.get("BookName") + "_updated");
bookResponse.save({}, {
success: function (model, respose, options) {
console.log("The model has been updated to the server");
},
error: function (model, xhr, options) {
console.log("Something went wrong while updating the model");
}
});
}
});
Delete
Now to delete a Model
, we just need to call the destroy
method of the model
object.
var book2 = new Book({ ID: 40 });
book2.destroy({
success: function (model, respose, options) {
console.log("The model has deleted the server");
},
error: function (model, xhr, options) {
console.log("Something went wrong while deleting the model");
}
});
Custom URLs to Perform CRUD Operation on Models
There are few scenarios where we might want to have provide custom URLs for the individual operations. This can be achieved by overriding the sync
function and providing custom URL for each action. Let us create one more model BookEx
to see how this can be done.
var BookEx = Backbone.Model.extend({
defaults: {
ID: "",
BookName: ""
},
idAttribute: "ID",
getCustomUrl: function (method) {
switch (method) {
case 'read':
return 'http://localhost:51377/api/Books/' + this.id;
break;
case 'create':
return 'http://localhost:51377/api/Books';
break;
case 'update':
return 'http://localhost:51377/api/Books/' + this.id;
break;
case 'delete':
return 'http://localhost:51377/api/Books/' + this.id;
break;
}
},
sync: function (method, model, options) {
options || (options = {});
options.url = this.getCustomUrl(method.toLowerCase());
return Backbone.sync.apply(this, arguments);
}
});
Now we can perform the CRUD operations on this model in the same way as we did for the previous model.
Point of Interest
In this article, we have looked at how to perform CRUD operations on backbone models using HTTP based REST service. This has been written from a beginner's perspective. I hope this has been informative.
History
- 17th July, 2014: First version