The class-based approach gave very little practical reuse, and it was not granular enough to allow us to easily add validation rules or customize the fields to return from a model. Lots of ugly code where you had to concern yourself with response codes.. I mean whats the point with a framework if you have to concern yourself with response codes? Isn't it the frameworks role to abstract away these details?
Most of my beef with the framework has to do with the design. It has abstraction in all the wrong places ... Inversion of Control (IoC) just seem like a complete afterthought in the entire design.
Now with Tastypie, I will admit it has a steep learning curve, and a conceptual overhead, but it does a much better job of abstracting away the internals and you end up with a much more correct and consistent REST implementation. In addition, it is better architected which makes it easier to extract base classes and override behavior, which is valuable if you need it to work really well with non DB models.
I will say that deep down I'm not really happy with either alternatives though. Tastypie requires too much code to get up and running and it takes too much time to get confident with it. Will def. take a look at the other frameworks mentioned in this discussion.
The initial version made some design compromises in order to support the Browseable API, and didn't take full advantage of Django's generic CBV's. (Since it was released when Django was still at 1.2) REST framework 2 fixes all that and much, much more.
I'd throughly recommend spending a while walking through the tutorial and taking a browse around the docs - I think you'll be pleasantly surprised.
We are using TastyPie in production on a pretty large site and I've been super happy with it. We have custom fields, custom auth, custom base classes for resources where the underlying data store are non django models, security is very granular (with minimal code overhead) and overall its been a blessing to extend and override. One thing I like in particular is how you can reuse nested Resource definitions, e.g. define a UserResource once and reuse it everywhere a model/resource has a FK to user and you get correct response output. Saves lots of time and gets you a correct, secure implementation.
I have cleaned up a lot of our Tasty-Pie backend and reduced query volume on endpoints which were 100+ queries down to be just 2 or 3 queries- but it was a tremendous amount of work with an ugly result from a complexity and architectural perspective.
I haven't found any Python-based API-in-a-box which I like.
OTOH, I've had much success with Scala + Play-framework + Squeryl - this combination gives fine grained explicit control over what is happening. This approach is generally very easy to scale. However this setup has it's own shortcomings- its always a tradeoff, right?
With Scala + Play, you don't get an API-in-a-box, so you must build it out yourself. It isn't particularly hard, but it definitely doesn't come "for free".
"for free", like TP- but it's only free at first because you will have to do complex and ugly hacks to make it scale.
We've ended up with stuff like:
class Meta(SomeResource.Meta):
cls = Challenge
select_related_fields = [
'category', 'owner', 'company', 'bonus', 'reward',
]
prefetch_related_fields = [
'specialities', 'countries',
'companies', 'products',
'groups',
]
queryset = (cls.objects
.select_related(*select_related_fields)
.prefetch_related(*prefetch_related_fields)
.all())
which takes some of the pain away, but going through and profiling exactly which prefetches & joins help is a major hassle.Resources with relations with full=True are also brutal. Manually stuffing only the required extra data speeds things up greatly, but there's too much boilerplate for my liking. Having some level in-between 'full' and 'resource-uri only' would be nice, but I haven't seen any nice way to do it.