Window.pipedriveLeadboosterConfig = { القاعدة: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', الإصدار: 2, } ؛(الدالة () { var w = نافذة إذا كان (w.LeadBooster) { console.warn('LeadBooster موجود بالفعل') } وإلا { { w.LeadBooster = { q: [], على: دالة (ن، ح) { { هذا.q.push({ t: 'o'، n: n، n: n، h: h }) }, الزناد: الدالة (n) { هذا.q.push({ t: 't'، n: n: n }) }, } } })() نشر واجهة برمجة تطبيقات GraphQL/منغودب باستخدام وظائف Netlify - The Codest
The Codest
  • نبذة عنا
  • الخدمات
    • تطوير البرمجيات
      • تطوير الواجهة الأمامية
      • تطوير الواجهة الخلفية
    • Staff Augmentation
      • مطورو الواجهة الأمامية
      • مطورو الواجهة الخلفية
      • مهندسو البيانات
      • مهندسو السحابة
      • مهندسو ضمان الجودة
      • أخرى
    • استشاري
      • التدقيق والاستشارات
  • الصناعات
    • التكنولوجيا المالية والمصرفية
    • E-commerce
    • أدتك
    • التكنولوجيا الصحية
    • التصنيع
    • الخدمات اللوجستية
    • السيارات
    • إنترنت الأشياء
  • القيمة مقابل
    • CEO
    • CTO
    • مدير التوصيل
  • فريقنا
  • دراسات الحالة
  • اعرف كيف
    • المدونة
    • اللقاءات
    • ندوات عبر الإنترنت
    • الموارد
الوظائف تواصل معنا
  • نبذة عنا
  • الخدمات
    • تطوير البرمجيات
      • تطوير الواجهة الأمامية
      • تطوير الواجهة الخلفية
    • Staff Augmentation
      • مطورو الواجهة الأمامية
      • مطورو الواجهة الخلفية
      • مهندسو البيانات
      • مهندسو السحابة
      • مهندسو ضمان الجودة
      • أخرى
    • استشاري
      • التدقيق والاستشارات
  • القيمة مقابل
    • CEO
    • CTO
    • مدير التوصيل
  • فريقنا
  • دراسات الحالة
  • اعرف كيف
    • المدونة
    • اللقاءات
    • ندوات عبر الإنترنت
    • الموارد
الوظائف تواصل معنا
السهم الخلفي العودة إلى الوراء
2021-05-13
تطوير البرمجيات

نشر واجهة برمجة تطبيقات GraphQL/منغودب باستخدام وظائف Netlify

The Codest

بافيل ريبشينسكي

Software Engineer

الأهداف الإعداد الأولي الإعداد الأولي تثبيت التبعيات لنبدأ أولاً، أضف tsconfig.json إلى الدليل الرئيسي: الآن، لننشئ src/server.ts لتطبيقات الخوادم. ثم أضف دالتين: واحدة للخادم المحلي والثانية للامبدا. حسنًا، ليس لدينا أي محاليل أو تعريفات للنوع لذا نحتاج إلى إنشاء بعضها. لنفترض أننا في البداية نريد [...].

الأهداف

  1. تكوين كل من الخوادم المحلية وخوادم لامدا.
  2. قم بتوصيل كليهما بـ MongoDB.
  3. تنفيذ المصادقة الأساسية.
  4. نشر أبولو بدون خادم GraphQL واجهة برمجة التطبيقات (API) مع Netlify.
  5. استخدام النص المكتوب.

الإعداد الأولي

npm init -y

تثبيت التبعيات

npm install -حفظ المخطوطة النوعية Graphql aws-lambda @types/aws-lambda

لنبدأ

أولاً، أضف أولاً tsconfig.json إلى الدليل الرئيسي:

{
 "compilerOptions": {
 "target": "es5",
 "الوحدة النمطية": "commonjs",
 "allowJs": صحيح
 "صارم": صحيح
 "esModuleInterop": صحيح
 "skipLibCheck": صحيح,
 "forceConsistentConsasingInFileNames": صحيح
 },
 "تضمين": ["src/*.ts", "src/***.ts", "src/***.ts", "src/***.js"],
 "استبعاد": ["node_modules"]
 }

والآن، دعنا ننشئ src/server.ts لتطبيقات الخوادم. ثم أضف دالتين: واحدة للخادم المحلي والثانية للامبدا.

// src/server.ts
استيراد { ApolloServer باسم ApolloServerLambda } من "Apollo-server-lambda";
استيراد { ApolloServer } من "Apollo-server-server";


const createLambdaServer = () =>
  جديد ApolloServerLambda({ {
    typeDefs,
    المحللات
    الاستبطان: صحيح
    الملعب: صحيح,
    },
  });

const createLocalServer = () =>
  خادم أبوللو سيرفر جديد({
    typeDefs,
    المحللات,
    الاستبطان: صحيح
    الملعب: صحيح,
    },
  });

