Интеграция с backend фреймворками

Preact — легковесная библиотека для построения пользовательских интерфейсов, совместимая с экосистемой React, что упрощает интеграцию с различными backend-фреймворками. Взаимодействие между фронтендом на Preact и серверной частью осуществляется через HTTP-запросы, WebSocket или серверный рендеринг.

Архитектура взаимодействия

Интеграция с backend предполагает разделение ответственности:

  • Frontend (Preact): управление состоянием, рендеринг компонентов, обработка пользовательских событий.
  • Backend: бизнес-логика, работа с базой данных, маршрутизация и обработка API-запросов.

Для передачи данных используется REST, GraphQL или WebSocket. Ключевым моментом является стандартизация формата данных (JSON) и единая обработка ошибок.

Работа с REST API

REST является наиболее распространённым способом интеграции.

Создание запросов

Используется fetch или библиотеки вроде Axios:

import { useState, useEffect } from 'preact/hooks';

function UsersList() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch('/api/users')
      .then(response => response.json())
      .then(data => {
        setUsers(data);
        setLoading(false);
      })
      .catch(error => {
        console.error('Ошибка загрузки пользователей:', error);
        setLoading(false);
      });
  }, []);

  if (loading) return <p>Загрузка...</p>;
  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

Особенности:

  • Использование useEffect для асинхронной загрузки данных после монтирования компонента.
  • Управление состоянием загрузки и обработки ошибок.
  • Ключи у элементов списка (key) для оптимизации рендеринга.

Отправка данных на сервер

POST-запросы и отправка форм:

function AddUserForm() {
  const [name, setName] = useState('');

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      const response = await fetch('/api/users', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name })
      });
      const result = await response.json();
      console.log('Пользователь добавлен:', result);
    } catch (error) {
      console.error('Ошибка при добавлении пользователя:', error);
    }
  };

  return (
    <form onSub mit={handleSubmit}>
      <input value={name} onIn put={e => setName(e.target.value)} placeholder="Имя" />
      <button type="submit">Добавить</button>
    </form>
  );
}

Интеграция с GraphQL

GraphQL позволяет получать только необходимые данные и уменьшает количество запросов.

import { useState, useEffect } from 'preact/hooks';

function fetchGraphQL(query, variables = {}) {
  return fetch('/graphql', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ query, variables })
  }).then(res => res.json());
}

function ProductsList() {
  const [products, setProducts] = useState([]);

  useEffect(() => {
    const query = `
      query {
        products {
          id
          name
          price
        }
      }
    `;
    fetchGraphQL(query)
      .then(data => setProducts(data.data.products))
      .catch(console.error);
  }, []);

  return (
    <ul>
      {products.map(product => (
        <li key={product.id}>{product.name} - {product.price}</li>
      ))}
    </ul>
  );
}

Особенности:

  • Возможность точного запроса полей для уменьшения нагрузки.
  • Легкая интеграция с Preact через хуки.

WebSocket для реального времени

Для приложений с обновлениями в реальном времени (чаты, уведомления) используется WebSocket:

import { useState, useEffect } from 'preact/hooks';

function Chat() {
  const [messages, setMessages] = useState([]);
  const [input, setInput] = useState('');
  let socket;

  useEffect(() => {
    socket = new WebSocket('ws://localhost:3000/ws');

    socket.onmess age = (event) => {
      setMessages(prev => [...prev, event.data]);
    };

    return () => socket.close();
  }, []);

  const sendMessage = () => {
    socket.send(input);
    setInput('');
  };

  return (
    <div>
      <ul>
        {messages.map((msg, i) => <li key={i}>{msg}</li>)}
      </ul>
      <input value={input} onIn put={e => setInput(e.target.value)} />
      <button onCl ick={sendMessage}>Отправить</button>
    </div>
  );
}

Особенности:

  • Поддержка постоянного соединения с сервером.
  • Обработка сообщений в реальном времени.
  • Закрытие соединения при размонтировании компонента.

Серверный рендеринг с Preact

Preact поддерживает серверный рендеринг через preact-render-to-string, что улучшает SEO и ускоряет первичный рендер:

import { h } from 'preact';
import render from 'preact-render-to-string';
import App from './App';

const html = render(<App />);

На стороне backend это позволяет отправлять полностью готовую HTML-страницу, а на фронтенде Preact берет на себя гидратацию интерактивности.

Интеграция с популярными backend-фреймворками

  • Express.js: маршрутизация и обработка REST/GraphQL API, интеграция через middleware.
  • NestJS: строгая архитектура, поддержка GraphQL, WebSocket и REST из коробки.
  • Django/Flask (Python): API через Django REST Framework или Flask-RESTful, Preact выступает клиентом.
  • Rails: JSON API для передачи данных, Preact как SPA-фронтенд.

Ключевые моменты:

  • Определение четких контрактов API.
  • Обработка CORS и авторизации.
  • Поддержка асинхронных операций и ошибок.

Оптимизация взаимодействия

  • Кэширование данных на клиенте с помощью SWR или React Query.
  • Дебаунсинг и троттлинг запросов при вводе данных.
  • Минимизация количества запросов через GraphQL или пакетирование REST-запросов.
  • Обработка ошибок и fallback UI для повышения устойчивости приложения.

Заключение

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