Как разместить фронтенд и бэкенд?

Back4app Full Stack Application Deploy Cover

В этом уроке мы дадим исчерпывающее руководство по размещению фронтенда и бэкенда приложения.

Для этого мы разместим приложение с полным стеком на Back4app. Сначала мы поработаем над бэкендом, затем перейдем к фронтенду и, наконец, соединим эти два компонента.

Цели

К концу этой статьи вы сможете:

  • Объясните разницу между frontend и backend
  • Создайте бэкэнд с помощью решения BaaS от Back4app
  • Развертывание фронтенд-приложения в контейнерах Back4app
  • Соедините фронтенд-приложение с бэкенд-приложением

В чем разница между frontend и backend?

Бэкэнд и фронтэнд – это разделение задач при создании современных веб- и мобильных приложений. Проще всего понять их разницу, представив себе айсберг.

Бэкэнд против фронтэнда

Фронтенд (или клиентская часть) – это все, что видит и с чем взаимодействует пользователь. Фронтенды бывают разных форматов: мобильные приложения, веб-приложения, веб-интерфейсы или любые другие типы клиентов.

Эта часть приложения отвечает за UI/UX, дизайн, анимацию, графику и другие виды медиа. Клиентская часть составляет 20 % работы над проектом и является неповторяющейся.

С другой стороны, бэкэнд (или серверная часть) – это все, что не видит пользователь. Это мост между фронтендом и базой данных.

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

Она составляет около 80 % работы над проектом и часто включает в себя повторяющиеся задачи, такие как управление пользователями, аутентификация, шифрование и т. д.

В этом уроке вы узнаете, как развернуть фронтенд и бэкенд на Back4app – бесплатно! Продолжайте читать, чтобы узнать, как развернуть бэкэнд и фронтэнд.

Введение в проект

Я подготовил полностековое приложение, чтобы продемонстрировать, как развернуть фронтенд и бэкенд на Back4app.

Приложение служит простым блогом в формате markdown. Администраторы могут добавлять, редактировать и удалять статьи, а пользователи – читать их.

Итоговый проект будет выглядеть примерно так:

Back4app Full-Stack App Blog

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

Back4app Full-Stack App Architecture

Мы развернем бэкенд на Back4app, а фронтенд-приложение – на Back4app Containers. Наконец, мы соединим эти два компонента с помощью Parse SDK.

Я предлагаю вам сначала изучить это приложение, а затем проверить свои знания, развернув свои полностековые приложения.

Продолжайте читать, чтобы узнать, как разместить бэкэнд и фронтэнд.

Как разместить бэкэнд?

В этом разделе мы займемся внутренней частью приложения.

Цели

  1. Создайте приложение Back4app
  2. Определите классы базы данных
  3. Настройка ACLs/CLPs базы данных
  4. Наполните базу данных
  5. Включите приложение администратора

Создать приложение Back4app

Вам понадобится бесплатная учетная запись Back4app, чтобы следить за происходящим. Если вы еще не зарегистрированы, зарегистрируйтесь бесплатно!

Чтобы работать с Back4app, вам сначала нужно создать приложение. Когда вы авторизуетесь в Back4app, вы будете перенаправлены на страницу приложения. Нажмите на кнопку “Создать новое приложение”.

Back4app Создать приложение

Далее выберите “Backend as a Service”, поскольку мы развертываем бэкенд.

Back4app Backend as a Service

Назовите свое приложение, выберите базу данных “NoSQL” и нажмите “Создать”.

Конфигурация Back4app BaaS

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

Когда ваше приложение будет готово, перед вами откроется проводник базы данных.

Просмотр базы данных Back4app

Определить базу данных

В этом разделе мы будем работать с классами баз данных.

Нам понадобится только один класс, поскольку мы создаем простое приложение. Нажмите “Создать класс” на боковой панели, назовите его Article, оставьте все остальное по умолчанию и нажмите “Создать класс и добавить столбцы”.

Back4app Создать класс базы данных

Добавьте к нему следующие пять столбцов:

+-----------+--------------+----------------+----------+
| Data type | Name         | Default value  | Required |
+-----------+--------------+----------------+----------+
| String    | slug         | <leave blank>  | 1        |
+-----------+--------------+----------------+----------+
| String    | title        | <leave blank>  | 1        |
+-----------+--------------+----------------+----------+
| File      | cover        | <leave blank>  | 0        |
+-----------+--------------+----------------+----------+
| String    | shortContent | <leave blank>  | 1        |
+-----------+--------------+----------------+----------+
| String    | content      | <leave blank>  | 1        |
+-----------+--------------+----------------+----------+

Не забудьте добавить столбцы для дополнительных данных, которые вы хотите хранить.

