Django REST Framework и Vue против Django и HTMX

В этой статье подробно описываются различия между разработкой приложения с использованием Vue и Django REST Framework (DRF) по сравнению с HTMX и Django. Мы рассмотрим простой пример того, как работают обе комбинации, и сравним их сильные и слабые стороны.

Фреймворк Vue и Django REST

Vue, хотя и менее популярен, чем Angular и React, выделяется своей простотой и позволяет сосредоточиться на уровне веб-приложений. Он легкий и может быть запущен всего из одного JS-файла. Это упрощает процесс обучения и интеграции в существующие проекты по сравнению с React или Angular.

Несмотря на то, что Vue сам по себе довольно мощный, его функциональность значительно расширяется за счет дополнительных библиотек и инструментов. Такие инструменты, как Vite для управления проектами, Pinia для управления состоянием и Vue Router для клиент-параллельная маршрутизация - все это способствует повышению надежности разработки Vue.

Одной из отличительных особенностей Vue является Однофайловый компонент. Этот подход объединяет HTML-шаблоны, логику JavaScript и CSS с областью действия в одном файле для лучшей организации и удобства обслуживания. Такая структура не только делает компоненты Vue автономными и простыми для понимания, но и демонстрирует основной принцип Vue - реактивную привязку данных, которая необходима для интерактивных веб-приложений.

Поскольку Vue работает в браузере, он может хранить данные только временно. Чтобы сохранить данные в дальнейшем, Vue необходимо подключить к внутреннему серверу. Из-за особенностей Vue, когда Vue отправляет запрос на серверный сервер, а затем обрабатывает ответ, платформа, используемая для серверной части, оказывает незначительное влияние. Хотя в этой статье используется фреймворк Django REST (вместе с Django, конечно), вы можете легко использовать Fast API или фреймворк на другом языке.

Давайте рассмотрим пример простой страницы, которая генерирует пароль.

DRF предоставляет конечную точку, которая на запрос GET по определенному URL возвращает ответ, содержащий password:

# view
class GeneratePassword(APIView):
    def get(self, request):
        password = "".join(
            secrets.choice(string.ascii_letters + string.digits + string.punctuation)
            for _ in range(12)
        )
        return Response(password)


# URL
urlpatterns = [
    path("generate-password/", views.GeneratePassword.as_view(), name="generate_password"),
]

Vue, автономное приложение, отправляет запрос на пароль и обрабатывает ответ. Хотя приложение Vue имеет более сложную настройку, часть, которая непосредственно взаимодействует с конечной точкой пароль, - это компонент пароль:

<template>
  <p>{{password}}</p>
  <br>
  <button @click="getPassword">Generate a password</button>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      password: ''
    };
  },
  methods: {
    getPassword() {
      const path = 'http://localhost:8000/generate-password/';
      axios.get(path)
        .then((res) => {
          this.password = res.data;
        })
        .catch((error) => {
          console.error(error);
        });
    }
  }
}
</script>

<style scoped>

</style>

Компонент является самодостаточным и позволяет размещать HTML, JS и CSS в одном файле. При загрузке страницы отображается начальное (пустое) значение для password. Когда пользователь нажимает на кнопку, вызывается getPassword. Затем этот метод вызывает вызов конечной точки API с помощью библиотеки Axios. Полученные данные затем сохраняются в свойстве данных с именем message. Поскольку данные двусторонней привязки были изменены, часть страницы, на которой они отображаются, обновляется.

drf and vue diagram

HTMX и Django

HTMX имеет репутацию "JavaScript-фреймворка для людей, которые ненавидят JavaScript". Он быстро набирает популярность благодаря своему легкому весу и простоте использования. Если вы раньше пользовались каким-либо интерфейсным фреймворком, то у вас совершенно другие ощущения от него - это не столько фреймворк, сколько HTML на стероидах. При использовании HTML вы можете легко добиться динамического отображения страницы, просто используя несколько атрибутов, специфичных для HTMX, непосредственно в HTML.

Основные атрибуты позволяют задать HTTP-метод и URL-адрес для запроса (например,, hx-put), указать, какое событие будет инициировать запрос (hx-trigger), и указать элемент, который будет изменен вместе с ответом (hx-target).

