30 Apr 2009
As I mentioned in a previous post I have
been working of a library to ease the creation of map/reduce views in
CouchDB.
The code is being hosted on google code and can be checked out and used
now. The development is currently at a very early stage, but the fundamentals are sound.
Code such that given below will work. In this example it will return all the documents with a member ‘x’ whoes
value is greater than one.
Read More...
23 Apr 2009
In the first
part I talked
about using the Content-Type
and Accept
HTTP headers to allow a single website to be use both by humans
and programs.n In the previous part I gave a decorator which can be used to make working with JSON very easy.
For our use though this isn’t great because a view decorated in this way only accepts JSON as the POST body
and only returns JSON, regardless of the HTTP headers.
The decorator given below relies on a django snippet to decode
the Accept
header for us so don’t forget to added it to your middleware.
def content_type(func, common=None, json_in=None, json_out=None, form_in=None):
def wrapper(req, *args, **kwargs):
# run the common function, if we have one
if common is not None:
args, kwargs = common(req, *args, *kwargs), {}
if isinstance(args, HttpResponse): return args
content_type = req.META.get("content_type", "")
if content_type == "application/json":
args, kwargs = json_in(req, json.loads(req.raw_post_data), *args, *kwargs), {}
elif content_type == "application/x-www-form-urlencoded":
args, kwargs = json_in(req, req.POST, *args, *kwargs), {}
else:
return HttpResponse(status=415, "Unsupported Media Type")
if isinstance(args, HttpResponse): return args
for (media_type, q_value) in req.accepted_types:
if media_type == "text/html":
return func(req, args, kwargs)
else:
r = json_out(req, args, kwargs)
if isinstance(r, HttpResponse):
return r
else:
return HttpResponse(json.dumps(r), mimetype="application/json")
return func(req, args, kwargs)
return wrapper
Read More...
16 Apr 2009
CouchDB is a very exciting development in the world of databases and I’m greatly
enjoying building a website which uses it. One problem is that most of the of views that I have created are
extremely simple and could easily be represented using SQL. Although I wrote some
code to help make life
easier, creating a view such as that below is never going to be as simple as including SELECT * FROM table
WHERE (status="open" OR status="accepted") AND latest AND key="xyz"
directly in your code.
function (doc) {
if((doc["status"] == "open" || doc["status"] == "accepted") && doc["latest"]) {
emit(doc["key"], null);
}
}
The SQL above and the Javascript view function are directly equivalent, which is why I’ve started working on
an extension to the Python CouchDB library, which I’ve decided to
call CouchQL.
Read More...
08 Apr 2009
Building a RESTful webservice is pretty straight-forward with Django, but in many cases you want to have both
a human readable website and a machine readable api. A lot of websites solve this problem by using www.x.com
as the human site, an api.x.com as the machine site. They also will typically have different structures to
support the different usecases.n Unless your documentation is really excellent and the person writing the
client to your service actually reads it building a client for the service is an error prone process. In an
ideal world the developer would be able to browse the website and use the same urls in their client program.
Fortunately HTTP has two headers which make it possible to do just that, Content-Type
and Accept
.
The Content-Type
header describes the type of data that is included in the body of the HTTP request.
Typically this will be values such as text/html
, application/json
or application/x-www-form-urlencoded
.
A content type is sent by the client when POSTing or PUTing data, and whenever the webserver includes some
data in its response. The Accept
header is sent by a client to specify what content types it can accept in
the response. This header has a more complicated format that Content-Type
because it can used to specify a
number of different content types and to give a weighting to each.
When combined these two headers can be used to allow a normal user to browse the site and to allow a robot to
make api calls on the same site, using the same urls. This makes it easier both for the creator of the
programmer accessing your site and for you because you can easily share code between the site and your api.
Read More...
02 Apr 2009
ID Software have taken time out from letting you play Quake 3 in your browser to
release a port of the granddaddy of all first person shooters - Wolfenstein
3d. The iPhone is really beginning to show itself as an
excellent gaming platform, and despite its age Wolfenstein really looks at home on the phone.
The graphics are, quite frankly, rubbish. However, they’re exactly as they were when the game was released in
1992 which is exactly the point. The sound has faired much better and sounds great. The voices of the German
soldiers still send shivers up your spine. It’s an extremely faithful port of the game, and the addition of an
automatic save feature means it really works as a pick up and play game. It’s very easy to dip in and out of
taking one level at a time.
The controls have naturally been revamped for the iPhone’s unique control system. You steer by moving your
left finger over up/down/left/right arrows and fire by tapping your right finger on a button. This works
really well and it is very easy to pick up and to start running around the Nazi prison that you find yourself
in. The controls do rather feel like driving a fork lift truck. You regularly find your self reversing
backwards around a corner, which is not how a person would move, but it’s easy to forgive and hard to see how
else it could be done.
Read More...