Martijn Faassen defends web
frameworks in a rather longish post (you can tell it's 5 AM in the
morning and I've nearly defeated the unread post queue in Google
Reader). I'd like to propose a condensed
version. Consider this slogan:
Simple things should be easy; complicated things should be possible.
Frameworks make simple things easy. Good frameworks
keep the complicated thing possible; poorly-designed frameworks make the
complicated thing more difficult than necessary; bad frameworks make even
simple things complicated.
Doing everything from scratch merely makes things possible, but rarely
easy.
Disclaimer: I received a free review copy of this book. The book links are
affiliate links; I get a small amount from any purchase you make through them.
Grok is a Python web framework, built on
top of the Zope Toolkit, which is the core of what used to be called Zope 3 and
is now rebranded as BlueBream. Confused yet? Get used to it: the small
pluggable components are the heart and soul of ZTK, and the source of its
flexibility. It's not surprising that people take the same approach on a larger
scale: take Zope 3 apart into smaller packages and reassemble them into
different frameworks such as Grok, BlueBream or repoze.bfg.
The Grok
book by Carlos de la Guardia introduces the framework by demonstrating
how to create a small but realistic To-do list manager. I like this technique,
and it works pretty well. The author covers many topics:
- creation of a new project
- simple views with Zope Page Templates
- automatic form generation from schemas (with tweaks)
- catalogs and indexes (my favourite chapter)
- security: users, roles, permissions; authentication and authorization
- extremely pluggable page layouts with viewlets and pagelets
- basic ZODB, blobs, ZEO, database packing, backups with repozo
- SQL databases, integration with SQLAlchemy (including a common
transactional model)
- component architecture: adapters and utilities
- Martian: extending Grok by defining custom component directives
- very short intro to testing (zope.testing, unit tests and doctests,
functional tests with zope.testbrowsing) and debugging (pdb; AJAXy
debugger, which looks exactly like the Pylons one with an uglier skin)
- deployment (my second favourite chapter): paster, apache and mod_proxy,
mod_wsgi, pound, squid, varnish, scalable deployments.
Some important topics like internationalization, time zones, testing with
Selenium, and (especially) database migration (which is pretty specific for
ZODB) were not covered.
If you want to learn about Grok, this book will be useful,
but there's a caveat: there's the usual slew of typographical mistakes and
other errors I've come to expect from books published by Packt. It's their
third book I've seen; all three had surprisingly high numbers of errors. Some
had more, others had fewer. The Grok book was on the high side and the first
one where I was tempted to record a "WTFs per page" metric.
The mistakes are easy to notice and correct, so they didn't impede my
understanding of the book's content. Disclaimer: I've been working with
Zope 3 for the last six-or-so years, so I was pretty familiar with the
underlying technologies, just not the thin Grok convenience layer. If
minor errors annoy you, stay away. I haven't noticed any major
factual errors, although there were what I would consider some pretty important
omissions:
- ZODB is not as transparent as people tell you. There are many gotchas,
especially if you want to refactor your code without throwing away old
databases.
- bin/buildout is free to recursively remove anything under
parts. Keeping your database there is fine only if you don't mind
occasionally starting from scratch.
- repozo does not back up blobs.
- The ZODB transaction conflict resolution depends on being able to
repeat requests several times; this is important if your code has external
side effects (e.g. sends emails, creates files, pings 3rd party websites over
HTTP). Packages like megrok.rdb or zope.sendmail take care of this; it'd be
nice to be shown how to do that for your own code before you discover this
issue the hard way when your app starts charging people's credit cards three
times every now and then.
- You need to make sure you send out object events at appropriate times, or
your catalog indexes won't be updated.
- Permission and role grants are persistent: if you delete a user and then
create a new one with the same username, the new user will have all the roles
and permissions granted to the old one. If you implement user deletion, you
need to explicitly remove old grants.
- The Zope security model expects every object to have a valid
__parent__
attribute; permission/role grants will not work properly on objects without a
__parent__. Most of the time this is taken care of
automatically, but when it's not, you can get really confusing errors.
applySkin should only be used for browser requests; blindly
calling it from a traversal event handler can break WebDAV/XML-RPC.
(Incidentally, I should file a bug about that; it should abort if you pass a
non-browser request instead of silently converting it into a browser
request.)
- Allowing end-users to specify
++skin++ in the URL can be a
security hole.
Overall, Grok is pretty nice, especially compared to vanilla Zope 3.
However, when compared to frameworks like Pylons or Django, Grok appears more
complex and seemingly requires you to do additional work for unclear gain. For
example, chapter 8 has you writing three components for every new form you add:
one for the form itself, one for a pagelet wrapping the form, and one for a
page containing the pagelet. Most of that code is very similar with only the
names being different. I'm sure there are situations where this kind of
extreme componentization pays off (e.g. it lets you override particular bits on
particular pages to satisfy a particular client's requests, without affecting
any other clients), but the book doesn't convincingly demonstrate those
advantages. Again, I may be biased here since I've been enjoying those
advantages for the past six years, without ever having felt the pain of doing
similar customizations with a less flexible framework. (It's a gap in my
professional experience that I'm itching to fill.)
Update: some other
reviews
on Planet Python.
Update 2: Another
review (well, part 1 of one, but I got tired waiting for part 2).