Самый простой способ работать с HTML и Django - это тесно переплетать их. В отличие от сопряжения Vue и DRF, где каждый фреймворк может быть заменен независимо, вы не можете просто отключить Django или HTMX и заменить их чем-то другим (по крайней мере, нелегко).

С одной стороны, код Django, предназначенный для взаимодействия с HTML, отличается от обычного кода Django. И наоборот, HTML встроен непосредственно в шаблоны Django, а не существует в виде отдельных файлов. Как только вы решите использовать эту комбинацию, замена любого из этих инструментов на что-то другое потребует полной перезаписи.

С другой стороны, использование простого Django и решение о том, что вам нужно немного больше интерактивности, не представляют проблемы для облегченного HTMX. Весь ваш проект может основываться исключительно на Django, и добавление одной функциональности HTMX через несколько месяцев потребует небольших накладных расходов.

Давайте посмотрим, как выглядит то же самое - простой генератор паролей с использованием Django и HTML.

HTML просто включен в Django, то есть в нем нет специальных HTML-файлов. Представления и URL-адреса выглядят точно так же, как вы привыкли в обычном Django:

# views
class GeneratePasswordPage(TemplateView):
    template_name = "generate_password_page.html"


class GeneratePassword(APIView):
    def get(self, request):
        password = "".join(
            secrets.choice(string.ascii_letters + string.digits + string.punctuation)
            for _ in range(12)
        )
        return Response(password)


# URLs
urlpatterns = [
    path("password/", views.GeneratePasswordPage.as_view(), name="generate_password_page"),
    path("password/generate", views.GeneratePasswordPartial.as_view(), name="generate_password_partial")
]

Шаблон представляет собой типичный шаблон Django с добавлением небольшого количества HTML-кода:

{% extends 'base.html' %}

{% block content %}
  <p id="password">{{ password }}</p>
  <br>
  <button hx-get="{% url 'generate_password_partial' %}"
          hx-target="#password"
  >
    Generate a password
  </button>
{% endblock %}

Как вы можете видеть, шаблон проще, чем его аналог в Vue. Он почти полностью основан на Django - HTML отправляет запрос и включает ответ в HTML.

HTML не имеет встроенного управления состоянием; управление состоянием полностью зависит от серверной части (в нашем случае, Django). В этом случае Django предоставляет две конечные точки, потому что, в отличие от случая с Vue, где Vue управляет начальной страницей, здесь за обслуживание начальной страницы отвечает Django. При нажатии кнопки запрос отправляется на вторую конечную точку. Эта конечная точка возвращает ответ с паролем. Затем этот пароль добавляется на страницу с помощью HTML.

В отличие от обычного Django, для его объединения с HTML требуется множество фрагментированных представлений Django. Использование HTML для создания приложения, подобного Vue, с множеством изменяемых компонентов может быстро усложнить управление.

django and htmx diagram

В обоих случаях мы создали приложение, которое генерирует пароль при нажатии на кнопку без перезагрузки всей страницы. Но мы пришли к этому двумя совершенно разными способами.

HTMX против Vue

Важно понимать, что сравнивать HTMX и Vue напрямую - все равно что сравнивать яблоки и апельсины. Они затрагивают совершенно разные аспекты веб-разработки.

HTMX ориентирован на взаимодействие с сервером, передачу данных на сервер и обновление страницы на основе его ответа. Основная цель Vue - создавать динамические пользовательские интерфейсы на стороне клиента и управлять ими. Это главное отличие проявляется во всех аспектах процесса разработки.

Одно из наиболее существенных различий между HTMX и Vue заключается в том, как они управляют состоянием. HTMX не имеет состояния и использует серверную часть для управления состоянием, в то время как Vue обрабатывает состояние прямо в браузере, что имеет решающее значение для создания более динамичного взаимодействия с пользователем.

HTMX, несомненно, менее сложен - это усовершенствование HTML, а Vue - полноценный интерфейсный фреймворк. Хотя добавить Vue в существующий проект проще, чем, скажем, React, это все же сложнее, чем добавить HTMX. Однако дизайн Vue позволяет управлять этой сложностью даже при масштабировании проекта. HTMX, хотя и прост для небольших дополнений, может усложниться при более крупных и сложных реализациях.

