كيفية استضافة الواجهة الأمامية والخلفية؟

غطاء نشر تطبيقات Back4app كامل المكدس Back4app كامل المكدس

سنقدم في هذا البرنامج التعليمي دليلاً شاملاً حول استضافة الواجهة الأمامية والخلفية للتطبيق.

لهذا الغرض، سنقوم باستضافة تطبيق كامل المكدس على Back4app. سنعمل أولًا على الواجهة الخلفية، ثم ننتقل إلى الواجهة الأمامية، وأخيرًا، سنقوم بربط المكونين.

الأهداف

بحلول نهاية هذه المقالة، ستكون قادراً على:

  • شرح الفروق بين الواجهة الأمامية والخلفية
  • إنشاء واجهة خلفية باستخدام حل Back4app’s BaaS من Back4app
  • نشر تطبيق واجهة أمامية على حاويات Back4app
  • توصيل تطبيق الواجهة الأمامية بتطبيق الواجهة الخلفية

ما هي الاختلافات بين الواجهة الأمامية والخلفية؟

تشير الواجهة الخلفية والواجهة الأمامية إلى الفصل بين الاهتمامات عند إنشاء تطبيقات الويب والهاتف المحمول الحديثة. أسهل طريقة لفهم الاختلافات بينهما هي تصور جبل جليدي.

الواجهة الخلفية مقابل الواجهة الأمامية

الواجهة الأمامية (أو جانب العميل) هي كل ما يمكن للمستخدم رؤيته والتفاعل معه. تأتي الواجهات الأمامية بأشكال مختلفة، مثل تطبيقات الهاتف المحمول أو تطبيقات الويب أو واجهات الويب أو أي نوع آخر من العملاء.

هذا الجزء الخاص بالتطبيق مسؤول عن واجهة المستخدم/تجربة المستخدم والتصميم والرسوم المتحركة والرسومات وأنواع الوسائط الأخرى. يشكل جانب العميل 20% من عمل المشروع وهو غير متكرر.

من ناحية أخرى، الواجهة الخلفية (أو جانب الخادم) هي كل شيء لا يمكن للمستخدم رؤيته. إنه الجسر بين الواجهة الأمامية وقاعدة البيانات.

إنه مسؤول عن منطق الأعمال ومهام الخلفية وتخزين البيانات والتوسع والتكاملات مع جهات خارجية وما إلى ذلك. على الرغم من أن المستخدم لا يستطيع التفاعل معها بشكل مباشر، إلا أنها لا تزال تؤثر بشكل كبير على جودة التطبيق.

وهو يمثل حوالي 80% من عمل المشروع وغالباً ما يتضمن مهام متكررة مثل إدارة المستخدم والمصادقة والتشفير وما إلى ذلك.

في هذا البرنامج التعليمي، ستتعلم في هذا البرنامج التعليمي كيفية نشر الواجهة الأمامية والخلفية على Back4app – مجانًا! استمر في القراءة لتتعلم كيفية نشر الواجهة الخلفية والواجهة الأمامية.

مقدمة المشروع

لقد قمت بإعداد تطبيق كامل المكدس لتوضيح كيفية نشر واجهة أمامية وخلفية على Back4app.

يعمل التطبيق كمدونة تخفيض بسيطة. يمكن للمشرفين إضافة المقالات وتعديلها وحذفها، بينما يمكن للمستخدمين قراءتها.

سيبدو المشروع النهائي بهذا الشكل:

مدونة تطبيق Back4app كامل المكدس

كما ذكرنا أعلاه، يتكون التطبيق من جزأين: الواجهة الأمامية والخلفية. إذا تصورنا بنية التطبيق، فسيبدو كالتالي:

بنية تطبيقات Back4app كاملة المكدس

سننشر الواجهة الخلفية في Back4app وتطبيق الواجهة الأمامية في حاويات Back4app. وأخيرًا، سنقوم بربط المكونين عبر Parse SDK.