По умолчанию классы баз данных находятся в “Защищенном режиме”. Если мы хотим взаимодействовать с ними из нашего внешнего приложения, нам нужно немного изменить разрешения на уровне класса (CLP). Нажмите на значок замка в верхней части экрана и измените CLP следующим образом:

Back4app Class CLPs

Ознакомьтесь со следующей статьей, чтобы узнать больше о Parse Security.

Наконец, заполните базу данных примерами статей.

Если у вас нет никаких идей, не стесняйтесь импортировать этот дамп базы данных. Чтобы импортировать его, нажмите на опцию “Больше” в правом верхнем углу экрана, затем “Импорт > Данные класса”, а затем импортируйте JSON.

База данных Back4app заполнена

Превосходно, вот и все!

Теперь у нас есть тестовые данные для работы.

Приложение администратора

В настоящее время единственным способом управления статьями является просмотр базы данных Back4app. Это не оптимальный вариант, поскольку вы не хотите делиться своими учетными данными Back4app или добавлять в панель Back4app людей, не являющихся специалистами в этой области.

К счастью, Back4app поставляется с динамическим интерфейсом администратора для ваших моделей баз данных. Чтобы включить его, выберите “More > Admin App” на боковой панели, а затем нажмите “Enable Admin App”.

Back4app Включить приложение администратора

Выберите имя пользователя, пароль и поддомен для приложения admin. Я выбираю:

username:     admin
password:     verystrongpassword123
admin url:    https://fullstack.admin.back4app.com/

Теперь вы можете получить доступ к своей панели администратора по выбранному URL-адресу администратора.

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

Приборная панель приложения Back4app Admin

Узнайте больше о приложении администратора Back4app, просмотрев документацию.

Мы успешно создали полноценный бэкэнд без единого кода.

Как разместить фронтенд?

В этом разделе мы займемся фронтенд-приложением.

Цели

  1. Создайте локальную среду разработки
  2. Докеризация приложения
  3. Протестируйте образы Docker локально
  4. Разместите исходный код на GitHub
  5. Разверните приложение в контейнерах Back4app Containers

Локальная настройка

Начните с форка всех веток этого репозитория, а затем клонируйте форк на свою локальную машину:

$ git clone <fork_remote_git_url> --branch dummy
$ cd back4app-heroku-deploy && git branch -m master

Мы клонировали фиктивную ветку, потому что она не содержит код бэкенда. Мы поработаем над кодом бэкенда в следующем разделе.

Затем установите зависимости проекта:

$ npm install

Наконец, запустите сервер разработки:

$ npm run dev

Откройте свой любимый веб-браузер и перейдите по адресу http://localhost:3000. Вы должны увидеть индексную страницу блога. Попробуйте щелкнуть по статье и посмотреть, не переадресует ли вас на страницу с описанием статьи.

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

Dockerize

Чтобы развернуть приложение в Back4app Containers, его нужно сначала докеризировать.

Докеризация – это процесс упаковки кода в контейнер, который можно развернуть в любом месте. Самый простой способ докеризации приложения – это использование Dockerfile.

Dockerfile

Сценарий Dockerfile содержит инструкции по созданию образа контейнера Docker. С помощью этого файла можно определить окружение, установить зависимости и выполнить команды, необходимые для сборки и запуска приложения.

Создайте в корне проекта файл Dockerfile со следующим содержимым:

# Dockerfile

FROM node:18-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY . .

RUN npm run build
RUN npm install -g next

EXPOSE 3000

CMD ["next", "start", "-p", "3000"]

Этот Dockerfile основан на образе node:18-alpine. Он устанавливает рабочий каталог, обрабатывает зависимости, копирует проект и собирает приложение.

Когда приложение создано, оно открывает порт 3000 и запускает сервер Next.js, слушающий этот порт.

Чтобы узнать больше о Dockerfiles, ознакомьтесь с официальной документацией.

.dockerignore

Размер образа Docker должен быть минимальным. Самый простой способ уменьшить размер образа Docker – создать файл .dockerignore. Этот файл позволяет указать, какие файлы и папки должны быть исключены из конечного образа.

Например, вы не хотите включать в образ файлы IDE, сборки, .git или node_modules.

Вот пример файла .dockerignore, который вы можете использовать:

# .dockerignore

.idea/

/node_modules
/.next/
/out/
/build

.vercel

Убедитесь, что вы изменили файл .dockerignore в соответствии с вашими потребностями.

Сборка, запуск, тестирование

Всегда полезно протестировать свой проект Docker локально, прежде чем отправлять его в облако. Самый простой способ протестировать Docker-проект – установить Docker Desktop.

После установки вы можете создать свой образ:

$ docker build -t blog-frontend:1.0 .

Перечислите изображения, чтобы узнать, успешно ли создано изображение:

