dotaneli
dotaneli

Reputation: 45

Should I render ajax responses on server side?

New to Django and Ajax in general.

I was wondering about a general question of good-practice web design: Should a view function that returns a call called using ajax, return data structures and leave rendering of HTML pages to the client side (meaning javascript) or is it also an "okay" practice to render the entire HTML and return it to javascript so it can paste it somewhere in the code?

I don't want the logic of my templates to be repeated by javascript. I want to use the templates to render HTML and return it to the client. But... that misses the point of ajax, doesn't it?

I did come across this fantastic post: Rendering JSON objects using a Django template after an Ajax call

Since it's old, I didn't post a reply there but rather revived the matter here. Is it technically possible to render on server side? yes. Best practice? I don't know.

Perhaps the better practice is to have my HTML pages sort of "empty spaces" already well-formed and just pass data back and forward.

I would love to hear your opinions on the matter.

After being set on hold since this discussion tends to be opinion based (it does) and that format isn't fit for this forum, I though it would be good to update my post to include a finer resolution of discussion with very much technical implications.

What, in your "djangonian" experience, would be a best-practice for building a web page, such as a news feed, that could be dynamically updated with ajax calls, which return the client raw data (using JSON for example) and not pre-rendered HTML?

I'll get more specific: My website has a feed. On that feed, the user sees many posts and comments per post. Every post is its own HTML form, and already structured as HTML. An example for a page source:

<form id="post_looloo_by_testuser" method="post" action="/bz/login/" class="single_post_form">      
    <input type='hidden' name='csrfmiddlewaretoken' value='GfOHEMxx433XBUpg3yakTYPRQCVq132f' />
    <p class="box_single_post">
      <span name="post">
        <label class="single_post_form">
           says: looloo
        </label>
      </span>

      <span name="comments_for_post">
        <span name="single_comment">
          <label class="single_comment">
            testuser2 commented: moomoomoo
          </label>
        </span>
      </span>


      <span name="comments_for_post">
        <span name="single_comment">
          <label class="single_comment">
            testuser2 commented: qweqwe
          </label>
        </span>
      </span>


      <span name="add_comment">
        <input id="id_add_comment" maxlength="140" name="new_comment" type="text" placeholder="Add a comment..."/>
      </span>
    </p>
</form>

On the top, much like on facebook, the user can add a new post instantly.

<form id="add_post_form" method="post" action="" class="new_post_form" username="testuser">
  <input type='hidden' name='csrfmiddlewaretoken' value='GfOHEMxx433XBUpg3yakTYPRQCVq132f' />
  <span name="add_post">        
    <input id="id_add_post" maxlength="140" name="new_post" type="text" placeholder="Say something"/>
    <input id="add-post-btn" type="submit" name="submit" value="Add" username="testuser"/>
  </span>
</form>

The "Add" button (really a submit for the form) would then invoke an ajax call to a certain view within my app on the server side. I want the view to return information such as the user who owns the post, the post text, the comments list etc. The information would be return as JSON or XML. Not as pre-rendered HTML. I want to have my javascript process the information and update the user's feed with the new post on top, while avoiding refreshing the page (hence the use of ajax).

Problem is the user can of course add an infinite number of posts (or a limited number, but bigger than one). Why does it matter? see below question:

How should I create the feed page in a way which allows for me to just update variables on the page with the dynamically retrieved information, and still allow for more posts to be added?

If I were to know in advance that only one such new post is available, then I would create a pre-made post form, invisible, and the javascript would set values to that form and set it to visible. But what about the second post the user adds? and the third? and so on...

I would love to learn from your experience. Thank you.

Upvotes: 1

Views: 2438

Answers (4)

dotaneli
dotaneli

Reputation: 45

Thank you all for your replies.

I wanted to update that I decided to go with the elegant solution, which also turns out to be more practical, meaning letting the client side do the work:

I only transfer lean JSON elements to the client side; I let the client generate the relevant HTML.

True, it is sort of "repeating" myself since the server side and client side both have similar code segments handling the creation of exactly the same HTML segments.

Nonetheless, it became clear to me that loose coupling in this instance is crucial for being able to scale to other non-pc interfaces such as android, ios, windows phone etc.

Moreover - it is faster that way. No need to burden the server side with rendering countless amounts of HTML when the client side can do it.

Thank you all again.

My conclusion is - make it right, even if is seems to cost more.

Upvotes: 0

user2629998
user2629998

Reputation:

No, you shouldn't.

AJAX calls should only contain the requested resource in a standard format and not some custom HTML, for example if I do a request for /cars I expect to get a list of instances of car in a standard format (JSON or XML), the backend server shouldn't know nor care how I present that data.

Also it's a good idea to generate the HTML on the client side to avoid transmitting unnecessary data over the wire, let's say I request some /cars and get a few hundred thousands of them, each one with an HTML table markup... that's a lot of unnecessary markup that can be added on the client side without having to transmit it over the wire, so it saves bandwidth and that's important, especially for mobile users.

Finally the controllers for the endpoints called via AJAX should be simple and not contain any view-related code, first to cut a few milliseconds off the response time, and second so that if you want to change the UI you'll change it in your HTML/CSS/JS files which, depending on the complexity of your solution may be part of a different app altogether (what if your app only serves to provide an API for a third party webapp ? You'll want the third party app to control the presentation while you only provide the raw data).

Regarding your edit, I really don't see what is the problem with adding potentially infinite amounts of HTML elements to the page... You don't need to have each element declared in advance in the HTML file, you can create an infinite amount of them on the fly via Javascript and then insert them wherever you want.

For your "how would I do an AJAX-powered newsfeed" question, it depends on my motivation and it ca go between a basic server-generated page with optional AJAX refresh (the template lives both in the server and in the Javascript to present the AJAX data) to a complete Ember app with the server just providing a JSON API.

Upvotes: 1

martintrapp
martintrapp

Reputation: 829

Rendering on server side is probably faster than on client side. However it requires more performance on your server.

If you've already wrote your templates in django you could save development time by returning with complete html data. Otherwise you have to write your own rendering methods in JS.

In this case if you change anything in django, you have to duplicate yourself on the client side code.

Personally I think rendering on server is safer and simplier.

Upvotes: 1

jimjkelly
jimjkelly

Reputation: 1661

I think it's important to step back a bit, and break out some terminology here. Rendering, as you are using it, could refer to a couple of things:

  • Rendering html tags and css rules in a browser to create a view of a web page for the user, based on data received from a server or servers.
  • Rendering data to some sort of response on the server side, to be consumed by the client's browser, or any other tool that happens to follow the protocol being used (HTTP in this instance).

These are distinct activities that really aren't related, but I think the ability to use the same term to mean both may be confusing you. Django will render a response to an HTTP query asking for a resource, whether this response contains HTML or JSON or plain text doesn't matter much.

Now, that said, whether you want to do more of the work in creating the webpage to look a certain way on the server side (the template) or the client side (js) is more of a style question (with some allowance for the practicalities that can arise from your particular use case, of course).

For my own purposes, I generally prefer to render general data (perhaps an organization name, variables about navigation, etc) in the template, and if I'm displaying an unknown or large amount of data pulled from a db, I'll fire off an AJAX call for that and show the user an indication the data is loading.

But experience will be your guide for what is appropriate and when.

Upvotes: 0

Related Questions