أقترح أن تتابع هذا التطبيق أولاً ثم تختبر معرفتك لاحقاً من خلال نشر تطبيقاتك كاملة المكدس.

استمر في القراءة لمعرفة كيفية استضافة الواجهة الخلفية والواجهة الأمامية.

كيف تستضيف خلفية؟

في هذا القسم، سنهتم في هذا القسم بالجزء الخلفي من التطبيق.

الأهداف

  1. إنشاء تطبيق Back4app
  2. تعريف فئات قاعدة البيانات
  3. إعداد ACLs/CLPs لقاعدة البيانات
  4. ملء قاعدة البيانات
  5. تمكين تطبيق المسؤول

إنشاء تطبيق Back4app

ستحتاج إلى حساب مجاني على Back4app لمتابعة الأمر. إذا لم تكن مسجلاً، اشترك مجاناً!

للعمل مع Back4app، عليك أولاً إنشاء تطبيق. عندما تقوم بالمصادقة على Back4app، ستتم إعادة توجيهك إلى عرض التطبيق. انقر على زر “إنشاء تطبيق جديد”.

Back4app إنشاء تطبيق Back4app Create App

بعد ذلك، حدد “الواجهة الخلفية كخدمة” بما أننا ننشر واجهة خلفية.

Back4app Back4app Back4app كخدمة

قم بتسمية تطبيقك، واختر قاعدة بيانات “NoSQL”، وانقر على “إنشاء”.

تكوين Back4app BaaS Back4app BaaS

ستستغرق المنصة بعض الوقت لإعداد كل شيء (على سبيل المثال، قاعدة البيانات، والتوسع، والنسخ الاحتياطية، وطبقة التطبيق). لا تتردد في أخذ استراحة قصيرة لتناول القهوة في هذه الأثناء.

بمجرد أن يصبح تطبيقك جاهزاً، سيظهر لك مستكشف قاعدة البيانات.

عرض قاعدة بيانات Back4app Back4app

تعريف قاعدة البيانات

في هذا القسم، سنعمل على فئات قاعدة البيانات.

سنحتاج إلى فصل واحد فقط بما أننا نبني تطبيقًا بسيطًا. انقر على “إنشاء صنف” على الشريط الجانبي، وأطلق عليه اسم "مقالة“، واترك كل شيء آخر على أنه افتراضي، وانقر على “إنشاء صنف وإضافة أعمدة”.

Back4app إنشاء فئة إنشاء قاعدة بيانات 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        |
+-----------+--------------+----------------+----------+

تأكد من إضافة أعمدة للبيانات الإضافية التي ترغب في تخزينها.

بشكل افتراضي، تكون فئات قاعدة البيانات في “الوضع المحمي”. إذا أردنا التفاعل معها من تطبيق الواجهة الأمامية لدينا، فعلينا تعديل أذونات مستوى الفئة (CLPs) قليلاً. انقر على أيقونة القفل في الجزء العلوي من الشاشة وقم بتعديل CLPs على هذا النحو:

Back4app Class CLPs فئة CLPs

راجع المقالة التالية لمعرفة المزيد عن Parse Security.

وأخيراً، قم بتعبئة قاعدة البيانات ببعض نماذج المقالات.

إذا لم تكن لديك أي أفكار، فلا تتردد في استيراد تفريغ قاعدة البيانات هذه. لاستيرادها، انقر على خيار المزيد في أعلى يمين الشاشة ثم “استيراد > بيانات الفئة”، ثم قم باستيراد JSON.

تم ملء قاعدة بيانات Back4app

ممتاز، هذا كل شيء!

لدينا الآن بعض بيانات الاختبار للعمل عليها.

التطبيق الإداري

في الوقت الحالي، الطريقة الوحيدة لإدارة المقالات هي عبر عرض قاعدة بيانات Back4app. هذا ليس مثاليًا لأنك لا تريد مشاركة بيانات اعتماد Back4app الخاصة بك أو إضافة أشخاص غير تقنيين إلى لوحة معلومات Back4app.

