Skip to content
ccarpenterg edited this page Mar 30, 2012 · 14 revisions

Backbone.js ![Tornado] (http://www.tornadoweb.org/static/tornado.png)

Previously I had created backends for the Backbone.js todos example using Google App Engine and Django. Now it's the time for Tornado Web Server. Tornado is not a web framework so I had to add the SQLAlchemy ORM to the stack.

The main task, again, was to develop the RESTful handler to support the Backbone.js JSON interface.

class RESTfulHandler(BaseHandler):
    def get(self, id):
        ...
    def post(self, id):
        ...
    def put(self, id):
        ...
    def delete(self, id):
        ...

I've used the same Backbone.js todos application. So I pointed the collection (TodoList) to the url /todos.

window.TodoList = Backbone.Collection.extend({

    // Reference to this collection's model.
    model: Todo,

    // Save all of the todo items under the `"todos"` namespace.
    //localStorage: new Store("todos"),

    url: '/todos',

Then I mapped the url to the RESTful handler:

class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
            (r"/", MainHandler),
            (r"/todos\/?([0-9]*)", RESTfulHandler),
        ]

The regular expression "/todos\/?([0-9]*)" match the Backbone.js RESTful interface HTTP methods and urls:

  • read -> GET /todos[/id]
  • create -> POST /todos
  • update -> PUT /todos/id
  • delete -> DELETE /todos/id

So now I'm using SQLAlchemy to save the todos and users into a Postgresql database. And the truth is that once you've worked with the Django ORM, SQLAlchemy feels very natural.

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    session = Column(String(32))
    created_on = Column(DateTime, default=datetime.now())
    todos = relationship("Todo", backref="users")

class Todo(Base):
    __tablename__ = 'todos'

    id = Column(Integer, primary_key=True)
    order = Column(Integer, primary_key=True)
    content = Column(String(256))
    done = Column(Boolean, default=False)
    user = Column(Integer, ForeignKey('users.id'))

A persistent cookie is set to emulate a user's session:

class MainHandler(BaseHandler):
    def get(self):
        if self.get_cookie('todos') is None:
            remote_ip = self.request.remote_ip
            user = User(remote_ip)
            self.db.add(user)
            self.db.commit()
            self.set_cookie('todos', user.session, expires=datetime(2020, 1, 1))
        self.render("index.html")

That was fun!

Clone this wiki locally