<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Christophe Coenraets &#187; REST</title>
	<atom:link href="http://coenraets.org/blog/category/rest/feed/" rel="self" type="application/rss+xml" />
	<link>http://coenraets.org/blog</link>
	<description>Web Platform, Cloud and Mobile Application Development</description>
	<lastBuildDate>Mon, 13 May 2013 16:05:20 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Creating a REST API using Node.js, Express, and MongoDB</title>
		<link>http://coenraets.org/blog/2012/10/creating-a-rest-api-using-node-js-express-and-mongodb/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=creating-a-rest-api-using-node-js-express-and-mongodb</link>
		<comments>http://coenraets.org/blog/2012/10/creating-a-rest-api-using-node-js-express-and-mongodb/#comments</comments>
		<pubDate>Tue, 02 Oct 2012 17:03:24 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Express]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=3967</guid>
		<description><![CDATA[I recently used Node.js, Express, and MongoDB to rewrite a RESTful API I had previously written in Java and PHP with MySQL (Java version, PHP version), and I thought I&#8217;d share the experience&#8230; Here is a quick guide showing how to build a RESTful API using Node.js, Express, and MongoDB. Installing Node.js Go to http://nodejs.org, [...]]]></description>
				<content:encoded><![CDATA[<style>
table {
border-collapse:collapse;
width: 100%;
}
th, td {
padding:4px;
border: 1px solid #ddd;
}
</style>
<p><a href="http://coenraets.org/blog/wp-content/uploads/2012/10/nodemango1.jpg"><img src="http://coenraets.org/blog/wp-content/uploads/2012/10/nodemango1.jpg" alt="" title="nodemango" width="600" height="120" class="aligncenter size-full wp-image-4129" /></a><br />
I recently used Node.js, Express, and MongoDB to rewrite a RESTful API I had previously written in Java and PHP with MySQL (<a href="http://coenraets.org/blog/2011/12/restful-services-with-jquery-and-java-using-jax-rs-and-jersey/">Java version</a>, <a href="http://coenraets.org/blog/2011/12/restful-services-with-jquery-php-and-the-slim-framework/">PHP version</a>), and I thought I&#8217;d share the experience&#8230; </p>
<p>Here is a quick guide showing how to build a RESTful API using <a href="http://nodejs.org/">Node.js</a>, <a href="http://expressjs.com/">Express</a>, and <a href="http://www.mongodb.org/">MongoDB</a>.</p>
<h3>Installing Node.js</h3>
<ol>
<li>Go to <a href="http://nodejs.org">http://nodejs.org</a>, and click the <em>Install</em> button.</li>
<li>Run the installer that you just downloaded. When the installer completes, a message indicates that <em>Node was installed at /usr/local/bin/node</em> and <em>npm was installed at /usr/local/bin/npm</em>.</li>
</ol>
<p>At this point node.js is ready to use. Let&#8217;s implement the webserver application from the nodejs.org home page. We will use it as a starting point for our project: a RESTful API to access data (retrieve, create, update, delete) in a wine cellar database.<br />
<span id="more-3967"></span></p>
<ol>
<li>Create a folder named <em>nodecellar</em> anywhere on your file system.</li>
<li>In the wincellar folder, create a file named <em>server.js</em>.</li>
<li>Code server.js as follows:
<p><script src="https://gist.github.com/3815873.js?file=server.js"></script>
</li>
</ol>
<p>We are now ready to start the server and test the application:</p>
<ol>
<li>To start the server, open a shell, <em>cd</em> to your nodecellar directory, and start your server as follows:
<p class="shell">node server.js</p>
</li>
<li>To test the application, open a browser and access <a href="http://localhost:3000">http://localhost:3000</a>.</li>
</ol>
<p><br/></p>
<h3>Installing Express</h3>
<p>Express is a lightweight node.js web application framework. It provides the basic HTTP infrastructure that makes it easy to create REST APIs.</p>
<p>To install Express in the nodecellar application:</p>
<ol>
<li>In the nodecellar folder, create a file named <em>package.json</em> defined as follows:
<p><script src="https://gist.github.com/3815974.js?file=package.json"></script></p>
</li>
<li>Open a shell, <em>cd</em> to the nodecellar directory, and execute the following command to install the express module.
<p class="shell">npm install</p>
<p>A <em>node_modules</em> folder is created in the nodecellar folder, and the Express module is installed in a subfolder of node_modules.
</li>
</ol>
<p>Now that Express is installed, we can stub a basic REST API for the nodecellar application: </p>
<ol>
<li>Open server.js and replace its content as follows:
<p><script src="https://gist.github.com/3815974.js?file=server.js"></script>
</li>
<li>Stop (CTRL+C) and restart the server:
<p class="shell">node server</p>
</li>
<li>To test the API, open a browser and access the following URLs:<br />
<table style="margin-top:12px;">
<tr>
<td width="320">Get all the wines in the database:</td>
<td><a href="http://localhost:3000/wines">http://localhost:3000/wines</a></td>
</tr>
<tr>
<td>Get wine with a specific id (for example: 1):</td>
<td><a href="http://localhost:3000/wines/1">http://localhost:3000/wines/1</a></td>
</tr>
</table>
</li>
</ol>
<p><br/></p>
<h3>Using Node.js Modules</h3>
<p>In a large application, things could easily get out of control if we keep adding code to a single JavaScript file (server.js). Let&#8217;s move the wine-related code in a <em>wines</em> module that we then declare as a dependency in server.js.</p>
<ol>
<li>In the nodecellar folder, create a subfolder called <em>routes</em>.</li>
<li>In the routes folder create a file named <em>wines.js</em> and defined as follows:
<p><script src="https://gist.github.com/3816103.js?file=wines.js"></script>
</li>
<li>Modify server.js as follows to delegate the routes implementation to the wines module:
<p><script src="https://gist.github.com/3816103.js?file=server.js"></script>
</li>
<li>Restart the server and test the APIs:<br />
<table style="margin-top:12px;margin-bottom:12px;">
<tr>
<td width="320">Get all the wines in the database:</td>
<td><a href="http://localhost:3000/wines">http://localhost:3000/wines</a></td>
</tr>
<tr>
<td>Get wine with a specific id (for example: 1):</td>
<td><a href="http://localhost:3000/wines/1">http://localhost:3000/wines/1</a></td>
</tr>
</table>
</li>
</ol>
<p>The next step is to replace the placeholder data with actual data from a MongoDB database.<br />
<br/></p>
<h3>Installing MongoDB</h3>
<p>To install MongoDB on your specific platform, refer to the <a href="http://www.mongodb.org/display/DOCS/Quickstart">MongoDB QuickStart</a>. Here are some quick steps to install MongoDB on a Mac:</p>
<ol>
<li>Open a terminal window and type the following command to download the latest release:
<p class="shell">curl http://downloads.mongodb.org/osx/mongodb-osx-x86_64-2.2.0.tgz > ~/Downloads/mongo.tgz</p>
<p>Note: You may need to adjust the version number. 2.2.0 is the latest production version at the time of this writing.
</li>
<li>Extract the files from the mongo.tgz archive:
<p class="shell">
cd ~/Downloads<br />
tar -zxvf mongo.tgz
</p>
</li>
<li>Move the mongo folder to /usr/local (or another folder according to your personal preferences):
<p class="shell">sudo mv -n mongodb-osx-x86_64-2.2.0/ /usr/local/</p>
</li>
<li>(Optional) Create a symbolic link to make it easier to access:
<p class="shell">sudo ln -s /usr/local/mongodb-osx-x86_64-2.2.0 /usr/local/mongodb</p>
</li>
<li>Create a folder for MongoDB&#8217;s data and set the appropriate permissions:
<p class="shell">sudo mkdir -p /data/db<br />
sudo chown `id -u` /data/db</p>
</li>
<li>Start mongodb
<p class="shell">cd /usr/local/mongodb<br />
./bin/mongod</p>
</li>
<li>You can also open the MongoDB Interactive Shell in another terminal window to interact with your database using a command line interface.
<p class="shell">cd /usr/local/mongodb<br />
./bin/mongo</p>
<p>Refer to the <a href="http://www.mongodb.org/display/DOCS/Overview+-+The+MongoDB+Interactive+Shell">MongoDB Interactive Shell documentation</a> for more information.
</li>
</ol>
<p><br/></p>
<h3>Installing the MongoDB Driver for Node.js</h3>
<p>There are different solutions offering different levels of abstraction to access MongoDB from Node.js (For example, <a href="http://mongoosejs.com/">Mongoose</a> and <a href="https://github.com/masylum/mongolia">Mongolia</a>). A comparaison of these solutions is beyond the scope of this article. In this, guide we use the <a href="http://www.mongodb.org/display/DOCS/node.JS">native Node.js driver</a>.  </p>
<p>To install the the native Node.js driver, open a terminal window, cd to your nodecellar folder, and execute the following command:</p>
<p class="shell">npm install mongodb</p>
<p><br/></p>
<h3>Implementing the REST API</h3>
<p>The full REST API for the nodecellar application consists of the following methods:</p>
<table style="margin-bottom:24px;">
<tr>
<th>Method</th>
<th>URL</th>
<th>Action</th>
</tr>
<tr>
<td>GET</td>
<td>/wines</td>
<td>Retrieve all wines</td>
</tr>
<tr>
<td>GET</td>
<td>/wines/5069b47aa892630aae000001</td>
<td>Retrieve the wine with the specified _id</td>
</tr>
<tr>
<td>POST</td>
<td>/wines</td>
<td>Add a new wine</td>
</tr>
<tr>
<td>PUT</td>
<td>/wines/5069b47aa892630aae000001</td>
<td>Update wine with the specified _id</td>
</tr>
<tr>
<td>DELETE</td>
<td>/wines/5069b47aa892630aae000001</td>
<td>Delete the wine with the specified _id</td>
</tr>
</table>
<p>To implement all the <em>routes</em> required by the API, modify server.js as follows:<br />
<script src="https://gist.github.com/3819468.js?file=server.js"></script></p>
<p>To provide the data access logic for each route, modify wines.js as follows:<br />
<script src="https://gist.github.com/3819468.js?file=wines.js"></script></p>
<p>Restart the server to test the API.</p>
<p><br/></p>
<h3>Testing the API using cURL</h3>
<p>If you want to test your API before using it in a client application, you can invoke your REST services straight from a browser address bar. For example, you could try:</p>
<ul>
<li><a href="http://localhost:3000/wines">http://localhost:3000/wines</a></li>
</ul>
<p>You will only be able to test your GET services that way. A more versatile solution to test RESTful services is to use <a href="http://curl.haxx.se/">cURL</a>, a command line utility for transferring data with URL syntax.</p>
<p>For example, using cURL, you can test the Wine Cellar API with the following commands:</p>
<ul>
<li>Get all wines:
<p class="shell">
curl -i -X GET http://localhost:3000/wines
</p>
</li>
<li>Get wine with _id value of 5069b47aa892630aae000007 (use a value that exists in your database):
<p class="shell">
curl -i -X GET http://localhost:3000/wines/5069b47aa892630aae000007
</p>
</li>
<li>Delete wine with _id value of 5069b47aa892630aae000007:
<p class="shell">
curl -i -X DELETE http://localhost:3000/wines/5069b47aa892630aae000007
</p>
</li>
<li>Add a new wine:
<p class="shell">
curl -i -X POST -H &apos;Content-Type: application/json&apos; -d &apos;{&quot;name&quot;: &quot;New Wine&quot;, &quot;year&quot;: &quot;2009&quot;}&apos; http://localhost:3000/wines
</p>
</li>
<li>Modify wine with _id value of 5069b47aa892630aae000007:
<p class="shell">
curl -i -X PUT -H &apos;Content-Type: application/json&apos; -d &apos;{&quot;name&quot;: &quot;New Wine&quot;, &quot;year&quot;: &quot;2010&quot;}&apos; http://localhost:3000/wines/5069b47aa892630aae000007
</p>
</li>
</ul>
<p><br/></p>
<h3>Next Steps</h3>
<p>In my next post, I&#8217;ll share a client application that makes use of that API. Update: The &#8220;next post&#8221; is now available <a href="http://coenraets.org/blog/2012/10/nodecellar-sample-application-with-backbone-js-twitter-bootstrap-node-js-express-and-mongodb/">here</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2012/10/creating-a-rest-api-using-node-js-express-and-mongodb/feed/</wfw:commentRss>
		<slash:comments>95</slash:comments>
		</item>
		<item>
		<title>Backbone.js Wine Cellar Tutorial — Part 3: Deep Linking and Application States</title>
		<link>http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-3-deep-linking-and-application-states/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=backbone-js-wine-cellar-tutorial-part-3-deep-linking-and-application-states</link>
		<comments>http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-3-deep-linking-and-application-states/#comments</comments>
		<pubDate>Thu, 08 Dec 2011 21:04:53 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=2555</guid>
		<description><![CDATA[UPDATE: I posted a &#8220;Postface&#8221; to this series with some lessons learned and an improved version of the app. Make sure you read it here. In Part 1 of this tutorial, we set up the basic infrastructure for the Wine Cellar application. In Part 2, we added the ability to create, update, and delete (CRUD) [...]]]></description>
				<content:encoded><![CDATA[<p><strong>UPDATE: I posted a &#8220;Postface&#8221; to this series with some lessons learned and an improved version of the app. Make sure you read it <a href="http://coenraets.org/blog/2012/01/backbone-js-lessons-learned-and-improved-sample-app/">here</a>.</strong></p>
<p>In <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-1-getting-started/">Part 1</a> of this tutorial, we set up the basic infrastructure for the Wine Cellar application. In <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-2-crud/">Part 2</a>, we added the ability to create, update, and delete (CRUD) wines.</p>
<p>There are a few remaining issues in the application. They are all related to &#8220;deep linking&#8221;. The application needs to continuously keep its URL in sync with its current state. This allows you to grab the URL from the address bar at any point in time during the course of the application, and re-use or share it to go back to the exact same state.</p>
<p>In this last installment of the tutorial, we add support for deep linking in the Wine Cellar application.<br />
<span id="more-2555"></span></p>
<h4>Problem 1: Linking to a specific wine</h4>
<p><strong>The problem</strong>: Select a specific wine from the list. The URL looks like this: http://www.coenraets.org/backbone-cellar/part2/#wines/<em>[id]</em>. Now do one of these two things:</p>
<ol>
<li>Grab that URL from the address bar and try to access it from another browser window or tab</li>
<li>Simply click your browser&#8217;s Refresh button</li>
</ol>
<p>You get an empty screen with no data. If you look at a debug console (for example, in Chrome&#8217;s Developer Tools), you&#8217;ll get this message:</p>
<p><a href="http://coenraets.org/blog/wp-content/uploads/2011/12/chome-error.jpg"><img src="http://coenraets.org/blog/wp-content/uploads/2011/12/chome-error.jpg" alt="" title="chome-error" width="640" height="317" class="alignnone size-full wp-image-2580" /></a></p>
<p>Let&#8217;s take a look at what&#8217;s going on here:</p>
<pre class="brush: jscript; title: ; notranslate">
var AppRouter = Backbone.Router.extend({

    routes:{
        &quot;&quot;:&quot;list&quot;,
        &quot;wines/:id&quot;:&quot;wineDetails&quot;
    },

    initialize:function () {
        $('#header').html(new HeaderView().render().el);
    },

    list:function () {
        this.wineList = new WineCollection();
        this.wineListView = new WineListView({model:this.wineList});
        this.wineList.fetch();
        $('#sidebar').html(this.wineListView.render().el);
    },

    wineDetails:function (id) {
        this.wine = this.wineList.get(id);
        if (app.wineView) app.wineView.close();
        this.wineView = new WineView({model:this.wine});
        $('#content').html(this.wineView.render().el);
    }

});
</pre>
<p>The problem is on line 20: we are assuming that a wine collection (this.wineList) already exists, and are trying to &#8220;get&#8221; a specific item from that list. That works well when we start the application with the default (&#8220;&#8221;) route. But this.wineList won&#8217;t exist if we start the application with the &#8220;wines/:id&#8221; route. There are different ways to address the issue:</p>
<p>We could modify the wineDetails function to fetch the requested item directly:</p>
<pre class="brush: jscript; title: ; notranslate">
	wineDetails: function(id) {
		this.wine = new Wine({id: id});
		this.wineView = new WineView({model: this.wine});
		this.wine.fetch();
  	}
</pre>
<p>That takes care of loading the wine details in the form, but the wine list remains empty when we start the application with &#8220;wines/:id&#8221; route. We could add the following line of code to load the list if it doesn&#8217;t exist:</p>
<pre class="brush: jscript; title: ; notranslate">
if (!this.wineList) this.list();
</pre>
<p>But now, the wine model that is part of the collection and the wine model fetched separately are two different objects, which means that data binding and View synchronization will not work as expected.</p>
<p>Another approach is to check if the collection exists in the wineDetails function. If it does, we simply &#8220;get&#8221; the requested item and render it as we did before. If it doesn&#8217;t, we store the requested id in a variable, and then invoke the existing list() function to populate the list. We then modify the list function: When we get the list from the server (on success), we check if there was a requested id. If there was, we invoke the wineDetails function to render the corresponding item.</p>
<pre class="brush: jscript; title: ; notranslate">
var AppRouter = Backbone.Router.extend({

    routes:{
        &quot;&quot;:&quot;list&quot;,
        &quot;wines/new&quot;:&quot;newWine&quot;,
        &quot;wines/:id&quot;:&quot;wineDetails&quot;
    },

    initialize:function () {
        $('#header').html(new HeaderView().render().el);
    },

    list:function () {
        this.wineList = new WineCollection();
        var self = this;
        this.wineList.fetch({
            success:function () {
                self.wineListView = new WineListView({model:self.wineList});
                $('#sidebar').html(self.wineListView.render().el);
                if (self.requestedId) self.wineDetails(self.requestedId);
            }
        });
    },

    wineDetails:function (id) {
        if (this.wineList) {
            this.wine = this.wineList.get(id);
            if (this.wineView) this.wineView.close();
            this.wineView = new WineView({model:this.wine});
            $('#content').html(this.wineView.render().el);
        } else {
            this.requestedId = id;
            this.list();
        }
    },

    newWine:function () {
        if (app.wineView) app.wineView.close();
        app.wineView = new WineView({model:new Wine()});
        $('#content').html(app.wineView.render().el);
    }

});
</pre>
<p>&nbsp;</p>
<h4>Problem 2: Updating the URL after a wine is created</h4>
<p><strong>The problem</strong>: Add a new Wine, and click Save. The id that has been assigned to the newly created wine appears in the form field. However the URL is still:<br />
http://localhost/backbone-cellar/part2/ when it should really be: http://localhost/backbone-cellar/part2/#wines/<em>[id]</em>.</p>
<p>You can easily fix that issue by using the router&#8217;s navigate function to change the URL. The second argument (false), indicates that we actually don&#8217;t want to &#8220;execute&#8221; that route: we just want to change the URL.</p>
<pre class="brush: jscript; title: ; notranslate">
if (this.model.isNew()) {
	var self = this;
	app.wineList.create(this.model, {
		success: function() {
			app.navigate('wines/'+self.model.id, false);
		}
	});
} else {
	this.model.save();
}
</pre>
<p>&nbsp;</p>
<h4>Problem 3: Updating the URL while creating a new wine</h4>
<p><strong>The problem</strong>: Select a wine in the list. The URL looks like this: http://localhost/backbone-cellar/part2/#wines/<em>[id]</em></p>
<p>Now, click the &#8220;Add Wine&#8221; button. You get an empty form to enter a new wine, but notice that the URL is still unchanged (http://localhost/backbone-cellar/part2/#wines/<em>[id]</em>). In other words, it doesn&#8217;t reflect the current state of the application.</p>
<p>In this case, we are going to add a new &#8220;route&#8221;:</p>
<pre class="brush: jscript; title: ; notranslate">
	routes: {
		&quot;&quot;			: &quot;list&quot;,
		&quot;wines/new&quot;	: &quot;newWine&quot;,
		&quot;wines/:id&quot;	: &quot;wineDetails&quot;
	},
</pre>
<p>The router&#8217;s newWine method is implemented as follows:</p>
<pre class="brush: jscript; title: ; notranslate">
	newWine: function() {
		console.log('MyRouter newWine');
		if (app.wineView) app.wineView.close();
		app.wineView = new WineView({model: new Wine()});
		app.wineView.render();
	}
</pre>
<p>And we can change the HeaderView newWine() method as follows:</p>
<pre class="brush: jscript; title: ; notranslate">
newWine: function(event) {
	app.navigate(&quot;wines/new&quot;, true);
	return false;
}
</pre>
<p>&nbsp;</p>
<h4>Putting it all together</h4>
<p>You can run the application (Part 3) <a href="http://coenraets.org/backbone-cellar/part3">here</a>. The create/update/delete features are disabled in this online version. Use the link at the bottom of this post to download a fully enabled version.</p>
<p>Here is the final version of the code:</p>
<pre class="brush: jscript; title: ; notranslate">
// Models
window.Wine = Backbone.Model.extend({
    urlRoot:&quot;../api/wines&quot;,
    defaults:{
        &quot;id&quot;:null,
        &quot;name&quot;:&quot;&quot;,
        &quot;grapes&quot;:&quot;&quot;,
        &quot;country&quot;:&quot;USA&quot;,
        &quot;region&quot;:&quot;California&quot;,
        &quot;year&quot;:&quot;&quot;,
        &quot;description&quot;:&quot;&quot;,
        &quot;picture&quot;:&quot;&quot;
    }
});

window.WineCollection = Backbone.Collection.extend({
    model:Wine,
    url:&quot;../api/wines&quot;
});


// Views
window.WineListView = Backbone.View.extend({

    tagName:'ul',

    initialize:function () {
        this.model.bind(&quot;reset&quot;, this.render, this);
        var self = this;
        this.model.bind(&quot;add&quot;, function (wine) {
            $(self.el).append(new WineListItemView({model:wine}).render().el);
        });
    },

    render:function (eventName) {
        _.each(this.model.models, function (wine) {
            $(this.el).append(new WineListItemView({model:wine}).render().el);
        }, this);
        return this;
    }
});

window.WineListItemView = Backbone.View.extend({

    tagName:&quot;li&quot;,

    template:_.template($('#tpl-wine-list-item').html()),

    initialize:function () {
        this.model.bind(&quot;change&quot;, this.render, this);
        this.model.bind(&quot;destroy&quot;, this.close, this);
    },

    render:function (eventName) {
        $(this.el).html(this.template(this.model.toJSON()));
        return this;
    },

    close:function () {
        $(this.el).unbind();
        $(this.el).remove();
    }
});

window.WineView = Backbone.View.extend({

    template:_.template($('#tpl-wine-details').html()),

    initialize:function () {
        this.model.bind(&quot;change&quot;, this.render, this);
    },

    render:function (eventName) {
        $(this.el).html(this.template(this.model.toJSON()));
        return this;
    },

    events:{
        &quot;change input&quot;:&quot;change&quot;,
        &quot;click .save&quot;:&quot;saveWine&quot;,
        &quot;click .delete&quot;:&quot;deleteWine&quot;
    },

    change:function (event) {
        var target = event.target;
        console.log('changing ' + target.id + ' from: ' + target.defaultValue + ' to: ' + target.value);
        // You could change your model on the spot, like this:
        // var change = {};
        // change[target.name] = target.value;
        // this.model.set(change);
    },

    saveWine:function () {
        this.model.set({
            name:$('#name').val(),
            grapes:$('#grapes').val(),
            country:$('#country').val(),
            region:$('#region').val(),
            year:$('#year').val(),
            description:$('#description').val()
        });
        if (this.model.isNew()) {
            var self = this;
            app.wineList.create(this.model, {
                success:function () {
                    app.navigate('wines/' + self.model.id, false);
                }
            });
        } else {
            this.model.save();
        }

        return false;
    },

    deleteWine:function () {
        this.model.destroy({
            success:function () {
                alert('Wine deleted successfully');
                window.history.back();
            }
        });
        return false;
    },

    close:function () {
        $(this.el).unbind();
        $(this.el).empty();
    }
});

window.HeaderView = Backbone.View.extend({

    template:_.template($('#tpl-header').html()),

    initialize:function () {
        this.render();
    },

    render:function (eventName) {
        $(this.el).html(this.template());
        return this;
    },

    events:{
        &quot;click .new&quot;:&quot;newWine&quot;
    },

    newWine:function (event) {
        app.navigate(&quot;wines/new&quot;, true);
        return false;
    }
});


// Router
var AppRouter = Backbone.Router.extend({

    routes:{
        &quot;&quot;:&quot;list&quot;,
        &quot;wines/new&quot;:&quot;newWine&quot;,
        &quot;wines/:id&quot;:&quot;wineDetails&quot;
    },

    initialize:function () {
        $('#header').html(new HeaderView().render().el);
    },

    list:function () {
        this.wineList = new WineCollection();
        var self = this;
        this.wineList.fetch({
            success:function () {
                self.wineListView = new WineListView({model:self.wineList});
                $('#sidebar').html(self.wineListView.render().el);
                if (self.requestedId) self.wineDetails(self.requestedId);
            }
        });
    },

    wineDetails:function (id) {
        if (this.wineList) {
            this.wine = this.wineList.get(id);
            if (this.wineView) this.wineView.close();
            this.wineView = new WineView({model:this.wine});
            $('#content').html(this.wineView.render().el);
        } else {
            this.requestedId = id;
            this.list();
        }
    },

    newWine:function () {
        if (app.wineView) app.wineView.close();
        app.wineView = new WineView({model:new Wine()});
        $('#content').html(app.wineView.render().el);
    }

});

var app = new AppRouter();
Backbone.history.start();
</pre>
<p>&nbsp;</p>
<h3>Download</h3>
<p>The source code for this application is hosted on GitHub <a href="https://github.com/ccoenraets/backbone-cellar">here</a> (see part3). And <a href="https://github.com/ccoenraets/backbone-cellar/zipball/master">here</a> is a quick link to the download.</p>
<p>You will need the RESTful services to run this application. A PHP version (using the Slim framework) is available as part of the download. </p>
<p><strong>UPDATE (1/11/2012):</strong> A version of this application with a Java back-end (using JAX-RS and Jersey) is also available on GitHub <a href="https://github.com/ccoenraets/backbone-jax-cellar">here</a>. You can find more information on the Java version of this application <a href="http://coenraets.org/blog/2012/01/using-backbone-js-with-a-restful-java-back-end/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-3-deep-linking-and-application-states/feed/</wfw:commentRss>
		<slash:comments>38</slash:comments>
		</item>
		<item>
		<title>Backbone.js Wine Cellar Tutorial — Part 2: CRUD</title>
		<link>http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-2-crud/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=backbone-js-wine-cellar-tutorial-part-2-crud</link>
		<comments>http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-2-crud/#comments</comments>
		<pubDate>Wed, 07 Dec 2011 16:52:01 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=2483</guid>
		<description><![CDATA[In Part 1 of this tutorial, we set up the basic infrastructure for the Wine Cellar application. The application so far is read-only: it allows you to retrieve a list of wines, and display the details of the wine you select. In this second installment, we will add the ability to create, update, and delete [...]]]></description>
				<content:encoded><![CDATA[<p>In <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-1-getting-started/">Part 1</a> of this tutorial, we set up the basic infrastructure for the Wine Cellar application. The application so far is read-only: it allows you to retrieve a list of wines, and display the details of the wine you select.</p>
<p>In this second installment, we will add the ability to create, update, and delete (CRUD) wines.</p>
<h4>RESTful Services</h4>
<p>As mentioned in Part 1, <a href="http://documentcloud.github.com/backbone/">Backbone.js</a> provides a natural and elegant integration with RESTful services. If your back-end data is exposed through a pure RESTful API, retrieving (GET), creating (POST), updating (PUT), and deleting (DELETE) models is incredibly easy using the Backbone.js simple Model API.</p>
<p>This tutorial uses pure RESTful services. The services are implemented as follows:</p>
<table style="border-collapse:collapse;margin-bottom:20px;">
<tr>
<th style="padding:4px;border: 1px solid #666666;width:150px;">HTTP Method</th>
<th style="padding:4px;border: 1px solid #666666;width:150px;">URL</th>
<th style="padding:4px;border: 1px solid #666666;width:300px;">Action</th>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">GET</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines</td>
<td style="padding:4px;border: 1px solid #666666;">Retrieve all wines</td>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">GET</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines/10
<td style="padding:4px;border: 1px solid #666666;">Retrieve wine with id == 10</td>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">POST</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines</td>
<td style="padding:4px;border: 1px solid #666666;">Add a new wine</td>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">PUT</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines/10</td>
<td style="padding:4px;border: 1px solid #666666;">Update wine with id == 10</td>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">DELETE</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines/10</td>
<td style="padding:4px;border: 1px solid #666666;">Delete wine with id == 10</td>
</tr>
</table>
<p><span id="more-2483"></span><br />
A PHP version of these services (using the <a href="http://www.slimframework.com/">Slim framework</a>) is available as part of the download. A similar Java version of the API (using JAX-RS) is available as part of <a href="http://coenraets.org/blog/2011/12/restful-services-with-jquery-and-java-using-jax-rs-and-jersey/">this post</a>.</p>
<p><strong>Using Backbone.js with non-RESTful Services</strong></p>
<p>If your persistence layer is not available through RESTful services, you can override Backbone.sync. From the documentation:</p>
<p><em>&#8220;Backbone.sync is the function that Backbone calls every time it attempts to read or save a model to the server. By default, it uses (jQuery/Zepto).ajax to make a RESTful JSON request. You can override it in order to use a different persistence strategy, such as WebSockets, XML transport, or Local Storage.&#8221;</em></p>
<p>Using non-RESTful services is not discussed in this tutorial. See the <a href="http://documentcloud.github.com/backbone/">documentation</a> for more information.</p>
<h3>Part 2: Adding Create, Update, Delete</h3>
<p>You can run the application (Part 2) <a href="http://coenraets.org/backbone-cellar/part2">here</a>. The create/update/delete features are disabled in this online version. Use the link at the bottom of this post to download a fully enabled version.</p>
<p>Here is the code for the improved version of the applications. Key changes are discussed below.</p>
<pre class="brush: jscript; title: ; notranslate">
// Models
window.Wine = Backbone.Model.extend({
    urlRoot:&quot;../api/wines&quot;,
    defaults:{
        &quot;id&quot;:null,
        &quot;name&quot;:&quot;&quot;,
        &quot;grapes&quot;:&quot;&quot;,
        &quot;country&quot;:&quot;USA&quot;,
        &quot;region&quot;:&quot;California&quot;,
        &quot;year&quot;:&quot;&quot;,
        &quot;description&quot;:&quot;&quot;,
        &quot;picture&quot;:&quot;&quot;
    }
});

window.WineCollection = Backbone.Collection.extend({
    model:Wine,
    url:&quot;../api/wines&quot;
});


// Views
window.WineListView = Backbone.View.extend({

    tagName:'ul',

    initialize:function () {
        this.model.bind(&quot;reset&quot;, this.render, this);
        var self = this;
        this.model.bind(&quot;add&quot;, function (wine) {
            $(self.el).append(new WineListItemView({model:wine}).render().el);
        });
    },

    render:function (eventName) {
        _.each(this.model.models, function (wine) {
            $(this.el).append(new WineListItemView({model:wine}).render().el);
        }, this);
        return this;
    }
});

window.WineListItemView = Backbone.View.extend({

    tagName:&quot;li&quot;,

    template:_.template($('#tpl-wine-list-item').html()),

    initialize:function () {
        this.model.bind(&quot;change&quot;, this.render, this);
        this.model.bind(&quot;destroy&quot;, this.close, this);
    },

    render:function (eventName) {
        $(this.el).html(this.template(this.model.toJSON()));
        return this;
    },

    close:function () {
        $(this.el).unbind();
        $(this.el).remove();
    }
});

window.WineView = Backbone.View.extend({

    template:_.template($('#tpl-wine-details').html()),

    initialize:function () {
        this.model.bind(&quot;change&quot;, this.render, this);
    },

    render:function (eventName) {
        $(this.el).html(this.template(this.model.toJSON()));
        return this;
    },

    events:{
        &quot;change input&quot;:&quot;change&quot;,
        &quot;click .save&quot;:&quot;saveWine&quot;,
        &quot;click .delete&quot;:&quot;deleteWine&quot;
    },

    change:function (event) {
        var target = event.target;
        console.log('changing ' + target.id + ' from: ' + target.defaultValue + ' to: ' + target.value);
        // You could change your model on the spot, like this:
        // var change = {};
        // change[target.name] = target.value;
        // this.model.set(change);
    },

    saveWine:function () {
        this.model.set({
            name:$('#name').val(),
            grapes:$('#grapes').val(),
            country:$('#country').val(),
            region:$('#region').val(),
            year:$('#year').val(),
            description:$('#description').val()
        });
        if (this.model.isNew()) {
            app.wineList.create(this.model);
        } else {
            this.model.save();
        }
        return false;
    },

    deleteWine:function () {
        this.model.destroy({
            success:function () {
                alert('Wine deleted successfully');
                window.history.back();
            }
        });
        return false;
    },

    close:function () {
        $(this.el).unbind();
        $(this.el).empty();
    }
});

window.HeaderView = Backbone.View.extend({

    template:_.template($('#tpl-header').html()),

    initialize:function () {
        this.render();
    },

    render:function (eventName) {
        $(this.el).html(this.template());
        return this;
    },

    events:{
        &quot;click .new&quot;:&quot;newWine&quot;
    },

    newWine:function (event) {
        if (app.wineView) app.wineView.close();
        app.wineView = new WineView({model:new Wine()});
        $('#content').html(app.wineView.render().el);
        return false;
    }
});


// Router
var AppRouter = Backbone.Router.extend({

    routes:{
        &quot;&quot;:&quot;list&quot;,
        &quot;wines/:id&quot;:&quot;wineDetails&quot;
    },

    initialize:function () {
        $('#header').html(new HeaderView().render().el);
    },

    list:function () {
        this.wineList = new WineCollection();
        this.wineListView = new WineListView({model:this.wineList});
        this.wineList.fetch();
        $('#sidebar').html(this.wineListView.render().el);
    },

    wineDetails:function (id) {
        this.wine = this.wineList.get(id);
        if (app.wineView) app.wineView.close();
        this.wineView = new WineView({model:this.wine});
        $('#content').html(this.wineView.render().el);
    }

});

var app = new AppRouter();
Backbone.history.start();
</pre>
<h4>Wine</h4>
<p>Two attributes were added to the Wine Model:</p>
<ul>
<li><strong>urlRoot</strong>: RESTful service endpoint to retrieve or persist Model data. Note that this attribute is only needed when retrieving/persisting Models that are not part of a Collection. If the Model is part of a Collection, the <strong>url</strong> attribute defined in the Collection is enough for Backbone.js to know how to retrieve, update, or delete data using your RESTful API.</li>
<li><strong>defaults</strong>: Default values used when a new instance of the model is created. This attribute is optional. However, it was required in this application for the wine-details template to render an &#8216;empty&#8217; wine model object (which happens when adding a new wine).</li>
</ul>
<h4>WineListView</h4>
<p>When a new wine is added, you want it to automatically appear in the list. To make that happen, you bind the View to the <strong>add</strong> event of the WineListView model (which is the collection of wines). When that event is fired, a new instance of WineListItemView is created and added to the list.</p>
<h4>WineListItemView</h4>
<p>When a wine is changed, you want the corresponding WineListItemView to re-render automatically to reflect the change. To make that happen, you bind the View to the <strong>change</strong> event of its model, and execute the render function when the event is fired.</p>
<p>Similarly, when a wine is deleted, you want the list item to be removed automatically. To make that happen, you bind the view to the <strong>destroy</strong> event of its model and execute our custom close function when the event is fired. To <strong>avoid memory leaks and events firing multiple times</strong>, it is important to unbind the event listeners before removing the list item from the DOM.</p>
<p>Note that in either case we don&#8217;t have the overhead of re-rendering the entire list: we only re-render or remove the list item affected by the change.</p>
<h4>WineView</h4>
<p>In the spirit of encapsulation, the event handlers for the Save and Delete buttons are defined inside WineView, as opposed to defining them as free-hanging code blocks outside the &#8220;class&#8221; definitions. You use the Backbone.js Events syntax which uses jQuery delegate mechanism behind the scenes.</p>
<p>There are always different approaches to update the model based on user input in a form:</p>
<ul>
<li>&#8220;Real time&#8221; approach: you use the change handler to update the model as changes are made in the form. This is in essence bi-directional data binding: the model and the UI controls are always in sync. Using this approach, you can then choose between sending changes to the server in real time (implicit save), or wait until the user clicks a Save button (explicit save). The first option can be chatty and unpractical when there are cross-field validation rules. The second option may require you to undo model changes if the user navigates to another item without clicking Save.</li>
<li>&#8220;Delayed&#8221; approach: You wait until the user clicks Save to update the model based on the new values in UI controls, and then send the changes to the server.</li>
</ul>
<p>This discussion is not specific to Backbone.js and is therefore beyond the scope of this post. For simplicity, I used the delayed approach here. However I still wired the <strong>change</strong> event, and use it to log changes to the console. I found this very useful when debugging the application, and particularly to make sure I had cleaned up my bindings (see close function): I you see the change event firing multiple times, you probably didn&#8217;t clean up as appropriate.</p>
<h4>HeaderView</h4>
<p>Backbone.js Views are typically used to render domain models (as done in WineListView, WineListItemView, and Wine View). But they can also be used to create composite UI components. For example, in this application, we define a Header View (a toolbar) that could be made of different components and that encapsulates its own logic.</p>
<h3>Download</h3>
<p>The source code for this application is hosted on GitHub <a href="https://github.com/ccoenraets/backbone-cellar">here</a> (see part2). And <a href="https://github.com/ccoenraets/backbone-cellar/zipball/master">here</a> is a quick link to the download.</p>
<p>You will need the RESTful services to run this application. A PHP version (using the Slim framework) is available as part of the download. </p>
<p><strong>UPDATE (1/11/2012):</strong> A version of this application with a Java back-end (using JAX-RS and Jersey) is also available on GitHub <a href="https://github.com/ccoenraets/backbone-jax-cellar">here</a>. You can find more information on the Java version of this application <a href="http://coenraets.org/blog/2012/01/using-backbone-js-with-a-restful-java-back-end/">here</a>.</p>
<h3>What&#8217;s Next?</h3>
<p>The application so far doesn&#8217;t support deep-linking. For example, select a wine in the list, grab the URL in the address bar and paste it in another browser window: it doesn&#8217;t work. In <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-3-deep-linking-and-application-states/">Part 3</a>, we will add complete support for deep linking.</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-2-crud/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>Backbone.js Wine Cellar Tutorial &#8212; Part 1: Getting Started</title>
		<link>http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-1-getting-started/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=backbone-js-wine-cellar-tutorial-part-1-getting-started</link>
		<comments>http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-1-getting-started/#comments</comments>
		<pubDate>Tue, 06 Dec 2011 21:07:57 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=2433</guid>
		<description><![CDATA[One of the challenges when building nontrivial Web applications is that JavaScript’s non-directive nature can initially lead to a lack of structure in your code, or in other words, a lack of&#8230; backbone. JavaScript is often written as a litany of free-hanging and unrelated blocks of code, and it doesn’t take long before it becomes [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://coenraets.org/blog/wp-content/uploads/2011/12/backbone.png"><img src="http://coenraets.org/blog/wp-content/uploads/2011/12/backbone.png" alt="" title="backbone" width="451" height="80" class="alignnone size-full wp-image-2479" /></a></p>
<p>One of the challenges when building nontrivial Web applications is that JavaScript’s non-directive nature can initially lead to a lack of structure in your code, or in other words, a lack of&#8230; backbone. JavaScript is often written as a litany of free-hanging and unrelated blocks of code, and it doesn’t take long before it becomes hard to make sense of the logic and organization of your own code.</p>
<p><a href="http://documentcloud.github.com/backbone/">Backbone.js</a> is a lightweight framework that addresses this issue by adding structure to JavaScript-heavy Web applications.<br />
<span id="more-2433"></span><br />
<strong>Self-contained building blocks</strong></p>
<p>Backbone.js provides several classes (Model, Collection, View, Router) that you can extend to define the building blocks of your application. To build an app with Backbone.js, you first create the Models, Collections, and Views of your application. You then bring these components to life by defining a “Router” that provides the entry points of your application through a set of (deep-linkable) URLs.</p>
<p>With Backbone.js, your code is organized in self-contained entities (Models, Collections, Views): No more free-hanging and unrelated blocks of code.</p>
<p><strong>Data Binding</strong></p>
<p>With Backbone.js, you bind Views to Models so that when a Model&#8217;s data changes, all the Views bound to that Model automatically re-render. No more complex UI synchronization code.</p>
<p><strong>Elegant REST Integration</strong></p>
<p>Backbone.js also provides a natural / magical / elegant integration with RESTful services. If your back-end data is exposed through a pure RESTful API, retrieving (GET), creating (POST), updating (PUT), and deleting (DELETE) models is incredibly easy using the Backbone.js simple Model API.</p>
<h3>Sample Application</h3>
<p>In this three-part tutorial, you&#8217;ll create a Wine Cellar application. You can browse through a list of wines, as well as add, update, and delete wines.</p>
<ul>
<li>In Part 1 (this post), you define the basic infrastructure. You create a “read-only” version of the application: you’ll be able to retrieve a list of wine and get the details of each wine.</li>
<li>In Part 2, you add the code to add, update and delete wines. You leverage Backbone’s powerful REST integration.</li>
<li>In Part 3, you add complete support for history management and deep linking.</li>
</ul>
<p><img src="http://coenraets.org/blog/wp-content/uploads/2011/12/cellar2.jpg" alt="" title="cellar2" width="640" height="496" class="alignnone size-full wp-image-2392" /><br />
NOTE: I also blogged a non-Backbone version of the application <a href="http://coenraets.org/blog/2011/12/restful-services-with-jquery-and-java-using-jax-rs-and-jersey/">here (Java back-end)</a> and <a href="http://coenraets.org/blog/2011/12/restful-services-with-jquery-php-and-the-slim-framework/">here (PHP back-end)</a>, which you can look at for comparison.</p>
<h4>Part 1: The Read-Only Wine Cellar Application</h4>
<p>You can run the application (Part 1) <a href="http://coenraets.org/backbone-cellar/part1">here</a>.</p>
<p>Here is the code:</p>
<pre class="brush: jscript; title: ; notranslate">
// Models
window.Wine = Backbone.Model.extend();

window.WineCollection = Backbone.Collection.extend({
    model:Wine,
    url:&quot;../api/wines&quot;
});

// Views
window.WineListView = Backbone.View.extend({

    tagName:'ul',

    initialize:function () {
        this.model.bind(&quot;reset&quot;, this.render, this);
    },

    render:function (eventName) {
        _.each(this.model.models, function (wine) {
            $(this.el).append(new WineListItemView({model:wine}).render().el);
        }, this);
        return this;
    }

});

window.WineListItemView = Backbone.View.extend({

    tagName:&quot;li&quot;,

    template:_.template($('#tpl-wine-list-item').html()),

    render:function (eventName) {
        $(this.el).html(this.template(this.model.toJSON()));
        return this;
    }

});

window.WineView = Backbone.View.extend({

    template:_.template($('#tpl-wine-details').html()),

    render:function (eventName) {
        $(this.el).html(this.template(this.model.toJSON()));
        return this;
    }

});

// Router
var AppRouter = Backbone.Router.extend({

    routes:{
        &quot;&quot;:&quot;list&quot;,
        &quot;wines/:id&quot;:&quot;wineDetails&quot;
    },

    list:function () {
        this.wineList = new WineCollection();
        this.wineListView = new WineListView({model:this.wineList});
        this.wineList.fetch();
        $('#sidebar').html(this.wineListView.render().el);
    },

    wineDetails:function (id) {
        this.wine = this.wineList.get(id);
        this.wineView = new WineView({model:this.wine});
        $('#content').html(this.wineView.render().el);
    }
});

var app = new AppRouter();
Backbone.history.start();
</pre>
<p><strong>Code Highlights:</strong></p>
<ol>
<li><strong>WineModel</strong> (line 2): Notice that we don&#8217;t need to explicitly define the attributes (name, country, year, etc). You could add validation, default values, etc. More on that in Part 2.</li>
<li><strong>WineCollection</strong> (lines 4 to 7): &#8220;model&#8221; indicates the nature of the collection. &#8220;url&#8221; provides the endpoint for the RESTFul API. This is all that&#8217;s needed to retrieve, create, update, and delete wines with Backbone&#8217;s simple Model API.</li>
<li><strong>WineListView</strong> (lines 10 to 25): The render() function iterates through the collection, instantiates a WineListItemView for each wine in the collection, and adds it to the wineList.</li>
<li><strong>WineListItemView</strong> (lines 27 to 38): The render() function merges the model data into the &#8220;wine-list-item&#8221; template (defined in index.html). By defining a separate View for list items, you will make it easy to update (re-render) a specific list item when the backing model changes without re-rendering the entire list. More on that in Part 2.</li>
<li><strong>WineView</strong> (lines 40 to 49): The view responsible for displaying the wine details in the Wine form. The render() function merges the model data (a specific wine) into the &#8220;wine-details&#8221; template retrieved from index.html.</li>
<li><strong>AppRouter</strong> (lines 52 to 71): Provides the entry points for the application through a set of (deep-linkable) URLs. Two routes are defined: The default route (&#8220;&#8221;) displays the list of wine. The &#8220;wines/:id&#8221; route displays the details of a specific wine in the wine form. Note that in Part 1, this route is not deep-linkable. You have to start the application with the default route and then select a specific wine. In Part 3, you will make sure you can deep-link to a specific wine.</li>
</ol>
<h4>Download</h4>
<p>The source code for this application is hosted on GitHub <a href="https://github.com/ccoenraets/backbone-cellar">here</a>. And <a href="https://github.com/ccoenraets/backbone-cellar/zipball/master">here</a> is a quick link to the download.</p>
<p>You will need the RESTful services to run this application. A PHP version (using the <a href="http://www.slimframework.com/">Slim framework</a>) is available as part of the download. </p>
<p><strong>UPDATE (1/11/2012):</strong> A version of this application with a Java back-end (using JAX-RS and Jersey) is also available on GitHub <a href="https://github.com/ccoenraets/backbone-jax-cellar">here</a>. You can find more information on the Java version of this application <a href="http://coenraets.org/blog/2012/01/using-backbone-js-with-a-restful-java-back-end/">here</a>.</p>
<p>Part 2 is available <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-2-crud/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-1-getting-started/feed/</wfw:commentRss>
		<slash:comments>101</slash:comments>
		</item>
		<item>
		<title>RESTful services with jQuery, PHP and the Slim Framework</title>
		<link>http://coenraets.org/blog/2011/12/restful-services-with-jquery-php-and-the-slim-framework/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=restful-services-with-jquery-php-and-the-slim-framework</link>
		<comments>http://coenraets.org/blog/2011/12/restful-services-with-jquery-php-and-the-slim-framework/#comments</comments>
		<pubDate>Thu, 01 Dec 2011 17:12:06 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[JQuery]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=2369</guid>
		<description><![CDATA[NOTE: This is the PHP version of this article and its companion app. A Java version is available here. I have been looking for a lightweight framework to build a RESTful API in PHP. There are a number of good options out there: Slim, Epiphany, Tonic, Recess, and Frapi to name a few. They all [...]]]></description>
				<content:encoded><![CDATA[<p>NOTE: This is the PHP version of this article and its companion app. A Java version is available <a href="http://coenraets.org/blog/2011/12/restful-services-with-jquery-and-java-using-jax-rs-and-jersey/">here</a>.</p>
<p>I have been looking for a lightweight framework to build a RESTful API in PHP. There are a number of good options out there: <a href="http://www.slimframework.com/">Slim</a>, <a href="https://github.com/jmathai/epiphany">Epiphany</a>, <a href="http://peej.github.com/tonic/">Tonic</a>, <a href="http://www.recessframework.org/">Recess</a>, and <a href="http://getfrapi.com/">Frapi</a> to name a few. They all seem like good frameworks. In the end, I chose Slim for this project for two main reasons:</p>
<ol>
<li>It&#8217;s very lightweight and focused on REST and nothing else.</li>
<li>It supports all the HTTP methods (GET, POST, PUT, DELETE), which was a key requirement for my application.</li>
</ol>
<p>This article (and its companion app) provides an example of building a complete RESTful API using the different HTTP methods:</p>
<ul>
<li><strong>GET</strong> to retrieve and search data</li>
<li><strong>POST</strong> to add data</li>
<li><strong>PUT</strong> to update data</li>
<li><strong>DELETE</strong> to delete data</li>
</ul>
<p>The application used as an example for this article is a Wine Cellar app. You can search for wines, add a wine to your cellar, update and delete wines.</p>
<p><a href="http://coenraets.org/cellar"><img src="http://coenraets.org/blog/wp-content/uploads/2011/12/cellar2.jpg" alt="" title="cellar2" width="640" height="496" class="alignnone size-full wp-image-2392" /></a><br />
You can run the application <a href="http://coenraets.org/cellar">here</a>. The create/update/delete features are disabled in this online version. Use the link at the bottom of this post to download a fully enabled version.<br />
<span id="more-2369"></span></p>
<p>The REST API consists of the following methods:</p>
<table style="border-collapse:collapse;">
<tr>
<th style="padding:4px;border: 1px solid #666666;">Method</th>
<th style="padding:4px;border: 1px solid #666666;">URL</th>
<th style="padding:4px;border: 1px solid #666666;">Action</th>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">GET</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines</td>
<td style="padding:4px;border: 1px solid #666666;">Retrieve all wines</td>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">GET</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines/search/Chateau
<td style="padding:4px;border: 1px solid #666666;">Search for wines with &#8216;Chateau&#8217; in their name</td>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">GET</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines/10
<td style="padding:4px;border: 1px solid #666666;">Retrieve wine with id == 10</td>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">POST</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines</td>
<td style="padding:4px;border: 1px solid #666666;">Add a new wine</td>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">PUT</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines/10</td>
<td style="padding:4px;border: 1px solid #666666;">Update wine with id == 10</td>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">DELETE</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines/10</td>
<td style="padding:4px;border: 1px solid #666666;">Delete wine with id == 10</td>
</tr>
</table>
<p>&nbsp;</p>
<h4>Implementing the API with Slim</h4>
<p>Slim makes it easy to implement this API in PHP:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

require 'Slim/Slim.php';

$app = new Slim();

$app-&gt;get('/wines', 'getWines');
$app-&gt;get('/wines/:id',	'getWine');
$app-&gt;get('/wines/search/:query', 'findByName');
$app-&gt;post('/wines', 'addWine');
$app-&gt;put('/wines/:id', 'updateWine');
$app-&gt;delete('/wines/:id',	'deleteWine');

$app-&gt;run();

function getWines() {
	$sql = &quot;select * FROM wine ORDER BY name&quot;;
	try {
		$db = getConnection();
		$stmt = $db-&gt;query($sql);
		$wines = $stmt-&gt;fetchAll(PDO::FETCH_OBJ);
		$db = null;
		echo '{&quot;wine&quot;: ' . json_encode($wines) . '}';
	} catch(PDOException $e) {
		echo '{&quot;error&quot;:{&quot;text&quot;:'. $e-&gt;getMessage() .'}}';
	}
}

function getWine($id) {
	$sql = &quot;SELECT * FROM wine WHERE id=:id&quot;;
	try {
		$db = getConnection();
		$stmt = $db-&gt;prepare($sql);
		$stmt-&gt;bindParam(&quot;id&quot;, $id);
		$stmt-&gt;execute();
		$wine = $stmt-&gt;fetchObject();
		$db = null;
		echo json_encode($wine);
	} catch(PDOException $e) {
		echo '{&quot;error&quot;:{&quot;text&quot;:'. $e-&gt;getMessage() .'}}';
	}
}

function addWine() {
	$request = Slim::getInstance()-&gt;request();
	$wine = json_decode($request-&gt;getBody());
	$sql = &quot;INSERT INTO wine (name, grapes, country, region, year, description) VALUES (:name, :grapes, :country, :region, :year, :description)&quot;;
	try {
		$db = getConnection();
		$stmt = $db-&gt;prepare($sql);
		$stmt-&gt;bindParam(&quot;name&quot;, $wine-&gt;name);
		$stmt-&gt;bindParam(&quot;grapes&quot;, $wine-&gt;grapes);
		$stmt-&gt;bindParam(&quot;country&quot;, $wine-&gt;country);
		$stmt-&gt;bindParam(&quot;region&quot;, $wine-&gt;region);
		$stmt-&gt;bindParam(&quot;year&quot;, $wine-&gt;year);
		$stmt-&gt;bindParam(&quot;description&quot;, $wine-&gt;description);
		$stmt-&gt;execute();
		$wine-&gt;id = $db-&gt;lastInsertId();
		$db = null;
		echo json_encode($wine);
	} catch(PDOException $e) {
		echo '{&quot;error&quot;:{&quot;text&quot;:'. $e-&gt;getMessage() .'}}';
	}
}

function updateWine($id) {
	$request = Slim::getInstance()-&gt;request();
	$body = $request-&gt;getBody();
	$wine = json_decode($body);
	$sql = &quot;UPDATE wine SET name=:name, grapes=:grapes, country=:country, region=:region, year=:year, description=:description WHERE id=:id&quot;;
	try {
		$db = getConnection();
		$stmt = $db-&gt;prepare($sql);
		$stmt-&gt;bindParam(&quot;name&quot;, $wine-&gt;name);
		$stmt-&gt;bindParam(&quot;grapes&quot;, $wine-&gt;grapes);
		$stmt-&gt;bindParam(&quot;country&quot;, $wine-&gt;country);
		$stmt-&gt;bindParam(&quot;region&quot;, $wine-&gt;region);
		$stmt-&gt;bindParam(&quot;year&quot;, $wine-&gt;year);
		$stmt-&gt;bindParam(&quot;description&quot;, $wine-&gt;description);
		$stmt-&gt;bindParam(&quot;id&quot;, $id);
		$stmt-&gt;execute();
		$db = null;
		echo json_encode($wine);
	} catch(PDOException $e) {
		echo '{&quot;error&quot;:{&quot;text&quot;:'. $e-&gt;getMessage() .'}}';
	}
}

function deleteWine($id) {
	$sql = &quot;DELETE FROM wine WHERE id=:id&quot;;
	try {
		$db = getConnection();
		$stmt = $db-&gt;prepare($sql);
		$stmt-&gt;bindParam(&quot;id&quot;, $id);
		$stmt-&gt;execute();
		$db = null;
	} catch(PDOException $e) {
		echo '{&quot;error&quot;:{&quot;text&quot;:'. $e-&gt;getMessage() .'}}';
	}
}

function findByName($query) {
	$sql = &quot;SELECT * FROM wine WHERE UPPER(name) LIKE :query ORDER BY name&quot;;
	try {
		$db = getConnection();
		$stmt = $db-&gt;prepare($sql);
		$query = &quot;%&quot;.$query.&quot;%&quot;;
		$stmt-&gt;bindParam(&quot;query&quot;, $query);
		$stmt-&gt;execute();
		$wines = $stmt-&gt;fetchAll(PDO::FETCH_OBJ);
		$db = null;
		echo '{&quot;wine&quot;: ' . json_encode($wines) . '}';
	} catch(PDOException $e) {
		echo '{&quot;error&quot;:{&quot;text&quot;:'. $e-&gt;getMessage() .'}}';
	}
}

function getConnection() {
	$dbhost=&quot;127.0.0.1&quot;;
	$dbuser=&quot;root&quot;;
	$dbpass=&quot;&quot;;
	$dbname=&quot;cellar&quot;;
	$dbh = new PDO(&quot;mysql:host=$dbhost;dbname=$dbname&quot;, $dbuser, $dbpass);
	$dbh-&gt;setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	return $dbh;
}

?&gt;
</pre>
<p><strong>Code Highlights</strong></p>
<ol>
<li>Lines 7 to 12: Slim helps you route resource URIs to callback functions in response to specific HTTP request methods (e.g. GET, POST, PUT, DELETE).</li>
<li>Lines 45 to 46 and 67 to 68: the request object makes it easy to access the request&#8217;s data: In this case the JSON representation of a wine object.</li>
<li>The approach you use to actually retrieve the data is totally up to you. In this example, I use some simple PDO code, but you can of course use your own data access solution.</li>
</ol>
<h4>Testing the API using cURL</h4>
<p>If you want to test your API before using it in a client application, you can invoke your REST services straight from a browser address bar. For example, you could try:</p>
<ul>
<li><a href="http://localhost/cellar/api/wines">http://localhost/cellar/api/wines</a></li>
<li><a href="http://localhost/cellar/api/wines/search/Chateau">http://localhost/cellar/api/wines/search/Chateau</a></li>
<li><a href="http://localhost/cellar/api/wines/5">http://localhost/cellar/api/wines/5</a></li>
</ul>
<p>You will only be able to test your GET services that way, and even then, it doesn&#8217;t give you full control to test all the content types your API can return.</p>
<p>A more versatile solution to test RESTful services is to use <a href="http://curl.haxx.se/">cURL</a>, a command line utility for transferring data with URL syntax.</p>
<p>For example, using cURL, you can test the Wine Cellar API with the following commands:</p>
<ul>
<li>Get all wines:
<pre class="brush: bash; gutter: false; title: ; wrap-lines: true; notranslate">
curl -i -X GET http://localhost/cellar/api/wines
</pre>
</li>
<li>Get all wines with &#8216;chateau&#8217; in their name:
<pre class="brush: bash; gutter: false; title: ; wrap-lines: true; notranslate">
curl -i -X GET http://localhost/cellar/api/wines/search/chateau
</pre>
</li>
<li>Get wine #5:
<pre class="brush: bash; gutter: false; title: ; wrap-lines: true; notranslate">
curl -i -X GET http://localhost/cellar/api/wines/5
</pre>
</li>
<li>Delete wine #5:
<pre class="brush: bash; gutter: false; title: ; wrap-lines: true; notranslate">
curl -i -X DELETE http://localhost/cellar/api/wines/5
</pre>
</li>
<li>Add a new wine:
<pre class="brush: bash; gutter: false; title: ; wrap-lines: true; notranslate">
curl -i -X POST -H 'Content-Type: application/json' -d '{&quot;name&quot;: &quot;New Wine&quot;, &quot;year&quot;: &quot;2009&quot;}' http://localhost/cellar/api/wines
</pre>
</li>
<li>Modify wine #27:
<pre class="brush: bash; gutter: false; title: ; wrap-lines: true; notranslate">
curl -i -X PUT -H 'Content-Type: application/json' -d '{&quot;id&quot;: &quot;27&quot;, &quot;name&quot;: &quot;New Wine&quot;, &quot;year&quot;: &quot;2010&quot;}' http://localhost/cellar/api/wines/27
</pre>
</li>
</ul>
<h4>The jQuery Client</h4>
<p>Accessing your API through cURL is cool, but there is nothing like a real application to put your API to the test. So the source code (available for download at the end of this post) includes a simple jQuery client to manage your wine cellar.</p>
<p>Here is the jQuery code involved in calling the services:</p>
<pre class="brush: jscript; title: ; notranslate">
function findAll() {
	$.ajax({
		type: 'GET',
		url: rootURL,
		dataType: &quot;json&quot;, // data type of response
		success: renderList
	});
}

function findByName(searchKey) {
	$.ajax({
		type: 'GET',
		url: rootURL + '/search/' + searchKey,
		dataType: &quot;json&quot;,
		success: renderList
	});
}

function findById(id) {
	$.ajax({
		type: 'GET',
		url: rootURL + '/' + id,
		dataType: &quot;json&quot;,
		success: function(data){
			$('#btnDelete').show();
			renderDetails(data);
		}
	});
}

function addWine() {
	console.log('addWine');
	$.ajax({
		type: 'POST',
		contentType: 'application/json',
		url: rootURL,
		dataType: &quot;json&quot;,
		data: formToJSON(),
		success: function(data, textStatus, jqXHR){
			alert('Wine created successfully');
			$('#btnDelete').show();
			$('#wineId').val(data.id);
		},
		error: function(jqXHR, textStatus, errorThrown){
			alert('addWine error: ' + textStatus);
		}
	});
}

function updateWine() {
	$.ajax({
		type: 'PUT',
		contentType: 'application/json',
		url: rootURL + '/' + $('#wineId').val(),
		dataType: &quot;json&quot;,
		data: formToJSON(),
		success: function(data, textStatus, jqXHR){
			alert('Wine updated successfully');
		},
		error: function(jqXHR, textStatus, errorThrown){
			alert('updateWine error: ' + textStatus);
		}
	});
}

function deleteWine() {
	console.log('deleteWine');
	$.ajax({
		type: 'DELETE',
		url: rootURL + '/' + $('#wineId').val(),
		success: function(data, textStatus, jqXHR){
			alert('Wine deleted successfully');
		},
		error: function(jqXHR, textStatus, errorThrown){
			alert('deleteWine error');
		}
	});
}

// Helper function to serialize all the form fields into a JSON string
function formToJSON() {
	return JSON.stringify({
		&quot;id&quot;: $('#id').val(),
		&quot;name&quot;: $('#name').val(),
		&quot;grapes&quot;: $('#grapes').val(),
		&quot;country&quot;: $('#country').val(),
		&quot;region&quot;: $('#region').val(),
		&quot;year&quot;: $('#year').val(),
		&quot;description&quot;: $('#description').val()
		});
}

</pre>
<p>&nbsp;</p>
<h4>Download the Source Code</h4>
<p>The source code for this application is hosted on GitHub <a href="https://github.com/ccoenraets/wine-cellar-php">here</a>. And <a href="https://github.com/ccoenraets/wine-cellar-php/zipball/master">here</a> is a quick link to the source code download. It includes both the PHP and jQuery code for the application.</p>
<p>I&#8217;m interested in your feedback. Let me know what you think and what your experience has been building RESTful-based applications using PHP and jQuery</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2011/12/restful-services-with-jquery-php-and-the-slim-framework/feed/</wfw:commentRss>
		<slash:comments>74</slash:comments>
		</item>
		<item>
		<title>RESTful services with jQuery and Java using JAX-RS and Jersey</title>
		<link>http://coenraets.org/blog/2011/12/restful-services-with-jquery-and-java-using-jax-rs-and-jersey/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=restful-services-with-jquery-and-java-using-jax-rs-and-jersey</link>
		<comments>http://coenraets.org/blog/2011/12/restful-services-with-jquery-and-java-using-jax-rs-and-jersey/#comments</comments>
		<pubDate>Thu, 01 Dec 2011 15:28:51 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JAX-RS]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=2244</guid>
		<description><![CDATA[NOTE: This is the Java version of this article and its companion app. A PHP version is available here. This is a more in depth version of my previous post on the same topic. The previous article only covered the HTTP GET method for building RESTful services. This article (and its new companion app) provides [...]]]></description>
				<content:encoded><![CDATA[<p>NOTE: This is the Java version of this article and its companion app. A PHP version is available <a href="http://coenraets.org/blog/2011/12/restful-services-with-jquery-php-and-the-slim-framework/">here</a>.</p>
<p>This is a more in depth version of my <a href="http://coenraets.org/blog/2011/11/building-apps-with-jquery-and-jax-rs-sample-app/">previous post</a> on the same topic. The previous article only covered the HTTP GET method for building RESTful services. This article (and its new  companion app) provides an example of building a complete RESTful API using the different HTTP methods:</p>
<ul>
<li><strong>GET</strong> to retrieve and search data</li>
<li><strong>POST</strong> to add data</li>
<li><strong>PUT</strong> to update data</li>
<li><strong>DELETE</strong> to delete data</li>
</ul>
<p>The application used as an example for this article is a Wine Cellar app. You can search for wines, add a wine to your cellar, update and delete wines.</p>
<p><a href="http://coenraets.org/cellar"><img src="http://coenraets.org/blog/wp-content/uploads/2011/12/cellar2.jpg" alt="" title="cellar2" width="640" height="496" class="alignnone size-full wp-image-2392" /></a><br />
You can run the application <a href="http://coenraets.org/cellar">here</a>. The create/update/delete features are disabled in this online version. Use the link at the bottom of this post to download a fully enabled version.<br />
<span id="more-2244"></span><br />
The REST API consists of the following methods:</p>
<table style="border-collapse:collapse;">
<tr>
<th style="padding:4px;border: 1px solid #666666;">Method</th>
<th style="padding:4px;border: 1px solid #666666;">URL</th>
<th style="padding:4px;border: 1px solid #666666;">Action</th>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">GET</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines</td>
<td style="padding:4px;border: 1px solid #666666;">Retrieve all wines</td>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">GET</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines/search/Chateau
<td style="padding:4px;border: 1px solid #666666;">Search for wines with &#8216;Chateau&#8217; in their name</td>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">GET</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines/10
<td style="padding:4px;border: 1px solid #666666;">Retrieve wine with id == 10</td>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">POST</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines</td>
<td style="padding:4px;border: 1px solid #666666;">Add a new wine</td>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">PUT</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines/10</td>
<td style="padding:4px;border: 1px solid #666666;">Update wine with id == 10</td>
</tr>
<tr>
<td style="padding:4px;border: 1px solid #666666;">DELETE</td>
<td style="padding:4px;border: 1px solid #666666;">/api/wines/10</td>
<td style="padding:4px;border: 1px solid #666666;">Delete wine with id == 10</td>
</tr>
</table>
<p>&nbsp;</p>
<h4>Implementing the API using JAX-RS</h4>
<p>JAX-RS makes it easy to implement this API in Java. You simply create a class defined as follows:</p>
<pre class="brush: java; title: ; notranslate">
package org.coenraets.cellar;

@Path(&quot;/wines&quot;)
public class WineResource {

	WineDAO dao = new WineDAO();

	@GET
	@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	public List&lt;Wine&gt; findAll() {
		return dao.findAll();
	}

	@GET @Path(&quot;search/{query}&quot;)
	@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	public List&lt;Wine&gt; findByName(@PathParam(&quot;query&quot;) String query) {
		return dao.findByName(query);
	}

	@GET @Path(&quot;{id}&quot;)
	@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	public Wine findById(@PathParam(&quot;id&quot;) String id) {
		return dao.findById(Integer.parseInt(id));
	}

	@POST
	@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
	@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	public Wine create(Wine wine) {
		return dao.create(wine);
	}

	@PUT @Path(&quot;{id}&quot;)
	@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
	@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	public Wine update(Wine wine) {
		return dao.update(wine);
	}

	@DELETE @Path(&quot;{id}&quot;)
	@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	public void remove(@PathParam(&quot;id&quot;) int id) {
		dao.remove(id);
	}
}
</pre>
<p>Quick look at the JAX-RS annotations used in this class:</p>
<ul>
<li><strong>@GET</strong>, <strong>@POST</strong>, <strong>@PUT</strong>, <strong>@DELETE</strong>: HTTP method the class method responds to.</li>
<li><strong>@Path</strong>: path the method responds to.</li>
<li><strong>@Consumes</strong>: type of data the method can take as input. The data will automatically be deserialized into a method input parameter. For example, you can pass a wine object to the addWined() method either as JSON or XML. The JSON or XML representation of a new wine is automatically deserialized into the Wine object passed as an argument to the method.</li>
<li><strong>@Produces</strong>: One or more response content type(s) the method can generate. The method&#8217;s return value will be automatically serialized using the content type requested by the client. If the client didn&#8217;t request a specific content type, the first content type listed in the @Produces annotation will be used. For example, if you access http://coenraets.org/rest/wines, you get a list of wines represented as JSON because it is the first content type listed in the @Produces annotation of the findAll() method.</li>
</ul>
<p>The jQuery client below sends data to the server using JSON (addWine() and updateWine() methods).</p>
<p>The approach you use to actually retrieve the data is totally up to you. In this example, I use a simple DAO, but you can of course use your own data access solution.</p>
<h4>Testing the API using cURL</h4>
<p>If you want to test your API before using it in a client application, you can invoke your REST services straight from a browser address bar. For example, you could try:</p>
<ul>
<li><a href="http://localhost:8080/cellar/rest/wines">http://localhost:8080/cellar/rest/wines</a></li>
<li><a href="http://localhost:8080/cellar/rest/wines/search/Chateau">http://localhost:8080/cellar/rest/wines/search/Chateau</a></li>
<li><a href="http://localhost:8080/cellar/rest/wines/5">http://localhost:8080/cellar/rest/wines/5</a></li>
</ul>
<p>You will only be able to test your GET services that way, and even then, it doesn&#8217;t give you full control to test all the content types your API can return.</p>
<p>A more versatile solution to test RESTful services is to use <a href="http://curl.haxx.se/">cURL</a>, a command line utility for transferring data with URL syntax.</p>
<p>For example, using cURL, you can test the Wine Cellar API with the following commands:</p>
<ul>
<li>Get all wines returned as default content type:
<pre class="brush: bash; gutter: false; title: ; wrap-lines: true; notranslate">
curl -i -X GET http://localhost:8080/cellar/rest/wines
</pre>
</li>
<li>Get all wines returned as xml:
<pre class="brush: bash; gutter: false; title: ; wrap-lines: true; notranslate">
curl -i -X GET http://localhost:8080/cellar/rest/wines -H 'Accept:application/xml'
</pre>
<li>Get all wines with &#8216;chateau&#8217; in their name:
<pre class="brush: bash; gutter: false; title: ; wrap-lines: true; notranslate">
curl -i -X GET http://localhost:8080/cellar/rest/wines/search/chateau
</pre>
</li>
<li>Get wine #5:
<pre class="brush: bash; gutter: false; title: ; wrap-lines: true; notranslate">
curl -i -X GET http://localhost:8080/cellar/rest/wines/5
</pre>
</li>
<li>Delete wine #5:
<pre class="brush: bash; gutter: false; title: ; wrap-lines: true; notranslate">
curl -i -X DELETE http://localhost:8080/cellar/rest/wines/5
</pre>
</li>
<li>Add a new wine:
<pre class="brush: bash; gutter: false; title: ; wrap-lines: true; notranslate">
curl -i -X POST -H 'Content-Type: application/json' -d '{&quot;name&quot;: &quot;New Wine&quot;, &quot;year&quot;: &quot;2009&quot;}' http://localhost:8080/cellar/rest/wines
</pre>
</li>
<li>Modify wine #27:
<pre class="brush: bash; gutter: false; title: ; wrap-lines: true; notranslate">
curl -i -X PUT -H 'Content-Type: application/json' -d '{&quot;id&quot;: &quot;27&quot;, &quot;name&quot;: &quot;New Wine&quot;, &quot;year&quot;: &quot;2010&quot;}' http://localhost:8080/cellar/rest/wines/27
</pre>
</li>
</ul>
<h4>The jQuery Client</h4>
<p>Accessing your API through cURL is cool, but there is nothing like a real application to put your API to the test. So the source code (available for download at the end of this post) includes a simple jQuery client to manage your wine cellar.</p>
<p>Here is the jQuery code involved in calling the services:</p>
<pre class="brush: jscript; title: ; notranslate">
function findAll() {
	$.ajax({
		type: 'GET',
		url: rootURL,
		dataType: &quot;json&quot;, // data type of response
		success: renderList
	});
}

function findByName(searchKey) {
	$.ajax({
		type: 'GET',
		url: rootURL + '/search/' + searchKey,
		dataType: &quot;json&quot;,
		success: renderList
	});
}

function findById(id) {
	$.ajax({
		type: 'GET',
		url: rootURL + '/' + id,
		dataType: &quot;json&quot;,
		success: function(data){
			$('#btnDelete').show();
			renderDetails(data);
		}
	});
}

function addWine() {
	console.log('addWine');
	$.ajax({
		type: 'POST',
		contentType: 'application/json',
		url: rootURL,
		dataType: &quot;json&quot;,
		data: formToJSON(),
		success: function(data, textStatus, jqXHR){
			alert('Wine created successfully');
			$('#btnDelete').show();
			$('#wineId').val(data.id);
		},
		error: function(jqXHR, textStatus, errorThrown){
			alert('addWine error: ' + textStatus);
		}
	});
}

function updateWine() {
	$.ajax({
		type: 'PUT',
		contentType: 'application/json',
		url: rootURL + '/' + $('#wineId').val(),
		dataType: &quot;json&quot;,
		data: formToJSON(),
		success: function(data, textStatus, jqXHR){
			alert('Wine updated successfully');
		},
		error: function(jqXHR, textStatus, errorThrown){
			alert('updateWine error: ' + textStatus);
		}
	});
}

function deleteWine() {
	console.log('deleteWine');
	$.ajax({
		type: 'DELETE',
		url: rootURL + '/' + $('#wineId').val(),
		success: function(data, textStatus, jqXHR){
			alert('Wine deleted successfully');
		},
		error: function(jqXHR, textStatus, errorThrown){
			alert('deleteWine error');
		}
	});
}

// Helper function to serialize all the form fields into a JSON string
function formToJSON() {
	return JSON.stringify({
		&quot;id&quot;: $('#id').val(),
		&quot;name&quot;: $('#name').val(),
		&quot;grapes&quot;: $('#grapes').val(),
		&quot;country&quot;: $('#country').val(),
		&quot;region&quot;: $('#region').val(),
		&quot;year&quot;: $('#year').val(),
		&quot;description&quot;: $('#description').val()
		});
}

</pre>
<p>&nbsp;</p>
<h4>Download the Source Code</h4>
<p>The source code for this application is hosted on GitHub <a href="https://github.com/ccoenraets/wine-cellar-java">here</a>. And <a href="https://github.com/ccoenraets/wine-cellar-java/zipball/master">here</a> is a quick link to the project download (Eclipse Dynamic Web Project). It includes both the Java and jQuery code for the application.</p>
<p><strong>UPDATE (1/11/2012):</strong> A version of this application using Backbone.js at the client-side is also available on GitHub <a href="https://github.com/ccoenraets/backbone-jax-cellar">here</a>. You can find more information on the Backbone.js of this application <a href="http://coenraets.org/blog/2012/01/using-backbone-js-with-a-restful-java-back-end/">here</a>.</p>
<p>I&#8217;m interested in your feedback. Let me know what you think and what your experience has been building RESTful-based applications using Java and jQuery.</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2011/12/restful-services-with-jquery-and-java-using-jax-rs-and-jersey/feed/</wfw:commentRss>
		<slash:comments>56</slash:comments>
		</item>
		<item>
		<title>Building RESTful Services with Java Using JAX-RS and Jersey &#8212; Sample Application</title>
		<link>http://coenraets.org/blog/2011/11/building-restful-services-with-java-using-jax-rs-and-jersey-sample-application/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=building-restful-services-with-java-using-jax-rs-and-jersey-sample-application</link>
		<comments>http://coenraets.org/blog/2011/11/building-restful-services-with-java-using-jax-rs-and-jersey-sample-application/#comments</comments>
		<pubDate>Mon, 07 Nov 2011 16:32:57 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JAX-RS]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=2019</guid>
		<description><![CDATA[I&#8217;m working on a project that required a RESTful API implemented in Java. Jersey, the reference implementation for JAX-RS, made it easy to implement and deploy these services. I figured I’d share my sample application here. Configuring Tomcat (or your own app server) There are many options to initialize Jersey in your servlet container. Some [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;m working on a project that required a RESTful API implemented in Java. <a href="http://jersey.java.net/">Jersey</a>, the reference implementation for JAX-RS, made it easy to implement and deploy these services. I figured I’d share my sample application here.<br />
<span id="more-2019"></span></p>
<h4>Configuring Tomcat (or your own app server)</h4>
<p>There are many options to initialize Jersey in your servlet container. Some of them require no XML configuration at all. For my application, I simply configured the Jersey Servlet in web.xml as follows:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;servlet&gt;
	&lt;servlet-name&gt;Jersey&lt;/servlet-name&gt;
	&lt;servlet-class&gt;com.sun.jersey.spi.container.servlet.ServletContainer&lt;/servlet-class&gt;
	&lt;init-param&gt;
		&lt;param-name&gt;com.sun.jersey.config.property.packages&lt;/param-name&gt;
		&lt;param-value&gt;org.coenraets&lt;/param-value&gt;
	&lt;/init-param&gt;
	&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
&lt;/servlet&gt;

&lt;servlet-mapping&gt;
	&lt;servlet-name&gt;Jersey&lt;/servlet-name&gt;
	&lt;url-pattern&gt;/rest/*&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
</pre>
<p>NOTE: Using this type of initialization, the packages parameter defines which classes Jersey will scan for URL Paths to resolve: in this case, all the classes in org.coenraets.* packages.</p>
<h4>Defining the REST API</h4>
<p>Before working on the implementation, I identified that my simple application would require three services:</p>
<ol>
<li>Find all employees</li>
<li>Find an employee by id</li>
<li>Find a list of direct reports for a specific employee</li>
</ol>
<p>Based on these requirements, I came up with the following REST API:</p>
<ol>
<li>
<strong>/api/employees</strong><br/>Returns all employees
</li>
<li>
<strong>/api/employees/1</strong><br/>Returns an employee identified by id (employee 1 in this case)
</li>
<li>
<strong>/api/employees/1/reports</strong><br/>Returns direct reports of an employee (employee 1 in this case)
</li>
</ol>
<h4>Implementing the API</h4>
<p>Once my API was defined, providing the implementation using JAX-RS was easy. I just created a Java class defined as follows:</p>
<pre class="brush: java; title: ; notranslate">
package org.coenraets.directory;

import java.util.List;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path(&quot;/employees&quot;)
public class EmployeeResource {

	EmployeeDAO dao = new EmployeeDAO();

	@GET
	@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	public List&lt;Employee&gt; findAll() {
		return dao.findAll();
	}

	@GET @Path(&quot;{id}&quot;)
	@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	public Employee findById(@PathParam(&quot;id&quot;) String id) {
		return dao.findById(Integer.parseInt(id));
	}

	@GET @Path(&quot;{id}/reports&quot;)
	@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	public List&lt;Employee&gt; findByManager(@PathParam(&quot;id&quot;) String managerId) {
		return dao.findByManager(Integer.parseInt(managerId));
	}
}
</pre>
<p>You annotate your class and methods with the path (@Path) and the content type (@Produces) they respond to. The  serialization from model objects to the content type requested by the client happens automatically. In this application, the methods will return either JSON or XML depending on the content type requested by the client.</p>
<p>The approach you use to actually retrieve the data is, of course, totally up to you. In this example, I use a simple DAO, but you can of course use your own data access solution.</p>
<p>This application only required GET methods, but JAX-RS allows you to handle the other HTTP methods (@GET, @PUT, @POST, @DELETE and @HEAD).</p>
<p>Note that the package name matches the packages parameter defined in web.xml.</p>
<h4>Testing the API</h4>
<p>If you want to test your API before using it in a client application, you can invoke your REST services straight from a browser address bar.  For example, try:</p>
<p><a href="http://coenraets.org/rest/employees">http://coenraets.org/rest/employees</a><br />
<a href="http://coenraets.org/rest/employees/1">http://coenraets.org/rest/employees//1</a><br />
<a href="http://coenraets.org/rest/employees/1/reports">http://coenraets.org/rest/employees/1/reports</a></p>
<p>However, that doesn’t give you full control to test all the content types your API can return. A common option to test the different content types supported by your API is to use <a href="http://curl.haxx.se/">cURL</a> and specify the content type requested in the Accept header:</p>
<p>curl -I http://coenraets.org/rest/employees -H&#8217;Accept:application/json&#8217;</p>
<h4>Download the Source Code</h4>
<p>Click <a href="http://coenraets.org/apps/directory/EmployeeDirectoryJAXRS.zip">here</a> to download the source code (Eclipse Dynamic Web Project).</p>
<p>In my next post, I&#8217;ll share the client-side of the application: how to invoke these services using jQuery (and JSON).</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2011/11/building-restful-services-with-java-using-jax-rs-and-jersey-sample-application/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>