$ docker images

REPOSITORY        TAG       IMAGE ID       CREATED             SIZE
blog-frontend     1.0       d361534a68da   2 minutes ago       1.08GB

Запустите контейнер, используя только что созданный образ:

$ docker run -p 3000:3000 --name blog-frontend blog-frontend:1.0

Откройте ваш любимый веб-браузер и перейдите на сайт http://localhost:3000. Ваше приложение должно быть там!

Чтобы завершить работу контейнера, нажмите CTRL + c на клавиатуре.

Отправить на GitHub

Back4pp Containers тесно интегрирован с GitHub. Он обеспечивает автоматическую систему CI/CD, которая переразвертывает ваше приложение при каждом коммите. Чтобы развернуть ваш код в следующем разделе, вы должны сначала отправить изменения в VCS.

Зафиксируйте все изменения и отправьте их в облако:

$ git add .
$ git commit -m "dockerized the application"
$ git push origin master

Перейдите в репозиторий GitHub и убедитесь, что Dockerfile присутствует в репозитории.

Развернуть приложение

Вам понадобится бесплатная учетная запись Back4app, чтобы следить за происходящим. Если вы еще не зарегистрированы, зарегистрируйтесь бесплатно!

Для начала перейдите на панель Back4app и нажмите “Создать новое приложение”.

Back4app Создать приложение

Поскольку мы развертываем докерное приложение, выберите “Контейнеры как сервис”.

Back4app Select CaaS

Если вы впервые используете Back4app Containers, вам будет предложено подключить ваш аккаунт GitHub к аккаунту Back4app. Убедитесь, что вы включили доступ ко всем репозиториям, которые вы хотите развернуть.

Далее найдите репозиторий back4app-full-stack и выберите его, нажав кнопку “Выбрать”.

Репозиторий Back4app Select GitHub

Приложение, которое мы развертываем, не требует особой настройки. Все, что вам нужно сделать, это указать описательное “Имя приложения”. Я буду использовать back4app-full-stack, чтобы все было упорядочено.

И наконец, нажмите кнопку “Развернуть”.

Окружение контейнеров Back4app

Back4app Containers потребуется несколько минут, чтобы собрать и развернуть ваш образ Docker. После успешного развертывания статус вашего приложения изменится на “Готово”.

Чтобы перейти к своему приложению, нажмите на зеленый URL-адрес, как показано на рисунке ниже.

Успешное развертывание Back4app

Отлично, вы успешно развернули фиктивное фронтенд-приложение в Back4app Containers.

Как подключить фронтенд к бэкенду?

В этом разделе мы подключим наш фронтенд к бэкенду Back4app.

Цели

  1. Установите Parse SDK
  2. Настройка Parse SDK
  3. Получение данных (например, с помощью ParseQuery)

Установите Parse SDK

Сначала установите Parse SDK:

$ npm install parse

Настройка Parse SDK

Чтобы инициализировать Parse SDK, вам необходимо предоставить “ID приложения” и “JavaScript-ключ” Back4app. Чтобы получить их, перейдите в свое приложение Back4app и выберите “Настройки приложения > Безопасность и ключи” на боковой панели.

Поскольку мы не хотим раскрывать эти секреты в исходном коде, создайте файл .env.local:

# .env.local

NEXT_PUBLIC_PARSE_APPLICATION_ID=<your_parse_app_id>
NEXT_PUBLIC_PARSE_JAVASCRIPT_KEY=<your_parse_js_key>

Убедитесь, что вы заменили простановки на реальные значения.

Инициализация Parse SDK

Далее перейдите в файл providers.js и инициализируйте Parse следующим образом:

// src/app/providers.js

// ...

import Parse from "parse/dist/parse";

const PARSE_APPLICATION_ID = process.env.NEXT_PUBLIC_PARSE_APPLICATION_ID;
const PARSE_JAVASCRIPT_KEY = process.env.NEXT_PUBLIC_PARSE_JAVASCRIPT_KEY;
Parse.initialize(PARSE_APPLICATION_ID, PARSE_JAVASCRIPT_KEY);
Parse.serverURL = "https://parseapi.back4app.com/";

export function Providers({children}) {
    return (
        // ...
    );
}

Чтобы иметь возможность обращаться к экземпляру Parse во всех наших представлениях. Мы будем использовать контекст React.

Создайте новый файл с именем context/parseContext.js и вставьте в него следующий код:

// src/app/context/parseContext.js

"use client";

import {createContext} from "react";

const ParseContext = createContext();

export default ParseContext;

Затем оберните все приложение в ParseContext и предоставьте ему экземпляр Parse:

// src/app/providers.js

// ...

import ParseContext from "@/app/context/parseContext";

