51

I've got a Django application that works nicely. I'm adding REST services. I'm looking for some additional input on my REST strategy.

Here are some examples of things I'm wringing my hands over.

  • Right now, I'm using the Django-REST API with a pile of patches.
  • I'm thinking of falling back to simply writing view functions in Django that return JSON results.
  • I can also see filtering the REST requests in Apache and routing them to a separate, non-Django server instance.

Please nominate one approach per answer so we can vote them up or down.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
S.Lott
  • 384,516
  • 81
  • 508
  • 779

11 Answers11

59

I'm thinking of falling back to simply writing view functions in Django that return JSON results.

  • Explicit
  • Portable to other frameworks
  • Doesn't require patching Django
Ali Afshar
  • 40,967
  • 12
  • 95
  • 109
  • 3
    This can get you a certain distance, but if you want to do authentication then please don't reinvent the wheel - that's how we end up with lots of insecure web apps all over the web. That's why we all love the Django auth module (we do? don't we ...). A good article with more explanation ends with ["I plead with you to follow someone else's example and not roll your own authentication scheme."](http://broadcast.oreilly.com/2009/12/principles-for-standardized-rest-authentication.html). – Hamish Downer May 26 '11 at 12:02
  • 7
    There's some really good parts to that article, but the author's assertion that API keys should be added to the URL is misguided, and un-RESTful. That's what the WWW-Authenticate and Authorization headers are there for. (See the comments by Mike Amundsen and Ron Wail for a fuller explanation) – Tom Christie Jun 01 '11 at 12:15
  • Whilst I agree with the sentiment 100%, "un-RESTful" does not necessarily equate to "bad". Though clearly authorization codes in URLs are certainly not good. – Ali Afshar Jan 12 '13 at 17:18
30

Please note that REST does not just mean JSON results. REST essentially means exposing a resource-oriented API over native but full-fledged HTTP. I am not an expert on REST, but here are a few of the things Rails is doing.

  • URLs should be good, simple names for resources
  • Use the right HTTP methods
    • HEAD, GET, POST, PUT, and DELETE
    • Optionally with an override (form parameter '_method' will override HTTP request-method)
  • Support content-type negotiation via Accept request-header
    • Optionally with an override (filename extension in the URL will override MIME-type in the Accept request-header)
    • Available content types should include XML, XHTML, HTML, JSON, YAML, and many others as appropriate

For example, to get the native HTTP support going, the server should respond to

GET /account/profile HTTP/1.1
Host: example.com
Accept: application/json

as it would respond to

GET /account/profile.json HTTP/1.1
Host: example.com

And it should respond to

PUT /account/profile HTTP/1.1
Host: example.com

var=value

as it would respond to

POST /account/profile HTTP/1.1
Host: example.com

_method=PUT&var=value
yfeldblum
  • 65,165
  • 12
  • 129
  • 169
  • 1
    Note that you too are not discribing rest in its full glory. You are discribing level 2 on the Maturity Model. http://martinfowler.com/articles/richardsonMaturityModel.html – nickik Aug 06 '13 at 14:39
25

For anyone else looking for a very decent, pluggable API application for Django, make sure you checkout jespern's django-piston which is used internally at BitBucket.

It's well maintained, has a great following and some cool forks which do things like add support for pagination and other authentication methods (OAuth is supported out of the box).

Updated to reflect that django-piston is no longer maintained.

oliland
  • 1,299
  • 11
  • 23
  • 5
    Django-piston can no longer be considered "well-maintained." Although the code was stable when it was more-or-less abandoned, it has and will become more and more out of date as django (and the community) moves on. For one, there are a host of unresolved bug reports. Piston is dead, long live django-tastypie and django-rest-framework. http://pydanny.com/choosing-an-api-framework-for-django.html – B Robster May 17 '12 at 03:12
7

Tastypie is also a newly emerging REST framework for Django. It has the same mindset as pistons, and removes a lot of boilerplate coding.

RickyA
  • 15,465
  • 5
  • 71
  • 95
5

My answer to the same question here: Framework for Implementing REST web service in Django

The short version is, have a look at https://github.com/jgorset/django-respite/ a REST framework in its early days, but we use it every day on client projects.

Community
  • 1
  • 1
espenhogbakk
  • 11,508
  • 9
  • 39
  • 38
4

Scrap the Django REST api and come up with your own open source project that others can contribute to. I would be willing to contribute. I have some code that is based on the forms api to do REST.

Sam Corder
  • 5,374
  • 3
  • 25
  • 30
3

I'm thinking of falling back to simply writing view functions in Django that return JSON results.

I would go with that ..
Ali A summed it pretty well.

The main point for me is beign explicit. I would avoid using a function that automatically converts an object into json, what if the object has a reference to a user and somehow the password (even if it's hashed) go into the json snippit?

hasen
  • 161,647
  • 65
  • 194
  • 231
2

I ended up going with my own REST API framework for Django (that I'd love to get rid of if I can find a workable alternative), with a few custom views thrown in for corner cases I didn't want to deal with. It's worked out ok.

So a combination of 1 and 2; without some form of framework you'll end up writing the same boilerplate for the common cases.

I've also done a few stand-alone APIs. I like having them as stand-alone services, but the very fact that they stand alone from the rest of the code leads to them getting neglected. No technical reason; simply out-of-sight, out-of-mind.

What I'd really like to see is an approach that unifies Django forms and REST APIs, as they often share a lot of logic. Conceptually if your app exposes something in HTML it likely wants to expose it programmatically as well.

Parand
  • 102,950
  • 48
  • 151
  • 186
2

You could take look at django-dynamicresponse, which is a lightweight framework for adding REST API with JSON to your Django applications.

It requires minimal changes to add API support to existing Django apps, and makes it straight-forward to build-in API from the start in new projects.

Basically, it includes middleware support for parsing JSON into request.POST, in addition to serializing the returned context to JSON or rendering a template/redirecting conditionally based on the request type.

chrismi
  • 71
  • 1
  • 1
1

you could try making a generic functions that process the data (like parand mentioned) which you can call from the views that generate the web pages, as well as those that generate the json/xml/whatever

Jiaaro
  • 74,485
  • 42
  • 169
  • 190
1

TastyPie looks quite interesting and promising. It goes well with Django.

Cody
  • 342
  • 4
  • 8