Независимо от того, какой вариант вы выберете, вряд ли это будет единственный инструмент, который вам понадобится. Vue обладает богатой экосистемой, предлагающей интеграцию с CSS-фреймворками, маршрутизацию, управление состоянием и многое другое. Есть даже инструмент для разработки браузера, который поможет в разработке. HTMZ предлагает несколько расширений и может быть дополнен другими сторонними инструментами, однако в нем отсутствуют официальные возможности интеграции. Несмотря на то, что они обычно используются в паре с такими инструментами, как Alpine.js и Tailwind CSS, они остаются отдельными, без специального инструмента интеграции, который бы их легко соединял.

При принятии решения о том, какую платформу использовать, часто упускаются из виду два аспекта: тестирование и развертывание.

Наличие двух отдельных проектов требует наличия двух сред разработки и разного подхода к тестированию. Vue можно тестировать либо изолированно, когда вам нужно имитировать ответы серверной части, либо с реальными ответами от серверной части, и в этом случае вам понадобится специальная среда тестирования. Тесты с использованием реального API, как правило, проходят медленнее и сложнее, но ближе к реальности. HTMX, добавленный в Django, может быть в основном протестирован с помощью инструментов тестирования Django и дополнен чем-то вроде Cypress для наиболее важных пользовательских потоков.

Что касается развертывания, то при использовании DRF/Vue наиболее распространенным вариантом является их раздельное развертывание - например, два контейнера Docker. Затем вам нужно либо обслуживать их из разных доменов и настроить заголовки CORS, либо развернуть их через прокси-сервер на основе пути - например, перенаправлять все запросы, начинающиеся с префикса /api/, в контейнер DRF; остальное отправляется в Vue - в том же домене. В таком случае вам также необходимо обработать то, что может быть доступно / показано прошедшим проверку подлинности / не прошедшим проверку подлинности пользователям на обоих концах - например, блокировать запросы API для не прошедших проверку подлинности пользователей, перенаправлять на страницу входа в систему внутри Vue, когда API отклоняет запрос как не прошедший проверку подлинности. Хотя это может показаться большим количеством накладных расходов, это имеет смысл, когда вам нужно создавать приложения, ориентированные на клиента, или когда у вас разные клиенты. Например, если вам нужно создать API для приложения iOS, вы можете просто повторно использовать его для своего приложения web Vue.

Если вы все еще не можете решить, какой из них лучше для вас, ознакомьтесь с таблицей ниже:

  Vue с Django REST Framework HTMX с Джанго
Кривая обучения Более крутая кривая обучения. Более низкая кривая обучения.
Подход к развитию SPA (одностраничное приложение). Требуется отдельный REST API. Многостраничный подход к приложениям. Улучшает шаблоны Django с помощью возможностей AJAX.
Интерактивность Высокий уровень интерактивности. Отлично подходит для динамических и сложных пользовательских интерфейсов с обновлением данных в реальном времени. Умеренная интерактивность. Отлично подходит для добавления динамического поведения на страницы без сложности фреймворка JavaScript.
SEO-оптимизация Требует дополнительных мер по SEO, поскольку SPA изначально не являются SEO-дружественными. Улучшенная SEO-оптимизация изначально, поскольку контент обрабатывается на сервере.
Экосистема Большая экосистема — официальные основные библиотеки и сторонние плагины. Он имеет несколько расширений и может работать в паре с другими библиотеками, но экосистема гораздо меньше.
Структура кода Устоявшийся способ структурирования кода. HTMX увеличивает сложность кода Django. Поскольку он зависит от комбинации, не существует установленного способа его структурирования.
Масштабируемость Лучше подходит для крупномасштабных, сложных приложений, где важен широкий клиентский опыт или когда вы поддерживаете несколько клиентов. Больше подходит для небольших и средних по масштабу приложений, где не требуется полномасштабная сложность SPA.
Тестирование Требуются отдельные стратегии тестирования для фронтенда и бэкенда. Тестирование может быть в первую очередь сосредоточено на стороне Django с использованием стандартных инструментов тестирования Django.

Заключение

В этой статье рассказывается о различиях между разработкой приложения с использованием Vue и Django REST Framework (DRF) и HTMX и Django.

Теперь, в зависимости от ваших потребностей и предпочтений, вы можете принять более обоснованное решение о том, какую комбинацию использовать.

Выбор между Vue с REST-фреймворком Django и HTML с Django зависит от конкретных требований и целей вашего проекта, а также от опыта вашей команды разработчиков.

Вернуться на верх