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

В этом уроке мы дадим исчерпывающее руководство по размещению фронтенда и бэкенда приложения.
Для этого мы разместим приложение с полным стеком на Back4app. Сначала мы поработаем над бэкендом, затем перейдем к фронтенду и, наконец, соединим эти два компонента.
Contents
Цели
К концу этой статьи вы сможете:
- Объясните разницу между frontend и backend
- Создайте бэкэнд с помощью решения BaaS от Back4app
- Развертывание фронтенд-приложения в контейнерах Back4app
- Соедините фронтенд-приложение с бэкенд-приложением
В чем разница между frontend и backend?
Бэкэнд и фронтэнд – это разделение задач при создании современных веб- и мобильных приложений. Проще всего понять их разницу, представив себе айсберг.

Фронтенд (или клиентская часть) – это все, что видит и с чем взаимодействует пользователь. Фронтенды бывают разных форматов: мобильные приложения, веб-приложения, веб-интерфейсы или любые другие типы клиентов.
Эта часть приложения отвечает за UI/UX, дизайн, анимацию, графику и другие виды медиа. Клиентская часть составляет 20 % работы над проектом и является неповторяющейся.
С другой стороны, бэкэнд (или серверная часть) – это все, что не видит пользователь. Это мост между фронтендом и базой данных.
Он отвечает за бизнес-логику, фоновые задачи, хранение данных, масштабирование, интеграцию со сторонними разработчиками и так далее. Несмотря на то что пользователь не может напрямую взаимодействовать с ним, он все равно сильно влияет на качество приложения.
Она составляет около 80 % работы над проектом и часто включает в себя повторяющиеся задачи, такие как управление пользователями, аутентификация, шифрование и т. д.
В этом уроке вы узнаете, как развернуть фронтенд и бэкенд на Back4app – бесплатно! Продолжайте читать, чтобы узнать, как развернуть бэкэнд и фронтэнд.
Введение в проект
Я подготовил полностековое приложение, чтобы продемонстрировать, как развернуть фронтенд и бэкенд на Back4app.
Приложение служит простым блогом в формате markdown. Администраторы могут добавлять, редактировать и удалять статьи, а пользователи – читать их.
Итоговый проект будет выглядеть примерно так:

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

Мы развернем бэкенд на Back4app, а фронтенд-приложение – на Back4app Containers. Наконец, мы соединим эти два компонента с помощью Parse SDK.
Я предлагаю вам сначала изучить это приложение, а затем проверить свои знания, развернув свои полностековые приложения.
Продолжайте читать, чтобы узнать, как разместить бэкэнд и фронтэнд.
Как разместить бэкэнд?
В этом разделе мы займемся внутренней частью приложения.
Цели
- Создайте приложение Back4app
- Определите классы базы данных
- Настройка ACLs/CLPs базы данных
- Наполните базу данных
- Включите приложение администратора
Создать приложение Back4app
Вам понадобится бесплатная учетная запись Back4app, чтобы следить за происходящим. Если вы еще не зарегистрированы, зарегистрируйтесь бесплатно!
Чтобы работать с Back4app, вам сначала нужно создать приложение. Когда вы авторизуетесь в Back4app, вы будете перенаправлены на страницу приложения. Нажмите на кнопку “Создать новое приложение”.

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

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

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

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

Добавьте к нему следующие пять столбцов:
+-----------+--------------+----------------+----------+
| 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 следующим образом:

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

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

Выберите имя пользователя, пароль и поддомен для приложения admin. Я выбираю:
username: admin
password: verystrongpassword123
admin url: https://fullstack.admin.back4app.com/
Теперь вы можете получить доступ к своей панели администратора по выбранному URL-адресу администратора.
Откройте новую вкладку и перейдите в панель администратора. Используйте свои учетные данные для входа в систему и изучите интерфейс. Вы можете создать статью, обновить ее, а затем удалить.

Узнайте больше о приложении администратора Back4app, просмотрев документацию.
Мы успешно создали полноценный бэкэнд без единого кода.
Как разместить фронтенд?
В этом разделе мы займемся фронтенд-приложением.
Цели
- Создайте локальную среду разработки
- Докеризация приложения
- Протестируйте образы Docker локально
- Разместите исходный код на GitHub
- Разверните приложение в контейнерах 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 Containers, вам будет предложено подключить ваш аккаунт GitHub к аккаунту Back4app. Убедитесь, что вы включили доступ ко всем репозиториям, которые вы хотите развернуть.
Далее найдите репозиторий back4app-full-stack и выберите его, нажав кнопку “Выбрать”.

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

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

Отлично, вы успешно развернули фиктивное фронтенд-приложение в Back4app Containers.
Как подключить фронтенд к бэкенду?
В этом разделе мы подключим наш фронтенд к бэкенду Back4app.
Цели
- Установите Parse SDK
- Настройка Parse SDK
- Получение данных (например, с помощью
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>
</>
);
}
- Мы получили экземпляр Parse с помощью хука
useContext(). - Мы создали несколько состояний, включая
загрузку,ошибкуистатьи. - Мы использовали хук
useEffect()для запускаParse.Queryпри открытии страницы. Запрос Parse.Queryизвлекает все статьи, упорядоченные поcreatedAt.- Мы изменили оператор 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, и вы узнали, где размещать фронтенд и бэкенд.