تصدير { createLambdaServer, createLocalServer };

حسناً، ليس لدينا أي مُحَلِّلات أو تعريفات للنوع لذا نحتاج إلى إنشاء بعضها. لنفترض أننا في البداية نريد إنشاء مستخدمين وتلقي معلومات عنهم.

// src/schemas.ts
const { gql } = يتطلب("apollo-server-lambda");

يشكل userSchema = gql``
  اكتب مستخدم {
    المعرف: معرف!
    البريد الإلكتروني: سلسلة!
    الاسم: سلسلة!
  }

  اكتب استعلام {
    مستخدم(id: ID!): مستخدم!
  }

  اكتب طفرة {
    createUser(الاسم: سلسلة!, البريد الإلكتروني: سلسلة!, كلمة المرور: سلسلة!): مستخدم!
  }
`;

إذا لم تكن على دراية بذلك أعد أبولو برنامجاً تعليمياً رائعاً جداً

لنقم الآن بإنشاء محلل مستخدم باستعلام واحد وطفرة واحدة.

// src/resolvers.ts
const userResolver = {
  استعلام: {
    المستخدم: غير متزامن (الأصل، الحجج، السياق، المعلومات) => { {
      {...}
    },
  },
  طفرة: {
    createUser: غير متزامن (الأصل، الحجج، السياق، المعلومات) => {...} {
      {...}
    },
  },
};

لكن ليس لدينا أي بيانات... دعونا نصلح الأمر 😉

لا تنس استيراد تعريف النوع والمحلل إلى الخادم.

// src/server.ts
استيراد { ApolloServer باسم ApolloServerLambda } من "Apollo-server-lambda";
استيراد { ApolloServer } من "Apollo-server-server";

استيراد { typeDefs } من "./schemas";
استيراد { المحللات } من "./ المحللات";

{...}

التواصل مع MongoDB عبر mongoDB عبر mongoose

الآن هو الوقت المناسب لإنشاء اتصال بقاعدة بياناتنا. في هذه الحالة بالذات، ستكون MongoDB. إنه مجاني وسهل الصيانة. ولكن قبل ذلك، لنقم بتثبيت تبعيتين أخريين:

تثبيت npm -حفظ mongoose dotenv

الخطوة الأولى هي إنشاء نموذج مستخدم.

// src/model.ts
استيراد mongoose، { مستند، خطأ، مخطط } من "mongoose";

تصدير نوع المستخدم = مستند & {
  _id: سلسلة,
  البريد الإلكتروني: سلسلة,
  الاسم: سلسلة,
  كلمة المرور: سلسلة,
};

حذف mongoose.connection.models.models["المستخدم"];

const UserSchema: مخطط = مخطط جديد({
  البريد الإلكتروني: {
    النوع: سلسلة,
    مطلوب: صحيح,
    فريد: صحيح,
  },
  الاسم: {
    نوع: سلسلة,
    مطلوب: صحيح,
    الحد الأدنى للطول: 3,
    الحد الأقصى للطول: 32,
  },
  كلمة المرور: {
    النوع: سلسلة,
    مطلوبة: صحيح,
  },
});

تصدير const userModel = mongoose.model  ("مستخدم"، UserSchema);

اجعل كلمات المرور أكثر أماناً

الأمان أولاً! لنقم الآن بتأمين كلمات المرور الخاصة بنا عن طريق تجزئتها.

npm install - حفظ bcrypt @types/bcrypt

الآن، قم بتنفيذ أمان كلمة المرور داخل رد استدعاء البرنامج الوسيط المسبق. يتم تنفيذ دالات ما قبل البرامج الوسيطة واحدة تلو الأخرى، عند استدعاء كل برنامج وسيط بعد ذلك. لجعل كلمات المرور آمنة، نحن نستخدم تقنية تُنشئ ملحًا وتجزئة في استدعاءات دالة منفصلة.

// src/model.ts
استيراد bcrypt من "bcrypt";
{...}
const SALT_WORK_FACTOR: الرقم = 10;

UserSchema.pre("حفظ"، دالة (التالي) {
  const user = هذا كمستخدم;
  إذا (!this.isModified("كلمة المرور")) إرجاع التالي();

  bcrypt.genSalt(SALT_WORK_FACTOR، الدالة (خطأ، ملح) {
    إذا (خطأ) إرجاع التالي (خطأ);

    bcrypt.hash(user.password, salt, function (err, hash) {
      إذا (خطأ) أرجع التالي (خطأ);
      كلمة مرور المستخدم.password = hash;
      التالي();
    });
  });
});
{...}

ثم أضف طريقة مقارنة كلمات المرور إلى UserSchema:

// src/model.ts
{...}
UserSchema.methods.methods.comparePasswords = الدالة (
  كلمة المرور المرشحة: سلسلة,
  cb: (خطأ: خطأ | فارغ، نفس الشيء: منطقي | فارغ) => باطل
) {
  const user = هذا كمستخدم;
  مقارنة bcrypt.compare(candidatePassword, user.password, (خطأ، isMatch) => {
    إذا (خطأ) {
      إرجاع cb(err, null);
    }
    cb(فارغ، isMatch);
  });
};
{...}

وبالطبع، قم بتعديل نوع المستخدم.

اكتب comparePasswordFunction = (
  كلمة المرور المرشحة: سلسلة,
  cb: (خطأ: خطأ، isMatch: منطقية) => باطل
) => باطل;

تصدير نوع مستخدم = مستند & {
  _id: سلسلة,
  البريد الإلكتروني: سلسلة,
  الاسم: سلسلة,
  كلمة المرور: سلسلة,
  comparePasswords: comparePasswordFunction,
};

يمكننا الآن ترتيب اتصال بين الخوادم وقواعد البيانات. MONGODB_URI هو متغير بيئة يحتوي على سلسلة الاتصال اللازمة لإنشاء الاتصال. يمكنك الحصول عليها من لوحة المجموعة بعد تسجيل الدخول إلى حساب أطلس MongoDB الخاص بك. ضعه داخل .env

// .env
mongodb_uri = ....;

تذكر دائمًا إضافة هذا الملف إلى .gitignore. عظيم! الآن دعنا نضيف دالة تسمح بالاتصال مع db.

// src/server.ts
استيراد mongoose، { اتصال } من "mongoose";
{...}
دع cachedDb: اتصال;

const connectToDatabase = غير متزامن () => { {
  إذا كان (cachedDb) يعود;

  انتظر mongoose.connect(process.env.MONGODB_URI || ""، {
    useNewNewUrlParser: صحيح,
    useUnifiedTopology: صحيح,
    useFindAndAndModify: خطأ,
    useCreateIndex: صحيح,
  });
  cachedDb = mongoose.connection;
};
{...}

السياق هو كائن تتم مشاركته عبر جميع المحللات. لتوفيره، نحتاج فقط إلى إضافة دالة تهيئة السياق إلى مُنشئ ApolloServer. لنفعل ذلك.

// src/server.ts
استيراد { userModel } من "./models/user.model";
{...}
const createLambdaServer = غير متزامن () =>
  جديد ApolloServerLambda({ {
    typeDefs,
    المحللات,
    الاستبطان: صحيح,
    الملعب: صحيح,
    السياق: متزامن () => { {
      انتظر connectToDatabase();

      إرجاع {
        النماذج: {
          نموذج المستخدم,
        },
      };
    },
  });

const createLocalServer = () =>
  خادم أبوللو سيرفر جديد({ {
    typeDefs,
    المحللات,
    الاستبطان: صحيح
    الملعب: صحيح
    السياق: متزامن () => { {
      انتظر connectToDatabase();

      إرجاع {
        النماذج: {
          نموذج المستخدم,
        },
      };
    }
  });

كما ترون، نحن نمرر أيضًا نموذج المستخدم من خلال السياق. يمكننا الآن تحديث المُحَلِّل:

// resolvers.ts
const userResolver = {
  استعلام: {
    المستخدم: متزامن (_, { البريد الإلكتروني، { البريد الإلكتروني، الاسم، كلمة المرور }، { النماذج: { userModel } }) =>) {
      const user = await userModel.findById({ _id: id: id }).exec();
      إرجاع المستخدم;
    },
  },
  طفرة: {
    createUser: async (_, { id }, { النماذج: { userModel } }) => {
      const user = await userModel.create({ البريد الإلكتروني، الاسم، كلمة المرور });
      إرجاع المستخدم;
    },
  },
};

يبدو رائعاً! الآن قم بإنشاء مثيل خادم أساسي:

// src/index.ts
استيراد { createLocalServer } من "./Server";
يتطلب("dotenv").config();

const port = process.env.PORT || 4000;

const server = createLocalServer();

الخادم.listen(المنفذ).then(({ url })) =>) {
  console.log(``Server ir يعمل على ${url}`);
});

