كيفية استضافة الواجهة الأمامية والخلفية؟
سنقدم في هذا البرنامج التعليمي دليلاً شاملاً حول استضافة الواجهة الأمامية والخلفية للتطبيق.
لهذا الغرض، سنقوم باستضافة تطبيق كامل المكدس على Back4app. سنعمل أولًا على الواجهة الخلفية، ثم ننتقل إلى الواجهة الأمامية، وأخيرًا، سنقوم بربط المكونين.
Contents
الأهداف
بحلول نهاية هذه المقالة، ستكون قادراً على:
- شرح الفروق بين الواجهة الأمامية والخلفية
- إنشاء واجهة خلفية باستخدام حل Back4app’s BaaS من Back4app
- نشر تطبيق واجهة أمامية على حاويات Back4app
- توصيل تطبيق الواجهة الأمامية بتطبيق الواجهة الخلفية
ما هي الاختلافات بين الواجهة الأمامية والخلفية؟
تشير الواجهة الخلفية والواجهة الأمامية إلى الفصل بين الاهتمامات عند إنشاء تطبيقات الويب والهاتف المحمول الحديثة. أسهل طريقة لفهم الاختلافات بينهما هي تصور جبل جليدي.
الواجهة الأمامية (أو جانب العميل) هي كل ما يمكن للمستخدم رؤيته والتفاعل معه. تأتي الواجهات الأمامية بأشكال مختلفة، مثل تطبيقات الهاتف المحمول أو تطبيقات الويب أو واجهات الويب أو أي نوع آخر من العملاء.
هذا الجزء الخاص بالتطبيق مسؤول عن واجهة المستخدم/تجربة المستخدم والتصميم والرسوم المتحركة والرسومات وأنواع الوسائط الأخرى. يشكل جانب العميل 20% من عمل المشروع وهو غير متكرر.
من ناحية أخرى، الواجهة الخلفية (أو جانب الخادم) هي كل شيء لا يمكن للمستخدم رؤيته. إنه الجسر بين الواجهة الأمامية وقاعدة البيانات.
إنه مسؤول عن منطق الأعمال ومهام الخلفية وتخزين البيانات والتوسع والتكاملات مع جهات خارجية وما إلى ذلك. على الرغم من أن المستخدم لا يستطيع التفاعل معها بشكل مباشر، إلا أنها لا تزال تؤثر بشكل كبير على جودة التطبيق.
وهو يمثل حوالي 80% من عمل المشروع وغالباً ما يتضمن مهام متكررة مثل إدارة المستخدم والمصادقة والتشفير وما إلى ذلك.
في هذا البرنامج التعليمي، ستتعلم في هذا البرنامج التعليمي كيفية نشر الواجهة الأمامية والخلفية على Back4app – مجانًا! استمر في القراءة لتتعلم كيفية نشر الواجهة الخلفية والواجهة الأمامية.
مقدمة المشروع
لقد قمت بإعداد تطبيق كامل المكدس لتوضيح كيفية نشر واجهة أمامية وخلفية على Back4app.
يعمل التطبيق كمدونة تخفيض بسيطة. يمكن للمشرفين إضافة المقالات وتعديلها وحذفها، بينما يمكن للمستخدمين قراءتها.
سيبدو المشروع النهائي بهذا الشكل:
كما ذكرنا أعلاه، يتكون التطبيق من جزأين: الواجهة الأمامية والخلفية. إذا تصورنا بنية التطبيق، فسيبدو كالتالي:
سننشر الواجهة الخلفية في Back4app وتطبيق الواجهة الأمامية في حاويات Back4app. وأخيرًا، سنقوم بربط المكونين عبر Parse SDK.
أقترح أن تتابع هذا التطبيق أولاً ثم تختبر معرفتك لاحقاً من خلال نشر تطبيقاتك كاملة المكدس.
استمر في القراءة لمعرفة كيفية استضافة الواجهة الخلفية والواجهة الأمامية.
كيف تستضيف خلفية؟
في هذا القسم، سنهتم في هذا القسم بالجزء الخلفي من التطبيق.
الأهداف
- إنشاء تطبيق Back4app
- تعريف فئات قاعدة البيانات
- إعداد ACLs/CLPs لقاعدة البيانات
- ملء قاعدة البيانات
- تمكين تطبيق المسؤول
إنشاء تطبيق Back4app
ستحتاج إلى حساب مجاني على Back4app لمتابعة الأمر. إذا لم تكن مسجلاً، اشترك مجاناً!
للعمل مع Back4app، عليك أولاً إنشاء تطبيق. عندما تقوم بالمصادقة على Back4app، ستتم إعادة توجيهك إلى عرض التطبيق. انقر على زر “إنشاء تطبيق جديد”.
بعد ذلك، حدد “الواجهة الخلفية كخدمة” بما أننا ننشر واجهة خلفية.
قم بتسمية تطبيقك، واختر قاعدة بيانات “NoSQL”، وانقر على “إنشاء”.
ستستغرق المنصة بعض الوقت لإعداد كل شيء (على سبيل المثال، قاعدة البيانات، والتوسع، والنسخ الاحتياطية، وطبقة التطبيق). لا تتردد في أخذ استراحة قصيرة لتناول القهوة في هذه الأثناء.
بمجرد أن يصبح تطبيقك جاهزاً، سيظهر لك مستكشف قاعدة البيانات.
تعريف قاعدة البيانات
في هذا القسم، سنعمل على فئات قاعدة البيانات.
سنحتاج إلى فصل واحد فقط بما أننا نبني تطبيقًا بسيطًا. انقر على “إنشاء صنف” على الشريط الجانبي، وأطلق عليه اسم "مقالة
“، واترك كل شيء آخر على أنه افتراضي، وانقر على “إنشاء صنف وإضافة أعمدة”.
أضف الأعمدة الخمسة التالية إليها:
+-----------+--------------+----------------+----------+
| 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 |
+-----------+--------------+----------------+----------+
تأكد من إضافة أعمدة للبيانات الإضافية التي ترغب في تخزينها.
بشكل افتراضي، تكون فئات قاعدة البيانات في “الوضع المحمي”. إذا أردنا التفاعل معها من تطبيق الواجهة الأمامية لدينا، فعلينا تعديل أذونات مستوى الفئة (CLPs) قليلاً. انقر على أيقونة القفل في الجزء العلوي من الشاشة وقم بتعديل CLPs على هذا النحو:
راجع المقالة التالية لمعرفة المزيد عن Parse Security.
وأخيراً، قم بتعبئة قاعدة البيانات ببعض نماذج المقالات.
إذا لم تكن لديك أي أفكار، فلا تتردد في استيراد تفريغ قاعدة البيانات هذه. لاستيرادها، انقر على خيار المزيد في أعلى يمين الشاشة ثم “استيراد > بيانات الفئة”، ثم قم باستيراد JSON.
ممتاز، هذا كل شيء!
لدينا الآن بعض بيانات الاختبار للعمل عليها.
التطبيق الإداري
في الوقت الحالي، الطريقة الوحيدة لإدارة المقالات هي عبر عرض قاعدة بيانات Back4app. هذا ليس مثاليًا لأنك لا تريد مشاركة بيانات اعتماد Back4app الخاصة بك أو إضافة أشخاص غير تقنيين إلى لوحة معلومات Back4app.
لحسن الحظ، يأتي تطبيق Back4app مزودًا بواجهة مسؤول ديناميكية لنماذج قاعدة البيانات الخاصة بك. لتمكينها، حدد “المزيد > تطبيق المسؤول” على الشريط الجانبي، ثم انقر على “تمكين تطبيق المسؤول”.
اختر اسم مستخدم وكلمة مرور ونطاق فرعي لتطبيق المسؤول. سأختار
username: admin
password: verystrongpassword123
admin url: https://fullstack.admin.back4app.com/
يمكنك الآن الوصول إلى لوحة الإدارة الخاصة بك على عنوان URL المسؤول المحدد.
افتح علامة تبويب جديدة وانتقل إلى لوحة الإدارة. استخدم بيانات اعتمادك لتسجيل الدخول واستكشاف الواجهة. يمكنك إنشاء مقالة وتحديثها ثم حذفها.
تعرّف على المزيد حول تطبيق Back4app Admin من خلال الاطلاع على المستندات.
لقد نجحنا في إنشاء واجهة خلفية كاملة بدون كود برمجي.
كيف تستضيف واجهة أمامية؟
في هذا القسم، سنهتم في هذا القسم بتطبيق الواجهة الأمامية.
الأهداف
- إعداد بيئة تطوير محلية
- إرساء التطبيق
- اختبر صور 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، يجب عليك أولاً أن تقوم بإرساء التطبيق على حاويات Back4app.
Dockerization هي عملية تعبئة الشيفرة البرمجية في حاوية يمكن نشرها في أي مكان. أسهل طريقة لإرساء تطبيق ما هي استخدام ملف 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 محليًا قبل دفعه إلى السحابة. أسهل طريقة لاختبار ملف Dockerfile الخاص بك هي تثبيت 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، سيُطلب منك ربط حساب GitHub الخاص بك بحساب Back4app الخاص بك. تأكد من تمكين الوصول إلى جميع المستودعات التي ترغب في نشرها.
بعد ذلك، ابحث عن مستودع back4app-full-stack
repository وحدده بالنقر على “تحديد”.
لا يتطلب التطبيق الذي ننشره أي تهيئة خاصة. كل ما عليك فعله هو توفير “اسم تطبيق” وصفي. سأستخدم back4app-full-stack
للحفاظ على تنظيم الأمور.
وأخيراً، انقر فوق “نشر”.
ستستغرق حاويات Back4app Containers بضع دقائق لبناء ونشر صورة Docker الخاصة بك. ستتغير حالة تطبيقك إلى “جاهز” بمجرد نشره بنجاح.
لزيارة تطبيقك، انقر على عنوان URL الأخضر كما هو موضح في الصورة أدناه.
رائع، لقد نجحت في نشر تطبيق واجهة أمامية وهمي على حاويات Back4app.
كيفية توصيل الواجهة الأمامية بالواجهة الخلفية؟
في هذا القسم، سنقوم بتوصيل الواجهة الأمامية بالواجهة الخلفية لتطبيق Back4app.
الأهداف
- تثبيت Parse SDK
- تكوين Parse SDK
- جلب البيانات (على سبيل المثال، باستخدام
ParseQuery
)
تثبيت Parse SDK
أولاً، قم بتثبيت Parse SDK:
$ npm install parse
تكوين Parse SDK
لتهيئة Parse SDK، سيتعين عليك تقديم “معرّف تطبيق 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
بعد ذلك، انتقل إلى موفريك.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.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.Query
عند فتح الصفحة. - يجلب
استعلام Parse.Query.Query
جميع المقالات مرتبة حسبتاريخ الإنشاء
. - قمنا بتعديل عبارة الإرجاع لعرض البيانات.
بعد ذلك استبدل 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-ful-stack وتعلمت أين تستضيف الواجهة الأمامية والخلفية.