export function Providers({children}) {
  return (
    <CacheProvider>
      <ColorModeScript initialColorMode={theme.config.initialColorMode} />
      <ChakraProvider theme={theme}>
        <ParseContext.Provider value={Parse}>
          {children}
        </ParseContext.Provider>
      </ChakraProvider>
    </CacheProvider>
  );
}

Вот и все! Теперь мы можем получить доступ к экземпляру Parse с помощью хука useContext().

Получение данных

Последнее, что нам нужно сделать, это получить данные из бэкенда. Для этого мы воспользуемся Parse.Query. Этот класс, по сути, является ORM для баз данных на основе Parse.

Сначала замените файл src/app/page.jsx на следующий:

// src/app/page.jsx

"use client";

import NextLink from "next/link";
import {useContext, useEffect, useState} from "react";
import ParseContext from "@/app/context/parseContext";
import {Card, CardBody, Heading, Link, Spinner, Stack, Text} from "@chakra-ui/react";

export default function Home() {

  const parse = useContext(ParseContext);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");

  const [articles, setArticles] = useState([]);

  useEffect(() => {
    (async () => {
      try {
        const query = new parse.Query("Article");
        query.descending("createdAt");
        const articles = await query.find();
        setArticles(articles);
      } catch (error) {
        setError(error);
      } finally {
        setLoading(false);
      }
    })();
  }, [parse.Query]);

  if (loading) {
    return <Spinner size="lg"/>;
  }

  if (error) {
    return <Text color="red">{error}</Text>;
  }

  return (
    <>
      <Stack>
        {articles.map((article) => (
          <Card key={article.get("slug")}>
            <CardBody>
              <Stack>
                <Heading size="lg">
                  <Link as={NextLink} href={article.get("slug")}>
                    {article.get("title")}
                  </Link>
                </Heading>
                <Text>{article.get("shortContent")}</Text>
              </Stack>
            </CardBody>
          </Card>
        ))}
      </Stack>
    </>
  );
}
  1. Мы получили экземпляр Parse с помощью хука useContext().
  2. Мы создали несколько состояний, включая загрузку, ошибку и статьи.
  3. Мы использовали хук useEffect() для запуска Parse.Query при открытии страницы.
  4. Запрос Parse.Query извлекает все статьи, упорядоченные по createdAt.
  5. Мы изменили оператор return, чтобы вывести данные.

После этого замените src/app/[slug]/page.js на этот:

// src/app/[slug]/page.js

"use client";

import {formatDate} from "@/app/util/date-util";
import {useContext, useEffect, useState} from "react";
import ParseContext from "@/app/context/parseContext";
import {Card, CardBody, Heading, Image, Spinner, Stack, Text} from "@chakra-ui/react";
import ReactMarkdown from "react-markdown";
import ChakraUIRenderer from "chakra-ui-markdown-renderer";

export default function Article({params}) {

  const parse = useContext(ParseContext);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");

  const [article, setArticle] = useState(null);

  useEffect(() => {
    (async () => {
      try {
        const query = new parse.Query("Article");
        query.equalTo("slug", params.slug);
        const article = await query.first();
        if (!article) {
          setError("This article does not exist.");
        } else {
          setArticle(article);
        }
      } catch (error) {
        setError(error);
      } finally {
        setLoading(false);
      }
    })();
  }, [params.slug, parse.Query]);

  if (loading) {
    return <Spinner size="lg"/>;
  }

  if (error) {
    return <Text color="red">{error}</Text>;
  }

  return (
    <>
      {article && (
        <Stack>
          <Card>
            <CardBody>
              <Stack>
                <Heading as="h2" size="lg">{article.get("title")}</Heading>
                <Text>Posted on {formatDate(article.get("createdAt"))}</Text>
                {article.get("cover") && (
                  <Image 
                      src={article.get("cover").url()} 
                      alt={`${article.get("title")} cover`} 
                      borderRadius="lg"
                  />
                )}
                <ReactMarkdown 
                    components={ChakraUIRenderer()} 
                    children={article.get("content")} 
                    skipHtml
                />
              </Stack>
            </CardBody>
          </Card>
        </Stack>
      )}
    </>
  );
}

Мы использовали аналогичные концепции, как и в коде выше. Основное различие между этими двумя фрагментами кода заключается в том, что в данном случае мы получаем конкретную статью, а не все.

И мы закончили! Продолжайте тестировать проект локально:

$ next dev

Убедившись, что все работает, отправьте его в VCS:

$ git add .
$ git commit -m "connected the frontend with the backend"
$ git push origin master

Back4app Containers автоматически переразвернет ваше приложение с последними изменениями.

Заключение

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

Окончательный исходный код доступен в репо back4app-full-stack, и вы узнали, где размещать фронтенд и бэкенд.


Leave a reply

Your email address will not be published.