بدء تشغيل الخادم المحلي باستخدام Nodemon

آخر شيء قبل التشغيل، أضف nodemon.json

{
  "مشاهدة": ["src"],
  "ext": ".ts,.js",
  "تجاهل": [],
  "تنفيذ": "ts-node --transpile-only ./src/index.ts"
}

إضافة نص برمجي إلى الحزمة.json

"نصوص": {
    "ابدأ": "nodemon"
  },

واركض!

بدء تشغيل npm

يجب أن تحصل على هذه المعلومات داخل المحطة الطرفية:

الخادم ir يعمل على http://localhost:4000/

إذا كانت الإجابة بنعم، افتح http://localhost:4000/ داخل متصفحك.

يجب أن يظهر ملعب GraphQL. لنقم بإنشاء مستخدم جديد!

إنشاء مستخدم.png

ألق نظرة على كيفية ظهورها في قاعدة البيانات.

قاعدة البياناتJohnDoe.png

رائع! كل شيء يعمل بشكل جيد!

دعنا نحاول الحصول على بعض معلومات المستخدم.

userWithoutAuth.png

وإضافة حقل كلمة المرور...

كلمة مرور المستخدم.png

لطيف! نتلقى خطأ لا يمكن الاستعلام عن حقل "كلمة المرور" على نوع "المستخدم".". كما يمكنك التحقق مرة أخرى، لم نقم بإضافة هذا الحقل داخل تعريف نوع المستخدم. إنه موجود هناك عن قصد. يجب ألا نجعل من الممكن الاستعلام عن أي كلمة مرور أو بيانات حساسة أخرى.

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

