Как разместить фронтенд и бэкенд?
В этом уроке мы дадим исчерпывающее руководство по размещению фронтенда и бэкенда приложения.
Для этого мы разместим приложение с полным стеком на 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, и вы узнали, где размещать фронтенд и бэкенд.