Skip to content

HTTP Communication Between Frontend and Backend: A Guide with Vue.js and Django

About 1598 wordsAbout 5 min

NetworkFullstack

2025-07-19

Info

The reason I wanted to write this article is because I've been working on a Django + Vue.js full-stack project recently, and I previously only had some experience with Kotlin Jetpack Compose mobile application development in FIT2081. Although in some sense, mobile development and traditional full-stack development have many similarities, there are still some key differences, especially since I used Kotlin Jetpack Compose, a modern declarative framework. Thanks to Kotlin's good design, the experience of developing mobile applications with Jetpack Compose is very smooth. When using ORM and ViewModel, Kotlin's ecosystem provides excellent support, making the interaction between backend models, viewmodels, and views very natural and almost seamless. However, this excellent programming experience made me overlook a problem that I only now realize: the complexity of interaction between frontend and backend.

In web development, communication between frontend and backend is crucial for creating dynamic and interactive applications. This communication is primarily handled through HTTP. In this article, we will explore the fundamentals of HTTP and demonstrate how to set up communication between frontend and backend using Vue.js and Django as examples.

Understanding HTTP

HTTP is the foundation of data communication for the network. It is a client-server protocol, meaning requests are initiated by the recipient (usually a web browser). A complete document is reconstructed from different sub-documents fetched, such as text, layout descriptions, images, videos, scripts, etc. Although HTTP can be used to transmit any type of data, some even very complex in structure, the HTTP protocol itself does not care about the content of the data; it only cares about how the data is transmitted. Therefore, the structure of each HTTP message is actually very simple.

Warning

However, note that although this article consistently refers to HTTP requests and HTTP responses, it actually only discusses the most mainstream pattern of HTTP requests and responses, also called RESTful API. RESTful API is an architectural style based on the HTTP protocol that emphasizes statelessness, resource orientation, and uniform interfaces. It uses standard HTTP methods (such as GET, POST, PUT, DELETE) to operate on resources and identifies resources through URLs. Other common API styles include GraphQL and gRPC. If readers are interested in these, they can look up relevant materials on their own.

HTTP Request Structure

As shown above, HTTP requests start from the client, so we first explain the client's request structure.

An HTTP request is a message sent by the client to the server, requesting the server to perform some operation or return some data. An HTTP request typically contains the following parts:

An HTTP request consists of the following parts:

  1. Request Line: Includes the HTTP method (e.g., GET, POST, PUT, DELETE), request target (usually a URL), and HTTP version. Where:
    • HTTP Method: Indicates the type of request, such as GET (retrieve resource), POST (submit data), PUT (update resource), or DELETE (delete resource).
    • Request Target: Usually the resource path on the server, for example, in a backend running process, there is a URL /api/users/ specifically for getting the user list.
    • HTTP Version: Such as HTTP/1.1 or HTTP/2.
  2. Headers: These are key-value pairs that provide additional information about the request, such as content type, authentication tokens, and caching directives.
  3. Body: This is an optional part that contains data sent to the server, typically used with methods like POST and PUT, such as submitting form data or uploading files. This part often involves conversion of structured data formats like JSON.

HTTP Response Structure

An HTTP response consists of the following parts:

  1. Status Line: Includes the HTTP version, status code (e.g., 200, 404, 500), and status message.
  2. Headers: Similar to request headers, these headers provide information about the response.
  3. Body: Contains data sent back from the server, which can be HTML, JSON, XML, or other formats, but is usually in JSON format.

Common HTTP Status Codes

  • 200 OK: The request has succeeded.
  • 201 Created: The request has been fulfilled and has resulted in the creation of one or more new resources.
  • 400 Bad Request: The server cannot or will not process the request due to an apparent client error.
  • 404 Not Found: The server can't find the requested resource.
  • 500 Internal Server Error: The server has encountered a situation it doesn't know how to handle.

Setting Up the Backend with Django

Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. Let's create a simple API endpoint that returns a list of users.

Now, let's create a simple Django view and URL configuration.

Tips

The following code uses Python's decorator functionality, which is a way to add additional functionality before and after function or method calls. Decorators can make code more concise and readable. For details, you can read Python Decorators. Simply put, decorators achieve functionality extension by passing the decorated function into another function and returning a new function. This is a common usage of higher-order function.

views.py

from django.http import JsonResponse # Import JsonResponse from Django's HTTP module
from rest_framework.decorators import api_view # Import api_view decorator from Django REST Framework

@api_view(['GET'])
def user_list(request):
    """
    A view that returns a list of users in JSON format.
    """
    # This is just sample data; in actual applications, JSON can be obtained from database queries, which is easy to implement in many databases.
    users = [
        {'id': 1, 'name': 'Alice'},
        {'id': 2, 'name': 'Bob'},
    ]
    return JsonResponse(users, safe=False)

urls.py

from django.urls import path
from .views import user_list

# This is a URL configuration that maps API endpoints to view functions for communication with the frontend.
urlpatterns = [
    path('api/users/', user_list, name='user-list'),
]

Setting Up the Frontend with Vue.js

Vue.js is a progressive JavaScript framework for building user interfaces. We will use the axios library to make HTTP requests to our Django backend.

Now, let's create a Vue component to fetch and display the user list.

UserList.vue

<template>
  <div>
    <h1>User List</h1>
    <ul>
      <li v-for="user in users" :key="user.id">{{ user.name }}</li>
    </ul>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      users: [],
    };
  },
  mounted() {
    this.fetchUsers();
  },
  methods: {
    // Use async functions for handling network communication. If you don't understand the specific principles, you just need to know this is done to ensure correct program execution order and results
    async fetchUsers() {
      try {
        // The await keyword is used to wait for asynchronous operations to complete and can only be used in functions declared as async
        const response = await axios.get('/api/users/'); 
        this.users = response.data;
      } catch (error) {
        console.error('Error fetching users:', error);
      }
    },
  },
};
</script>

In this example, the fetchUsers method sends a GET request to the /api/users/ endpoint exposed by the backend. When the data is received, it's stored in the users array and displayed in the template.

Note

In practice, frontend and backend processes often run on different ports, so CORS (Cross-Origin Resource Sharing) needs to be configured to allow cross-domain requests. Django can easily handle this by installing the django-cors-headers package.

Conclusion

Although I am still a learning developer, through this process of building a full-stack project with Vue.js and Django, I have become more clearly aware that: communication between frontend and backend is actually much more complex than I initially thought.

The HTTP protocol serves as a bridge for frontend-backend communication, not just simple "request-response". Behind it, the request methods, status codes, data formats, cross-domain policies, etc., all affect the robustness and user experience of applications at different levels. This article is just a preliminary organization and summary. Real system development is far more complex than the example code, and it also needs to consider security, interface design specifications, error handling, performance optimization, etc.

In the process of writing this article, I also began to realize that RESTful is just one of many API design styles. As my understanding gradually deepens, I also hope to try new solutions like GraphQL or gRPC in the future to see how they differ from REST in actual development.

Further Reading