ولكن قبل ذلك...

تكوين كودجين

دعونا نستخدم GraphQL الكود مولد للحصول على نوع أساسي متوافق، بناءً على مخططنا.

npm install - حفظ @graphql-codegen/cli @graphql-codegen/introspection
@الجرافكل-كودجين/النص البرمجي @الجرافكل-كودجين/محللات النص البرمجي

إنشاء كودجين.yml

الكتابة فوق: صحيح
مخطط: "http://localhost:4000"
يولد:
  ./src/generated/graphql.ts:
    الإضافات:
      - "أنواع المخطوطات"
      - "مُحَلِّلات-مخطوطات-مخطوطات"
  ./graphql.schema.json:
    المكونات الإضافية:
      - "استبطان"

إضافة كودجين البرنامج النصي إلى الحزمة.json

"البرامج النصية": {
    "ابدأ": "nodemon",
    "كودجين": "Graphql-codegen --config ./codegen.yml",
  },

ثم، عند تشغيل الخادم المحلي، قم بتشغيل البرنامج النصي:

تشغيل npm codegen

في حالة النجاح ستصلك رسالة:

  √ تحليل التكوين
  √ توليد المخرجات

إذا تلقيت هذه المعلومات، يجب أن يظهر ملفان:

  • Graphql.schema.json في الدليل الرئيسي
  • graphql.ts في المسار الذي تم إنشاؤه حديثًا src/منشئ

نحن مهتمون أكثر بالثاني. إذا فتحتها، ستلاحظ وجود بنية جميلة من الأنواع.

يمكننا الآن تحسين المحللات لدينا:

// src/resolvers.ts
استيراد { المُحللات، الرمز المميز، المستخدم } من "./مُنشئ/الجرافكل";

const userResolver: محللون = {
  استعلام: {
    user: async (_, { id }, {الطرازات: { userModel }, auth }): الوعد> => {
      const user = await userModel.findById({ _id: id: id }).exec();
      إرجاع المستخدم;
    },
  },
  طفرة: {
    إنشاء مستخدم: غير متزامن (
      _,
      { البريد الإلكتروني، الاسم، كلمة المرور },
      { النماذج: { userModel } }
    ): وعد> => {
      const user = في انتظار userModel.create({
        البريد الإلكتروني,
        اسم,
        كلمة المرور,
      });
      إرجاع المستخدم;
    },
  },
};

