backbone.js + WebAPI

I’ll present you how to use backbone.js with WebAPI. If you don’t know anything about backbone.js you can find useful links in this artcile also.

Backbone.js is a JavaScript framework. I think that you aren’t suprised about that fact 🙂 I recommend you read Backbone.js Getting Started if you don’t know anything about this framework. It’s not my intention to write a lot about backbone.js but about integration between backbone.js and ASP.NET WebAPI. Backbone.js gives us very good mechanism to connect with REST.

I’ll create very simple example about managing list of planets. I’ll create WebAPI REST service and frontend in backbone.js.
We start from creating a new ASP.NET project:

Now we can create PlanetsController which provide REST service to manage planets list:
[csharp]
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebApiBackboneJs.Models;

namespace WebApiBackboneJs.Controllers
{
public class PlanetsController : ApiController
{
private static IList planets = new List
{
new Planet { Id = 1, Name = “Mercury”, Diameter = 4878, Orbit = 88, Day = 58.6m },
new Planet { Id = 2, Name = “Venus”, Diameter = 12104, Orbit = 225, Day = 241m },
new Planet { Id = 3, Name = “Earth”, Diameter = 12760, Orbit = 365.4m, Day = 1m },
new Planet { Id = 4, Name = “Mars”, Diameter = 6787, Orbit = 687, Day = 1.01m },
new Planet { Id = 5, Name = “Jupiter”, Diameter = 139822, Orbit = 11.9m * 365, Day = 9.8m / 24.0m }
};

[HttpGet]
[Route(“api/planets”)]
public HttpResponseMessage Get()
{
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, planets);

return response;
}

[HttpGet]
[Route(“api/planets/{id}”)]
public HttpResponseMessage Get(int id)
{
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, planets.FirstOrDefault(x => x.Id == id));

return response;
}

[HttpPost]
[Route(“api/planets”)]
public HttpResponseMessage Post([FromBody]Planet value)
{
value.Id = planets.Max(x => x.Id) + 1;
planets.Add(value);

return Request.CreateResponse(HttpStatusCode.OK, value);
}

[HttpPut]
[Route(“api/planets/{id}”)]
public HttpResponseMessage Put(int id, [FromBody]Planet value)
{
Planet planet = planets.FirstOrDefault(x => x.Id == id);
int index = planets.IndexOf(planet);
planets[index] = value;

return Request.CreateResponse(HttpStatusCode.OK);
}

[HttpDelete]
[Route(“api/planets/{id}”)]
public HttpResponseMessage Delete(int id)
{
Planet planet = planets.FirstOrDefault(x => x.Id == id);
planets.Remove(planet);

return Request.CreateResponse(HttpStatusCode.OK);
}
}
}
[/csharp]
I think that it’s time to install backbone.js. I’ll use bower and gulp to this.So first of all we create file .bowerrc:
[js]
{
“directory”: “./lib”
}
[/js]

And bower.json:
[js]
{
“name”: “WebApiBackboneJs”,
“private”: true,
“dependencies”: {
“backbone”: “*”,
“jquery”: “*”,
“json2”: “*”
}
}
[/js]
Bower install all necessary JavaScript files in lib folder. So, we need gulp to copy scripts from lib to Scripts. We create gulpfile.js to do that:
[js]
var gulp = require(‘gulp’);

gulp.task(‘copy_backbone’, function () {
gulp.src(‘./lib/backbone/backbone-min.js’)
.pipe(gulp.dest(‘./Scripts’));
});

gulp.task(‘copy_jQuery’, function () {
gulp.src(‘./lib/jquery/dist/jquery.min.js’)
.pipe(gulp.dest(‘./Scripts’));
});

gulp.task(‘copy_json2’, function () {
gulp.src(‘./lib/json2/*.js’)
.pipe(gulp.dest(‘./Scripts’));
});

gulp.task(‘copy_underscore’, function () {
gulp.src(‘./lib/underscore/underscore-min.js’)
.pipe(gulp.dest(‘./Scripts’));
});

gulp.task(‘default’, [‘copy_backbone’, ‘copy_jQuery’, ‘copy_json2’, ‘copy_underscore’]);
[/js]
Of course you can do that in other way. For example you can download all JavaScript files and add them to project to Scripts folder. It’s up to you. Now we need backbone scripts with our planet’s model and collection. So we add two files: planet-model.js and planet-view.js.
[js]
$(function () {
Planet = Backbone.Model.extend({
defaults: function () {
return {
id: null,
name: null,
diameter: 0,
orbit: 0,
day: 0
}
},
idAttribute: “id”,
urlRoot: “/api/Planets/”
});

PlanetSet = Backbone.Collection.extend({
url: “/api/Planets/”,
model: Planet
});
});
[/js]
and second:
[js]
$(function () {
PlanetView = Backbone.View.extend({
model: new Planet(),
tagName: ‘tr’,

initialize: function () {
this.template = _.template($(‘.planet-list-template’).html());
},

events: {
‘click .edit-planet’: ‘edit’,
‘click .update-planet’: ‘update’,
‘click .cancel’: ‘cancel’,
‘click .delete-planet’: ‘delete’
},

edit: function () {
$(‘.edit-planet’).hide();
$(‘.delete-planet’).hide();
this.$(‘.update-planet’).show();
this.$(‘.cancel’).show();

var id = this.$(‘.id’).html();
var name = this.$(‘.name’).html();
var diameter = this.$(‘.diameter’).html();
var orbit = this.$(‘.orbit’).html();
var day = this.$(‘.day’).html();

this.$(‘.id’).html(‘‘);
this.$(‘.name’).html(‘‘);
this.$(‘.diameter’).html(‘‘);
this.$(‘.orbit’).html(‘‘);
this.$(‘.day’).html(‘‘);
},
update: function () {
this.model.set(‘id’, $(‘.id-update’).html());
this.model.set(‘name’, $(‘.name-update’).val());
this.model.set(‘diameter’, $(‘.diameter-update’).val());
this.model.set(‘orbit’, $(‘.orbit-update’).val());
this.model.set(‘day’, $(‘.day-update’).val());
this.model.save();
planetsView.render();
},
cancel: function () {
planetsView.render();
},
delete: function () {
this.model.destroy();
},

render: function () {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});

planetsList = new PlanetSet();
planetsList.fetch({ data: { page: ‘no’ } });

PlanetsView = Backbone.View.extend({
el: $(‘.planets-list’),
model: planetsList,
initialize: function () {
var self = this;
this.model.on(‘add’, this.render, this);
this.model.on(‘change’, function () {
setTimeout(function () {
self.render();
}, 600);
}, this);
this.model.on(‘remove’, this.render, this);
},
render: function () {
var self = this;
this.$el.html(”);
_.each(this.model.toArray(), function (planet) {
self.$el.append((new PlanetView({ model: planet })).render().$el);
});
return this;
}
});

planetsView = new PlanetsView();
});
[/js]
Now we can create index.html:
[html]












Solar planets:

Id Name Diameter (km) Orbit (Earth days) Day (Earth days)




[/html]
It’s our example:

You can find all source code on GitHub: https://github.com/letyshub/WebApiBackboneJs.

 

Useful links

I use bower and gulp but mabe you have never used it before. So maybe those links will help you:

http://www.hanselman.com/blog/IntroducingGulpGruntBowerAndNpmSupportForVisualStudio.aspx

https://github.com/Microsoft/nodejstools

http://bower.io/

http://gulpjs.com/