I am working on a RESTful application, which goal is to allow user to track his results, progress and performance in sport activities.
I want to create two or more clients for this app:
1) web client
2) mobile client ( iOS / Android )
I am writting it in django using tastypie app and I wonder if I should make web client in the same application, which will provide the RESTful api or should I leave it as a pure REST service and build separate web client, which will contact it via the api?
As for now I don't see any drawbacks of making both in one, but I am not an expert in programs with such an architecture, so I am looking for some advise with argumentation behind it.
It is not easy to answer to this as it depends a lot on what kind of service you are building.
Approach 1: Traditional Django app + API
Here your Django-app and the tastpie API share common data models but present them differently. One using Djangos templates and views and the other using tastypie.
Pros:
Building a traditinal web service is relatively easy and well understood problem
Django provides a lot of tools for this
Cons:
There is no gurantee that the API presents the same functionality as the web service
You have to maintain two different ways to interact with your data.
Approach 2: API only + JavaScript webapp that uses the API
There is only one interface to the service via the tastypie API. The web client is built separately using javascript tools like backbone.js and backbone-tastypie.
Pros:
You gurantee that the 3rd party developers can build a service with the same functionality as your web service (see dogfooding).
Works pretty nicely if your service is more of an application than a collection of pages.
Cons:
Client side JavaScript tools are not as good as Djangos (for example, templating).
Client side rendering of templates only happens after most of the resources are loaded.
First pageload is slow
Pre-IE9 browsers won't work without trick, IE9 may need tricks
You really need to mind about browser caches
SEO is not as straightforward as with traditional web service.
Approach 3: API only + call the API from Django views
Pretty much same as Approach 1 but instead of using your models directly you call the tastypie resources internally.
Pros:
You can still use most of the Django tools.
You mostly use the same API as potential 3rd party developers
Cons:
I do not know how much overhead this incurs.
There is a fourth way to do this, which extends on #seppo-erviälä Approach 1 and Approach 2:
Approach 4: API View + Django View via Handler
Create a handler that returns the RESTful resource just as RESTful API view normally would. But this handler is callable from anywhere. It gets the same request dictionary that the view gets and it returns the same JSON the view returns. So now, the architecture is:
Handler
/ | \
/ | \
/ | \
/ | \
RESTfulView | Normal Django View
|
Anything Else
The handler:
class ResourceHandler:
def create_resource(self, data):
# code
def fetch_resource(self, rId):
# code
# and so on
and you call it from the views like so:
# /views/restfulview.py
# using django-rest-framework
from rest_framework.response import Response
class RESTCallView(APIView):
h = ResourceHandler()
def get(self, request, rId):
return Response(self.h.fetch_resource(rId))
# /views/normalview.py
from django.views.generic.base import TemplateView
class SomeDjangoView(TemplateView):
h = ResourceHandler()
def get(self, request, rId):
return HttpResponse(self.h.fetch_resource(rId))
Of course, this is just example code and not really pythonic but you get the idea.
I work in a large e-commerce company and some of my teammates have used this approach to good success.
Some other advantages are:
Migration of old data becomes a lot easier now since you just need to create the dict and send it to the Handler. Similarly, sync also becomes a lot easier.
Changes to APIs are in one place, and you can cut off the app without killing access to the data.
Hope this helps you too.. :)
Better create a pure REST service and consume it from both the client. It will provide a clean layered architecture as you are not mixing service with client in one app. By having a common service separately you would have : Separation of concern, Clean Architecture, Proper Laying, Readability and better Maintainability.
Related
I'm used to Django and already developed website with a whole Django or with Django API + React.
For a side project, I'm thinking about creating a Django project with 2 apps:
Django API 2) Django Front.
I absolutely want to decouple front/back to be able to reuse the API in the future, and I like the view system from Django.
Is my idea making sense?
Edit 1:
To clarify.
App 1: Django API serving JSON.
App 2: Django App using API calls in the controllers to generate the views.
Edit 2:
I did a proof of concept and it works like a charm.
The only drawback is that I have to use Cookies to store the JWT token and maintain the session state, which is not convenient
it is possible, but completely wrong with idea.
How it possible. Wrong version:
Try to remember, how we can create integrate test for our view. We Should create client and send request to Django to your view-url with args kwargs querystring e.t.c.
In response you have already answer. Try to imagine: part with client - is your Django front, requested part - your backend.
The same works not only in test, you can create request to ask something on the completely other server.
Redis/MemCashed e.t.c. (pattern sender/receiver) Wrong version:
The Front Django speaks with Backend through Third part application. It can be faster.
"Pythonic" version. Right in your case:
You can create Backend Django part like a library with views as interfaces.
Frontend Django part is completely standalone, it import an use interfaces from library, which is your "BackEnd Module".
If you want - you can use "BackEnd Module" everywhere as import, or you can start it as server and ask info per requests.
Completely independent in this case means, you can install "BackEnd Module" without "FrontEnd Module". "FrontEnd Module" can be installed standalone too and it should take from settings, which interfaces should be used as data-source.
I hope, i am right understand your question.
You could definitely separate front and back, remember, django just creates endpoints and consumes them with its own views, you can even use both.
Here is the documentation for django views: https://docs.djangoproject.com/en/4.0/#the-view-layer
You can use a librarie like React as frontend and connect to your api(django app) and use both.
So I just created a website's front-end using ReactJS. Now all I need is a backend database that I will fetch data from using requests.
The question is whether I need to render templates using my backend or just use my server to make requests (eg get, post etc)
PS. I will be using Django as my backend.
Thank you everyone who will help me out.
Doing both is recommended. Based on the requirements and use cases we must use both ways to render.
For example, Some products use initial html as a Server side rendered page with all essential data required inserted as scripts and so on. This helps in loading primary content faster. If we are not following this in applications that require data initially. Then it might take more time to fetch React chunks, scripting and after seeing an API makes request, and then getting data and then displaying the primary content. So when a page needs more data (like More API calls) then server side rendering might be a good way.
For other scenarios like getting user details, All these can be done using React.
No, because you will use DRF (Django Rest Framework) to communicate between frontend and backend. Basically you will write your own APIs in the views.py that will respond with JSON data, at least in major of cases this will be enough. So, you don't need templates, since template are really Djangos' frontend, that you will not be using at all.
But, this heavily depends on what you are doing and what is your setup.
I am not able to comprehend what would be pros and cons of the following approaches in making a single page backbone application using RESTful APIs from Django Rest Framework.
Render the whole app from within Django's template.
Serve the backbone app from another server ie node server. With nginx in the front for both servers.
Serve the HTML/Templates and JS from a separate CDN.
What are the things to take care ie points of caution in each strategy. Is there any other way to tie them up which I am missing?
This is a very broad question, and really it has nothing to do with Django or Backbone. What you're really asking about is a "thick-client" architecture vs. a "thin-client" architecture. In other words, having your user interface rendered on the client vs. having it rendered on the server.
First, allow me to recap a few things to make sure we're on the same page. The "thin-client" approach is the traditional/old school model, and the model Django itself is based on. The server renders HTML, sends it to the client, and whenever the client wants to do something it sends data back to the server and asks for fresh HTML.
In contrast the more modern "thick-client" approach lets the client render all of the UI. Whenever the client needs to do something it makes an AJAX request to a (presumably REST-ful) API, powered by a library like Django REST Framework. That API just returns the relevant data, and leaves it up to the client to render it appropriately.
There are advantages and disadvantages to both approaches, but the thick-client approach is becoming more and more popular because:
network transactions are faster: because your server is only sending the exact JSON you need instead of a mess of HTML, the "payload" of the response is much smaller
you can fetch all data "behind the scenes"; this makes things appear faster to the user, and lets you implement UI paradigms (eg. infinite scroll) that a thin client can't
the client/server relationship is simpler, because the people writing server code never have to even think about HTML or any other presentation logic; they get to just focus on the data (which, being server engineers, is probably the part they're most interested in anyway)
This is why a lot of companies (including the one I work for) have all but abandoned Django proper in favor of API endpoints served by Django REST Framework.
So, if you want to go with a thick client architecture, Django should never serve anything except the very first HTML page (and even that could be served by ngnix if you wanted, since it's just static HTML). After that you'd use a Backbone.Router and Backbone.Views to render your site. Whenever you need new information from the server you'd fetch a Backbone.Model or Backbone.Collection (with its url property pointing to your Django REST Framework endpoint).
I can attest that this whole approach works great; the site I work on is very complex, with many endpoints, and Backbone + Django REST Framework handles it beautifully. The only (slightly) tricky part is caching: in the thin client approach the browser automatically caches pages for you, but since there are no "pages" in a thick client (just AJAX responses with data) there is no automatic caching. This means that if you want to cache data you'll need to do it yourself, for instance with a Backbone.Collection devoted to that purpose.
Hope that helps.
P.S. Back in the day Django REST Framework didn't handle Django authentication stuff (ie. logging in/out) quite the way we wanted, so we wound up serving one other page, our login page, from Django. However I'm pretty sure the current Django REST Framework handles authentication stuff much better now, so this likely won't be an issue for you.
I'm trying to wrap my head around combining a client-side framework like AngularJS with Django. One thing that's really confusing me is the issue of routes and REST.
I've been trying to read a lot about it online, but documentation is limited, especially in terms of Django being combined with Angular (little snippets here or there). I understand that I need to add a REST framework like TastyPie to make a robust REST interface in my app in order for Angular to plug in and grab resources.
However, I'm confused as to how to properly map out my routes in such a way that (1) my server-side app can render my single-page app (SPA) with angular plugged in (2) routes that are supposed to load information/render templates (angular) and retrieve data from the server (django) don't conflict. Like if I have someone going on my website and doing site.com/user/1234 - that route is associated with both the Angular route and the Django route - except one renders a template and the other spits out JSON based on what is retrieved from the DB/server.
In addition, by using the REST api, do I forego a lot of the advantages I have in terms of having ModelForms being synchronized with my Models, etc? Is there any way to maintain this with AngularJS or do I have to look towards an AngularJS substitute.
The question isn't really specific to Django - just a matter of understanding the relationship between back-end and front-end in an SPA.
Routes are not duplicated between the back-end and the front-end. Your Django routes should be set up like:
/api/foo
/api/bar
...
and one single route that delivers a single page full of HTML partials, e.g.
/
The rest of the routes will be defined in Angular, e.g.
/articles/234
/blog/date/slug
...
The Angular controllers that handle those public-facing routes will in turn make $http calls against the API URLs and each will deliver one Angular partial. So there is no duplication, no overlap.
To the second part of your question, you can still use the Django ORM model relationships when constructing your API data, but yes, you'll lose all of that Django goodness when building the front-end.
If you build your API right, all of the data you need in each view will be fully present in the JSON feed that Angular consumes in that view. So you're using the ORM for back-end data construction, but you can't just decide to traverse a model relationship in a template without first preparing the back-end data to provide data for it.
Yes, it's a very different way of thinking of things, and yes it's quite a bit more complex than doing straight Django (or Rails). That's the cost of building a web app rather than a web site.
I'm in a process of migrating Rails project into Django. Rails project was built using restful routes and it never touches the database. Instead, it simply redirects to different methods which all call an external service with the specified action method. Now, I have found a number of frameworks for django that provide restful capability plus a bunch of bells and whistles, but it's an overkill for my current case.
As an alternative, I can ignore action method in urls.py by simply providing a regex to validate urls and then parse the request method in views.py, redirecting to the appropriate method. Is this a way to go or are there any other approaches that I can look at?
Class based views look like the idiomatic way to organize restful view functions by request method.
Django snippets has several simple example implementations.