المصادقة

بعد ذلك، لنقم بإعداد مصادقة بسيطة قائمة على الرمز المميز.

npm install - حفظ الرمز المميز ل jsonwebtoken @types/jsonwebtoken

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

// src/server.ts
import { IncomingHttpHeaders } from "http";
import {
  APIGatewayProxyEvent,
  APIGatewayProxyEventHeaders,
  Context,
} from "aws-lambda";
import jwt from "jsonwebtoken";
{...}
const checkAuth = async ({ token } : APIGatewayProxyEventHeaders | IncomingHttpHeaders ) => {
  if (typeof token === "string") {
    try {
      return await jwt.verify(token, "riddlemethis");
    } catch (e) {
      throw new AuthenticationError(`Your session expired. Sign in again.`);
    }
  }
};
{...}
const createLambdaServer = async (
  { headers }: APIGatewayProxyEvent,
  context: Context
) => {
  return new ApolloServerLambda({
    typeDefs,
    resolvers,
    context: async () => {
      await connectToDatabase();

      const auth = await checkAuth(headers);

      return {
        auth,
        models: {
          userModel,
        },
      };
    },
  });
};

function createLocalServer() {
  return new ApolloServer({
    typeDefs,
    resolvers,
    introspection: true,
    playground: true,
    context: async ({ req: { headers } = {} }) => {
      const auth = await checkAuth(headers);
      await connectToDatabase();

      return {
         auth,
         models: {
          userModel,
        },
      };
    },
  });
}

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

// resololvers.ts
استيراد { المُحللات، الرمز المميز، المستخدم } من "./مُنشئ/الجرافكل";

const userResolver: محللون = {
  استعلام: {
    user: async (_, { id }, {الطرازات: { userModel }, auth }): الوعد> => {
      إذا (!auth) قم بإلقاء خطأ مصادقة جديد ("لم تتم مصادقتك");

      const user = await userModel.findById({ _id: id: id }).exec();
      إرجاع المستخدم;
    },
    تسجيل الدخول: غير متزامن (
      _,
      { البريد الإلكتروني، كلمة المرور },
      { النماذج: { userModel } }
    ): الوعد> => {
      const user = await userModel.findOne({ email }).exec();

      إذا (!مستخدم) قم بإلقاء خطأ مصادقة جديد("بيانات اعتماد غير صالحة");

      const matchPasswords = bcrypt.compareSync(password, user.password);

      إذا (!تطابق كلمات المرور) قم بإلقاء خطأ مصادقة جديد("بيانات اعتماد غير صالحة");

      const token = jwt.sign({ id: user.id }, "riddlemethis", {
        expiresIn: 60,
      });

      إرجاع { رمز مميز };
    },
  },
  طفرة: {
    إنشاء مستخدم: غير متزامن (
      _,
      { البريد الإلكتروني، الاسم، كلمة المرور },
      { النماذج: { userModel } }
    ): وعد> => {
      const user = في انتظار userModel.create({
        البريد الإلكتروني,
        اسم,
        كلمة المرور,
      });
      إرجاع المستخدم;
    },
  },
};

تحتاج أيضًا إلى تحديث تعريفات نوع المستخدم حسب نوع الرمز المميز واستعلام تسجيل الدخول.

نوع الرمز المميز {
    رمز سلسلة
  }