لحسن الحظ، يأتي تطبيق Back4app مزودًا بواجهة مسؤول ديناميكية لنماذج قاعدة البيانات الخاصة بك. لتمكينها، حدد “المزيد > تطبيق المسؤول” على الشريط الجانبي، ثم انقر على “تمكين تطبيق المسؤول”.

تطبيق Back4app تمكين تطبيق المسؤول Back4app

اختر اسم مستخدم وكلمة مرور ونطاق فرعي لتطبيق المسؤول. سأختار

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

يمكنك الآن الوصول إلى لوحة الإدارة الخاصة بك على عنوان URL المسؤول المحدد.

افتح علامة تبويب جديدة وانتقل إلى لوحة الإدارة. استخدم بيانات اعتمادك لتسجيل الدخول واستكشاف الواجهة. يمكنك إنشاء مقالة وتحديثها ثم حذفها.

لوحة تحكم تطبيق Back4app Admin App Admin Dashboard

تعرّف على المزيد حول تطبيق Back4app Admin من خلال الاطلاع على المستندات.

لقد نجحنا في إنشاء واجهة خلفية كاملة بدون كود برمجي.

كيف تستضيف واجهة أمامية؟

في هذا القسم، سنهتم في هذا القسم بتطبيق الواجهة الأمامية.

الأهداف

  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، يجب عليك أولاً أن تقوم بإرساء التطبيق على حاويات 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 الخاصة بك وانقر على “إنشاء تطبيق جديد”.

باك4آب إنشاء تطبيق باك4آب

بما أننا ننشر تطبيقاً مرسى، اختر “الحاويات كخدمة”.

Back4app Select CaaS

إذا كانت هذه هي المرة الأولى التي تستخدم فيها حاويات Back4app، سيُطلب منك ربط حساب GitHub الخاص بك بحساب Back4app الخاص بك. تأكد من تمكين الوصول إلى جميع المستودعات التي ترغب في نشرها.

بعد ذلك، ابحث عن مستودع back4app-full-stack repository وحدده بالنقر على “تحديد”.

مستودع GitHub Back4app Select GitHub

لا يتطلب التطبيق الذي ننشره أي تهيئة خاصة. كل ما عليك فعله هو توفير “اسم تطبيق” وصفي. سأستخدم back4app-full-stack للحفاظ على تنظيم الأمور.

وأخيراً، انقر فوق “نشر”.

بيئة حاويات Back4app Back4app Containers

ستستغرق حاويات Back4app Containers بضع دقائق لبناء ونشر صورة Docker الخاصة بك. ستتغير حالة تطبيقك إلى “جاهز” بمجرد نشره بنجاح.

لزيارة تطبيقك، انقر على عنوان URL الأخضر كما هو موضح في الصورة أدناه.

النشر الناجح لتطبيق Back4app Back4app

رائع، لقد نجحت في نشر تطبيق واجهة أمامية وهمي على حاويات Back4app.

كيفية توصيل الواجهة الأمامية بالواجهة الخلفية؟

في هذا القسم، سنقوم بتوصيل الواجهة الأمامية بالواجهة الخلفية لتطبيق Back4app.

الأهداف

  1. تثبيت Parse SDK
  2. تكوين Parse SDK
  3. جلب البيانات (على سبيل المثال، باستخدام 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>
    </>
  );
}
  1. حصلنا على مثيل Parse من خلال خطاف useContext().
  2. أنشأنا بعض الحالات، بما في ذلك التحميل والخطأ والمقالات.
  3. استخدمنا خطاف useEffect() لتشغيل Parse.Query.Query عند فتح الصفحة.
  4. يجلب استعلام Parse.Query.Query جميع المقالات مرتبة حسب تاريخ الإنشاء.
  5. قمنا بتعديل عبارة الإرجاع لعرض البيانات.

بعد ذلك استبدل 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 وتعلمت أين تستضيف الواجهة الأمامية والخلفية.


Leave a reply

Your email address will not be published.