REST framework 2 released: Simple, beautiful, browsable Web APIs for Django
django-rest-framework.org
django-rest-framework.org
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.
It's built entirely on CBVs, so if you're familiar with them, you will feel right at home.
The API is not frozen, so it's not production ready yet.
So far used it in a couple of our projects, but would welcome feedback.
[0] too much ModelResource magic [1] custom model (de)serialization into multiple formats, browsable api is majority of the framework: IAGNI, and 80% functionality we needed was in 20% of DRF (which is basically what Restless is)
Compare to TastyPie where a functional API is built with very few lines of code and right near the top of the tutorial: http://django-tastypie.readthedocs.org/en/latest/tutorial.ht...
It starts with the amount of code you would usually write if you were to write an API by hand and then simplifies things along the road. At the end it makes it clear how the framework can be simple to use while you've learned how to use it behind the hood if the magic needs tweaking.
Sort of off-topic, but did Mr. Fielding mean to say either "inversely proportional to the complexity" or "proportional to the simplicity"? This quote implies that as effort increases, simplicity decreases, which seems out of spirit with the context of the quote.
He meant to say: "As effort increases, simplicity increases."
He instead said: "As effort increases, simplicity decreases."
So far the closet to happy I've been is with flask-restless - though I'm busy hacking around with that to get it working how I need (it's pretty feature light). It does mean I get to use SQL-Alchemy, which is every different kind of nice.
There's no doubt, designing a powerful and flexible api framework is a challenging job.
Will have a look at this now too, though. I'd definitely rather use something that has some development resource behind it instead of rolling my own.
Django-Piston
https://bitbucket.org/jespern/django-piston/wiki/Home
I have not used any other frameworks but will be trying ops suggestion.
There's also an outstanding pull req to build in support for django-filter and other filtering backends which now just needs some docs, and which I plan to have merged in within the next few days or so. https://github.com/tomchristie/django-rest-framework/pull/29... That'll make it easier to do more complex filtering stuff. (And eventually have the filters be presented in the Browsable API)
In case you want to provide an API to other users who aren't going to be making native Django calls.
In case your app is going to be based on Backbone (which maps models endpoints to REST endpoints, to oversimplify things.)
In case you need to consume your app from a mobile app, or external site, or whatever.
In case you want to surface your data in any way without having to give read/write access to the database directly -- you can implement REST and API Token authentication that maps to users so that they can read and write to the data that they have access to, but no more.
Could you give some pointers/links about how this is done?
I have used REST internally with no authentication. But I am not sure how these can be exposed to outside in a secure manner.
from tastypie.authorization import DjangoAuthorization
and then in your 'Meta' class for each resource, you'd specify the following: authorization = DjangoAuthorization()
That's step one. To go further, and limit access to resources per user, so that they can only access the things they should have access to (according to Django permissions), you'd simply use 'apply_authorization_limits' to narrow the query object to what the user should have access to. So, if your default query looks like queryset = Resource.objects.all()
You could filter that down in your apply_authorization_limits method to something like this: def apply_authorization_limits(self, request, object_list):
object_list.filter(user=request.user)Can I ask how you're determining whether or not the client is making an API call vs visiting the page directly? It'd be great to be able to supply Document templates that surface like REST Framework does, but I can't make out whether you're checking the client, the action, the protocol or something altogether different.
Browsers will indicate that they prefer HTML, so that's what REST framework serves them.
Much thanks!
The framework is great, the best I have tried.
Edit: I should mention that both were pretty painstaking the first go-around, but mostly due to my ignorance of the platform. I am thankful to know some more seasoned Tastypie users, so getting answers was pretty easy, and the Google Group is really good for Tastypie as well.
Here's the outstanding ticket for OAuth: https://github.com/tomchristie/django-rest-framework/issues/... There's a link to a gist on there which implements that for REST framework 0.4, which just needs a little updating, testing, and documentation.