Couchdb and PHP Web Development Beginner'S Guide: Chapter No. 3 "Getting Started With Couchdb and Futon"
Couchdb and PHP Web Development Beginner'S Guide: Chapter No. 3 "Getting Started With Couchdb and Futon"
Couchdb and PHP Web Development Beginner'S Guide: Chapter No. 3 "Getting Started With Couchdb and Futon"
Tim Juravich
I would like to thank my loving parents, my older (but smaller) brother Jon, and my wife Leigha. Without Leigha's support and love through our first year of marriage, this book, and much more, would not have been possible. I would also like to thank my clients and colleagues who have provided invaluable opportunities for me to shape my career, my life, and my perspective on technology.
Bonus Chapter, Replicating your Data, finds out how to use CouchDB's replication system to scale your application as it grows. You can download the Bonus Chapter from .
Specically, we will:
Dive into what CouchDB means and learn how it looks in the databases and documents Learn how we'll interact with CouchDB through its RESTful JSON API Use CouchDB's built in administrative console: Futon Learn how to add security to your CouchDB databases
What is CouchDB?
The rst sentence of CouchDB's denition (as dened by http://couchdb.apache.org/) is as follows: CouchDB is a document database server, accessible through the RESTful JSON API. Let's dissect this sentence to fully understand what it means. Let's start with the term database server.
Database server
CouchDB employs a document-oriented database management system that serves a at collection of documents with no schema, grouping, or hierarchy. This is a concept that NoSQL has introduced, and is a big departure from relational databases (such as MySQL), where you would expect to see tables, relationships, and foreign keys. Every developer has experienced a project where they have had to force a relational database schema into a project that really didn't require the rigidity of tables and complex relationships. This is where CouchDB does things dierently; it stores all of the data in a self-contained object with no set schema. The following diagram will help to illustrate this:
In the previous example, we might want to facilitate the ability for many users to belong to one-to-many groups. In order to handle this functionality in a relational database (such as MySQL), we would create a users table, a groups table, and a link table, called users_groups, that allow you to map many users to many groups. This practice is common to most web applications. Now look at the CouchDB documents. There are no tables or link tables, just documents. These documents contain all of the data pertaining to a single object.
This diagram is very simplied. If we wanted to create more logic around the groups in CouchDB, we would have had to create group documents, with a simple relationship between the user documents and group documents. We'll touch on how to handle this type of relationship as we get deeper into the book.
[ 34 ]
Chapter 3
We saw the term document quite a bit in this section. So let's dig further into what documents are and how CouchDB uses them.
Documents
To illustrate how you might use documents, rst imagine that you are physically lling out the paper form of a job application. This form has information about you, your address, and past addresses. It also has information about many of your past jobs, education, certications, and much more. A document would save all of this data exactly in the way you would see it in the physical form - all in one place, without any unnecessary complexity. In CouchDB, documents are stored as JSON objects that contain key and value pairs. Each document has reserved elds for metadata such as id, revision, and deleted. Besides the reserved elds, documents are 100 percent schema-less, meaning that each document can be formatted and treated independently with as many dierent variations as you might need.
Downloading the example code You can download the example code les for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub. com/support and register to have the les e-mailed directly to you.
JSON format
The rst thing you might notice is the strange markup of the document, which is JavaScript Object Notation (JSON). JSON is a lightweight data-interchange format based on JavaScript syntax and is extremely portable. CouchDB uses JSON for all communication with it, so you'll get very familiar with it through the course of this book.
[ 35 ]
Key-value storage
The next thing that you might notice is that there is a lot of information in this document. There are key-value pairs that are simple to understand, such as "title", "author", and "body", but you'll also notice that "tags" is an array of strings. CouchDB lets you embed as much information as you want directly into a document. This is a concept that might be new to relational database users who are used to normalized and structured databases.
Reserved elds
We mentioned reserved elds earlier on. Let's look at the two reserved elds that you saw in the previous example document: _id and _rev.
_id is the unique identier of the document. This means that _id is mandatory, and no two documents can have the same value. If you don't dene an _id on creation of a document, CouchDB will choose a unique one for you. _rev is the revision version of the document and is the eld that helps drive CouchDB's
version control system. Each time you save a document, the revision number is required so that CouchDB knows which version of the document is the newest. This is required because CouchDB does not use a locking mechanism, meaning that if two people are updating a document at the same time, then the rst one to save his/her changes rst, wins. One of the unique things about CouchDB's revision system is that each time a document is saved, the original document is not overwritten, and a new document is created with the new data, while CouchDB stores a backup of the previous documents in its original form in an archive. Old revisions remain available until the database is compacted, or some cleanup action occurs. The last piece of the denition sentence is the RESTful JSON API. So, let's cover that next.
[ 36 ]
Chapter 3
That might not mean a lot in itself, but, by putting all of these ideas together, it becomes a powerful concept. Let's illustrate the power of REST by looking at two examples:
Resource http://localhost/ collection GET PUT POST DELETE
Read a list
of all of the items inside of collection
Update the
collection with another collection
Create a new
collection
http://localhost/ collection/abc123
Read the
details of the abc123 item inside of collection
Update
the details of abc123 inside of collection
Create a
new object abc123 inside of a collection
Delete
abc123 from collection
By looking at the table, you can see that each resource is in the form of a URL. The rst resource is collection, and the second resource is abc123, which lives inside of collection. Each of these resources responds dierently when you pass dierent methods to them. This is the beauty of REST and HTTP working together. Notice the bold words I used in the table: Read, Update, Create, and Delete. These words are actually, in themselves, another concept, and it, of course, has its own term; CRUD. The unattering term CRUD stands for Create, Read, Update, and Delete and is a concept that REST uses to dene what happens to a dened resource when an HTTP method is combined with a resource in the form of a URL. So, if you were to boil all of this down, you would come to the following diagram:
In order to CREATE a resource, you can use either the POST or PUT method In order READ a resource, you need to use the GET method In order to UPDATE a resource, you need to use the PUT method In order to DELETE a resource, you need to use the DELETE method
[ 37 ]
As you can see, this concept of CRUD makes it really clear to nd out what method you need to use when you want to perform a specic action. Now that we've looked at what REST means, let's move onto the term API, which means Application Programming Interface. While there are a lot of dierent use cases and concepts of APIs, an API is what we'll use to programmatically interact with CouchDB. Now that we have dened all of the terms, the RESTful JSON API could be dened as follows: we have the ability to interact with CouchDB by issuing an HTTP request to the CouchDB API with a dened resource, HTTP method, and any additional data. Combining all of these things means that we are using REST. After CouchDB processes our REST request, it will return with a JSON-formatted response with the result of the request. All of this background knowledge will start to make sense as we play with CouchDB's RESTful JSON API, by going through each of the HTTP methods, one at a time. We will use curl (which we learned to use in the previous chapter) to explore each of the HTTP methods by issuing raw HTTP requests.
1. 2.
[ 38 ]
Chapter 3
1. 2. 3.
Try creating another database with the same name by running the following command in Terminal:
curl -X PUT http://localhost:5984/test-db
4.
5.
Okay, that didn't work. So let's to try to create a database with a dierent name by running the following command in Terminal:
curl -X PUT http://localhost:5984/another-db
6. 7.
Let's check the details of the test-db database quickly and see more detailed information about it. To do that, run the following command in Terminal:
curl -X GET http://localhost:5984/test-db
8.
Terminal will respond with something similar to this (I re-formatted mine for readability):
{ "committed_update_seq": 1, "compact_running": false, "db_name": "test-db", "disk_format_version": 5, "disk_size": 4182, "doc_count": 0, "doc_del_count": 0,
[ 39 ]
Getting Started with CouchDB and Futon "instance_start_time": "1308863484343052", "purge_seq": 0, "update_seq": 1 }
1. 2.
Chapter 3
1.
Create a document in the test-db database by running the following command in Terminal:
curl -X POST -H "Content-Type:application/json" -d '{"type": "customer", "name":"Tim Juravich", "location":"Seattle, WA"}' http://localhost:5984/test-db
2.
3.
Let's retrieve the newly created document from CouchDB. Start by copying the ID you were returned at the last response of the Terminal to your clipboard; mine is 39b1fe3cdcc7e7006694df91fb002082, but yours will be dierent. Then run this command in Terminal, pasting your ID at the end of the URL:
curl -X GET http://localhost:5984/test-db/41198fc6e20d867525a8faeb 7a000015 | python -mjson.tool
4.
[ 41 ]
After creating our document, we retrieved it to Terminal by submitting a GET request to http://localhost:5984/test-db/41198fc6e20d867525a8faeb7a000015. In response, we received a JSON object containing all of the document's data. At the end of this request, we did something a little dierent. We added python mjson.tool, which is a built-in component from Python that enables us to nicely format our JSON responses, so that we can make more sense of them. This will come in handy as we start looking at more complex documents.
I didn't mention that you needed Python installed earlier in the book because this is a nice to have feature. If you receive an error because you are missing Python, you can either install it by going here: http://python.org/download/.
I know that this has been a bit tiresome, but curl will be the main method that our PHP code will use to talk to CouchDB, so it's important that we're familiar with how it works. Luckily, there is an easier way to access and manage your data through a tool named Futon.
Futon
CouchDB comes with a built-in web-based administration console called Futon. Futon allows you to manage databases, users, and documents in a simple interface. The best part of Futon is that it's already installed and ready to go, since it comes packed with CouchDB. Let's check it out:
1. 2.
[ 42 ]
Chapter 3
This is Futon's Overview page. On this page, you can see all of the databases in the CouchDB installation and the ability to create new ones. You should see the database test-db that we created in the previous steps, and you can also see the _users database that is in the CouchDB installation by default. If you look to the right-side of the window, you'll see Tools. We will use this when we cover Replicator later in the book.
3.
Let's dig further into our database test-db by clicking on the link for test-db in the database list on the Overview page.
The page you see is the database detail. In this page, you can see a list of all of the documents that are in our database along with some actions that you can perform on the selected database such as New Document, Security, Compact & Cleanup, Delete Database, Search, and so on. It's worth noting that Futon is just a helper, and all of these functions are available through curl as well.
[ 43 ]
4.
Let's dig deeper into Futon by clicking on on a document, and you'll be forwarded to the document detail.
This data should look familiar! All of our keys are listed on the left, and the values are listed on the right.
1. 2. 3. 4. 5.
Make sure you have the document open in your browser. Note the value of _rev in your document. Double-click the value of the location eld: Seattle, WA, and change it to New York, NY. Click on Save Document at the top of the page. Check to make sure that the value of _rev in your document has changed, and that New York, NY is now the value of location.
[ 44 ]
Chapter 3
1. 2. 3. 4. 5. 6. 7.
Go to the database overview by clicking on the database name, test-db, in the header. Click on New Document. A blank document is created and ready for us to put in new elds. Notice that the _id is already set for us (but we can change it if we want). Click on Add Field to create a new eld, and call it location. Double-click on the value right next to the label that says null, and enter in your current location. Click on Add Field to create a new eld, and call it name. Double-click on the value right next to the label that says null, and enter in your name.
[ 45 ]
8. 9.
Click on Save Document at the top of the page. The document has been saved. Notice that it now has a _rev value set.
Security
Up to this point, we've created, read, updated, and deleted documents and databases, and we've done all of this without any type of security. When you don't have any administrators on your CouchDB instance, it's called Admin Party, and that simply means that CouchDB will process any request from anybody for anything.
1.
Open Futon to the Overview, and look at the bottom right corner. You'll see text that says:
Welcome to Admin Party! Everyone is admin. Fix this.
2. 3.
Click on the Fix this link. A new window will pop up, prompting you Create Server Admin.
[ 46 ]
Chapter 3
4.
Enter in a username and password that you want to use for your administrator account, and click on Create.
1. 2.
Open Terminal. Run the following command, replacing your_username with the username of the server admin that you just created.
curl localhost:5984/_users/org.couchdb.user:your_username | python -mjson.tool [ 47 ]
3.
1. 2. 3.
Open Futon to the Overview. Click on the _users database. Click on Security at the top of the screen.
[ 48 ]
Chapter 3
4.
Change the values of Roles for both Admins and Readers to ["admins"], so it looks as follows:
[ 49 ]
1. 2.
Open Terminal. Try to read the user document again by running the following command. Again, replace your_username with the username of the service admin that you just created:
curl localhost:5984/_users/org.couchdb.user:your_username
3.
If you were to play around with the command line again, you would be restricted by doing anything with the _users database, but you would also notice that the test-db database is operating just as it was before, perfect! That's exactly what we wanted. You might be asking how do I access the _users database through the command line, now that security is enabled? You have to show that you are an admin by passing your credentials to the RESTful JSON API.
[ 50 ]
Chapter 3
1. 2.
Open Terminal. View all of the documents saved in the _users database by running the following command. Replace username and password with your admin's username and password.
curl username:password@localhost:5984/_users/_all_docs
3.
Terminal will respond with the same data that you saw before you added the authentication.
{ "_id": "org.couchdb.user:your_username", "_rev": "1-b9af54a7cdc392c2c298591f0dcd81f3", "name": "your_username", "password_sha": "3bc7d6d86da6lfed6d4d82e1e4d1c3ca587aecc8", "roles": [], "salt": "9812acc4866acdec35c903f0cc072c1d", "type": "user" }
[ 51 ]
Pop quiz
1. What is the rst sentence of CouchDB's denition according to http://couchdb.apache.org/? 2. What are the four verbs used by HTTP, and how does each match up to CRUD? 3. What is the URL to access Futon? 4. What does the term Admin Party mean to CouchDB, and how do you take CouchDB out of this mode? 5. How would you authenticate a user for a secure database through the command line?
Summary
We learned a lot about CouchDB in this chapter. Let's quickly review:
We dened CouchDB by looking at databases, documents, and the RESTful JSON API We compared CouchDB to a traditional relational database such as MySQL We interacted with CouchDB's RESTful JSON API, using curl statements We created and altered documents by using Futon We learned how to add security to a database and tested its eectiveness
Get ready! In the next chapter, we are going to start building the PHP framework that will be the platform on which we will develop in the rest of the book.
[ 52 ]
Alternatively, you can buy the book from Amazon, BN.com, Computer Manuals and most internet book retailers.
www.PacktPub.com