Best practice when designing an api (with Django)

32 views
Skip to first unread message

Joakim Hove

unread,
Aug 31, 2015, 1:59:14 PM8/31/15
to django...@googlegroups.com
Hello;

[ This question might be more about general principles for API design than Django, but since Django is my tool of choice - and my context of understanding, I am posting it here.]

I have been maintaining a small Django based website for some time. It is mostly based on conventional views returning HTML, but both to support JavaScript interactivity and to interact with a traditional desktop application I am gradually creating a REST based API. Up until now I have created the REST endpoints manually, but I now I intend to look into the Django Rest Framework (DRF) and try to do things more properly. Now - the question where I would appreciate some guidance boils down to: "How much should I use my own http based API internally?". Assume I have two django models 'Author' and 'Book', each book can have several authors and of course each author can write several books - i.e. this is a many to many relationship:

    class Author(models.Model):
         ....
         books = models.ManyToManyfield( "Book", ...)

    class Book(models.Model):
         ....

It is then natural(?) to configure the urls:

/books/1       - Get information about the book with ID=1
/authors/7    - Get information about the author with ID=7

But let us say that I wanted to create the endpoint:

/books/7/authors

To get the author information for the authors of the book with ID=7. In my view I have used:

    book = Book.objects.get( pk = 7 )

To get the right book, now I want the author details. As I see it I have two approaches to get the author details:

  1. I can just use the ordinary Model/ORM methods.
  2. I can use my own http api - and "loopback" repeated calls to: /authors/$ID
On the one hand I strongly believe in the "eat your own dogfood" principle, but on the other hand it feels a bit over the top to issue http calls in this situation? Grateful for comments from experienced API desginers.


Joakim

James Schneider

unread,
Aug 31, 2015, 4:24:15 PM8/31/15
to django...@googlegroups.com
>
> I have been maintaining a small Django based website for some time. It is
> mostly based on conventional views returning HTML, but both to support
> JavaScript interactivity and to interact with a traditional desktop
> application I am gradually creating a REST based API. Up until now I have
> created the REST endpoints manually, but I now I intend to look into the
> Django Rest Framework (DRF) and try to do things more properly. Now - the
> question where I would appreciate some guidance boils down to: "How much
> should I use my own http based API internally?". Assume I have two django

The answer is "where it makes sense to do so". For the most part, this
means any area that requires partial page updates via AJAX calls.
Unless you are rendering everything via JS (for example, as part of an
SPA), the full page loads should probably be handled via the standard
Django rendering process rather than pulling objects via AJAX and
rendering client side. Usually that is simpler to manage.

> models 'Author' and 'Book', each book can have several authors and of course
> each author can write several books - i.e. this is a many to many
> relationship:
>
> class Author(models.Model):
> ....
> books = models.ManyToManyfield( "Book", ...)
>
> class Book(models.Model):
> ....
>
> It is then natural(?) to configure the urls:
>
> /books/1 - Get information about the book with ID=1
> /authors/7 - Get information about the author with ID=7

Yes, this is a typical layout, or at least it falls in line with the
URL schemes I normally use.

>
> But let us say that I wanted to create the endpoint:
>
> /books/7/authors
>
> To get the author information for the authors of the book with ID=7. In my
> view I have used:
>
> book = Book.objects.get( pk = 7 )

Where exactly did you use this? Can you post up a copy of the view?

>
> To get the right book, now I want the author details. As I see it I have two
> approaches to get the author details:
>
> I can just use the ordinary Model/ORM methods.

^^^ This one. ^^^

> I can use my own http api - and "loopback" repeated calls to: /authors/$ID
>
> On the one hand I strongly believe in the "eat your own dogfood" principle,
> but on the other hand it feels a bit over the top to issue http calls in
> this situation? Grateful for comments from experienced API desginers.

You can use repeated calls, but at that point you are trying to eat
your own dog food using a straw. There are much more efficient
methods. :-D

API's can handle multiple objects as easily as standard Django views.
In this case, you are querying for a list of authors for a specific
book. Your queryset would look like this:

# using the book object you created earlier
book_authors = book.author_set.all()

# or a single queryset to pull in everything
book_authors = Book.objects.get(pk=7).author_set.all()

Have you gone through the DRF tutorial? It shows examples of pulling
and serializing a list of users in a single query, very similar to
pulling a list of authors related to a book.

http://www.django-rest-framework.org/tutorial/quickstart/

-James

Joakim Hove

unread,
Aug 31, 2015, 4:36:07 PM8/31/15
to django...@googlegroups.com

Thank you for an informative answer ;-)

 
> To get the author information for the authors of the book with ID=7. In my
> view I have used:
>
>     book = Book.objects.get( pk = 7 )

Where exactly did you use this? Can you post up a copy of the view?

This was currently only a construction in my head; and not literally from an existing view. You have answered the question firmly further down.
 
> [...] ust use the ordinary Model/ORM methods.

^^^ This one. ^^^

Clear answer!


 

You can use repeated calls, but at that point you are trying to eat
your own dog food using a straw. 

Well - that does not sound terribly efficient.
 
Have you gone through the DRF tutorial? 

I'm in the process - very pleasent documentation by the way.


Thank's again - Joakim

Reply all
Reply to author
Forward
0 new messages