اكتب استعلام {
    مستخدم(id(id: ID!): مستخدم!
    تسجيل الدخول(البريد الإلكتروني: سلسلة!, كلمة المرور: سلسلة!): رمز!
  }

لنحاول الآن الحصول على مستخدم بدون رمز مميز

noAuth.png

حسناً، يعمل بشكل جيد! حاول تسجيل الدخول

الرمز المميز.png

دعنا نحاول مرة أخرى للحصول على المستخدم، ولكن هذه المرة مع إضافة الرمز المميز إلى الرؤوس

مع الرمز المميز.png

رائع! وماذا لو قمنا بتعيين بيانات اعتماد خاطئة؟

البريد الإلكتروني الخاطئ.png

لطيف!

الاستعداد للنشر

الخطوة الأخيرة: نشر واجهة برمجة التطبيقات بدون خادم مع Netlify!

إنشاء مجلد لامدا في القرص الرئيسي ووضع ملفين بداخله:

يحتوي أولاً على AWS معالج. يقوم بإنشاء مثيل خادم ApolloServerLambda و
ثم اعرض معالجًا باستخدام createHandler لذلك المثيل.

// lambda/graphql.ts
استيراد { APIGatewayProxyEvent, Context } من " aws-lambda";
استيراد { createLambdaServer } من "?????";

تصدير معالج ثابت = مزامن (
  الحدث: APIGatewayProxyEvent,
  السياق: السياق
) => {
  const server = await createLambdaServer(event, context);

  إرجاع وعد جديد((res, rej)) => { {
    const cb = (err: Error, args: any) => (err ? rej(err) : res(args));
    الخادم.createHandler() (الحدث، السياق، cb);
  });
};

يمكنك قراءة المزيد عن ذلك.

الجزء الثاني هو tsconfig. الجزء المهم هو مخرج المجال.

// lambda/TSconfig.json
{
  "compilerOptions": {
    "sourceMap": صحيح,
    "noImplicitAny": صحيح,
    "الوحدة النمطية": "commonjs",
    "target": "es6",
    "التجريبيات التجريبية": صحيح,
    "allowSyntheticDefaultImports": صحيح
    "moduleResolution": "العقدة",
    "skipLibCheck": صحيح,
    "esModuleInterop": صحيح,
    "outDir": "./dist"
  },
  "تضمين": ["./*.ts", "./**/*.ts", "./**/*.js"]
}

ولكن هناك مشكلة. لا يمكننا استخدام /Src دير لأن Netlify لا يمكنه الوصول إلى خارج مجلد لامدا. لذلك يجب علينا تجميعها.

تثبيت npm -حفظ ncp

إنها حزمة تسمح بنسخ الدليل.

إضافة الحزمة البرنامج النصي إلى الحزمة.json

"نصوص": {
    "حزمة": "ncp ./ src ./lambda/bundle",
    "كودجين": "Graphql-codegen --config ./codegen.yml",
    "بدء": "nodemon",
  },

الآن إذا قمت بتشغيل حزمة تشغيل npm، يمكنك أن ترى، أنه في المنشأة حديثًا لامدا/حزمة لدينا جميع الملفات من ق.س.س.س/.

تحديث مسار الاستيراد داخل lambda/graphql.ts

// lambda/graphql.ts
استيراد { APIGatewayProxyEvent، السياق } من ".aws-lambda";
استيراد { createLambdaServer } من "./bundle/server";

{...}

يمكنك الآن إضافة لامدا/حزمة دير إلى .gitignore

النشر باستخدام Netlify

يجب أن نخبر Netlify ما هو أمر الإنشاء وأين توجد وظائفنا. لذلك دعنا ننشئ netlify.toml file:

// netlify.toml
[بناء]
  الأمر = "npm run build:lambda"
  الدوال = "لامدا/ديست"

كما ترى، إنه نفس الدليل الذي تم تعريفه على أنه مخرج الحقل في lambda/TSconfig.json

هكذا يجب أن تبدو بنية تطبيقك (حسنًا... جزء منها؛)

التطبيق
─علم-لمبدا
│علم────حزمة
│ Graphql.ts
│ tsconfig.json.ts
′تعليم ─سرك
│││مُنشَأ-مُنشَأ
││جرافيكل.ts
فهرس.ts
نموذج.ts
─محللات.ts
│مخططات.ts
الخادم.ts
│
│ codegen.yml
│ جرافكل.schema.json
│ netlify.toml
│ nodemon.json
│ tsconfig.json

إضافة الحزمة: لامدا البرنامج النصي إلى الحزمة.json

"البرامج النصية": {
    "build:lambda": "npm run bundle & tsc -p lambda/tsconfig.json",
    "حزمة": "ncp ./src ./lambda/bundle",
    "كودجين": "Graphql-codegen --config ./codegen.yml",
    "بدء": "nodemon",
  },

النشر

لنجرب نشر تطبيقنا عبر Netlify.

  1. سجّل الدخول إلى حساب Netlify الخاص بك,
  2. تواصل مع Github الخاص بك,
  3. انقر على زر "موقع جديد من Git",
  4. اختر الريبو المناسب,
  5. اضبط أمر الإنشاء npm run build build:lambda,
  6. إضافة متغير البيئة (MONGODB_URI),
  7. نشر...

و TAAADAAAAAAAA...

pageNotFound.png

وذلك لأن نقطة النهاية افتراضيًا ليست هي http://page/ ولكن http://page/.netlify/functions/graphql.

بدون إعادة توجيه.png

كيف يمكن إصلاحه؟ الأمر بسيط للغاية. فقط قم بإنشاء _إعادة التوجيه مع:

/ / /.netlify/functions/graphql 200!

النشر مرة أخرى والتحقق.

إعادة توجيه.png

آمل أن تكون قد أعجبتك! لا تتردد في التحسين والتغيير.

اقرأ المزيد:

كيف لا تقتل مشروعاً بممارسات الترميز السيئة؟

أمان تطبيق الويب. ثغرة الهدف="_blank"

أمان تطبيق الويب - ثغرة XSS

مقالات ذات صلة

تطوير البرمجيات

إنشاء تطبيقات ويب مستقبلية: رؤى من فريق خبراء The Codest

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

ذا كوديست
تطوير البرمجيات

أفضل 10 شركات لتطوير البرمجيات في لاتفيا

تعرّف على أفضل شركات تطوير البرمجيات في لاتفيا وحلولها المبتكرة في أحدث مقالاتنا. اكتشف كيف يمكن لهذه الشركات الرائدة في مجال التكنولوجيا المساعدة في الارتقاء بأعمالك.

thecodest
الحلول المؤسسية وحلول التوسعة

أساسيات تطوير برمجيات جافا: دليل للاستعانة بمصادر خارجية بنجاح

استكشف هذا الدليل الأساسي حول تطوير برمجيات جافا outsourcing بنجاح لتعزيز الكفاءة والوصول إلى الخبرة وتحقيق نجاح المشروع باستخدام The Codest.

thecodest
تطوير البرمجيات

الدليل الشامل للاستعانة بمصادر خارجية في بولندا

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

ذا كوديست
الحلول المؤسسية وحلول التوسعة

الدليل الكامل لأدوات وتقنيات تدقيق تكنولوجيا المعلومات

تضمن عمليات تدقيق تكنولوجيا المعلومات وجود أنظمة آمنة وفعالة ومتوافقة. تعرف على المزيد حول أهميتها من خلال قراءة المقال كاملاً.

The Codest
ياكوب جاكوب جاكوبوفيتش CTO وشريك مؤسس CTO

اشترك في قاعدة معارفنا وابقَ على اطلاع على آخر المستجدات في قطاع تكنولوجيا المعلومات.

    نبذة عنا

    The Codest - شركة دولية لتطوير البرمجيات لها مراكز تقنية في بولندا.

    المملكة المتحدة - المقر الرئيسي

    • المكتب 303 ب، 182-184 شارع هاي ستريت نورث E6 2JA
      لندن، إنجلترا

    بولندا - مراكز التكنولوجيا المحلية

    • مجمع مكاتب فابريتشنا المكتبي، أليجا
      بوكوجو 18، 31-564 كراكوف
    • سفارة الأدمغة، كونستروكتورسكا
      11, 02-673 02-673 وارسو، بولندا

      The Codest

    • الصفحة الرئيسية
    • نبذة عنا
    • الخدمات
    • دراسات الحالة
    • اعرف كيف
    • الوظائف
    • القاموس

      الخدمات

    • استشاري
    • تطوير البرمجيات
    • تطوير الواجهة الخلفية
    • تطوير الواجهة الأمامية
    • Staff Augmentation
    • مطورو الواجهة الخلفية
    • مهندسو السحابة
    • مهندسو البيانات
    • أخرى
    • مهندسو ضمان الجودة

      الموارد

    • حقائق وأساطير حول التعاون مع شريك خارجي لتطوير البرمجيات
    • من الولايات المتحدة الأمريكية إلى أوروبا: لماذا تقرر الشركات الأمريكية الناشئة الانتقال إلى أوروبا؟
    • مقارنة مراكز تطوير التكنولوجيا في الخارج: تك أوفشور أوروبا (بولندا)، آسيان (الفلبين)، أوراسيا (تركيا)
    • ما هي أهم التحديات التي تواجه CTOs ومديري تكنولوجيا المعلومات؟
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • شروط استخدام الموقع الإلكتروني

    جميع الحقوق محفوظة © 2025 بواسطة The Codest. جميع الحقوق محفوظة.

    arArabic
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish it_ITItalian jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch etEstonian elGreek arArabic