البرنامج التعليمي: كيفية كتابة API CRUD مع بخار 2

في نهاية هذا البرنامج التعليمي ، سيكون لديك واجهة برمجة التطبيقات (API) مع إنشاء وقراءة وتحديث وحذف (CRUD) على مستخدم يتحدث JSON إليك!

يمكنك العثور على نتيجة هذا البرنامج التعليمي على جيثب: هنا.

1. إنشاء مشروع بخار جديد

ملاحظة: للقيام بهذا البرنامج التعليمي ، ستحتاج إلى تثبيت سريع 3 وصندوق أدوات بخار و postgresql.

سوف نقوم باستنساخ قالب api الذي يوفره البخار:

بخار اختبار جديد على سبيل المثال

اذهب إلى داخل الدليل الخاص بك ، وقم بإنشاء مشروع Xcode جديد وافتحه:

مثال اختبار CD /
بخار xcode -y

يجب أن يكون لديك هيكل مشروع مثل هذا:

اختبار سبيل المثال /
├── حزمة
/ المصادر /
/ ├── التطبيق /
├── │ ├── التكوين + Setup.swift
+ │ ├── Droplet + Setup.swift
├── │ ├── Routes.swift
/ │ ├── تحكم /
└── │ │ └── PostController.swift
/ │ └── النماذج /
. │ └── Post.swift
└── └── تشغيل /
/ الاختبارات /
├── التكوين /
├── عام /
التبعيات /
/ المنتجات /

2. حذف (نقل إلى سلة المهملات) الملفات والرمز

أحب أن أبدأ من نقطة الصفر حتى نعرف بالضبط أي الملفات والتطبيقات اللازمة من أجل ماذا؟

اختبار سبيل المثال /
├── حزمة
/ المصادر /
/ ├── التطبيق /
├── │ ├── التكوين + Setup.swift
+ │ ├── Droplet + Setup.swift
├── │ ├── Routes.swift
│ │ ├── تحكم / <- حذف
└── │ │ └── PostController.swift <- DELETE
/ │ └── النماذج /
└── │ └── Post.swift <- DELETE
└── └── تشغيل /
/ الاختبارات /
├── التكوين /
├── عام /
التبعيات /
/ المنتجات /

داخل Sources / App / Config + Setup.swift ، قم بحذف السطر التالي:

استيراد FluentProvider
تهيئة الامتداد {
  إعداد func العمومي ()
    / / السماح للتحويلات غامض لهذه الأنواع
    // (أضف الأنواع الخاصة بك هنا)
    Node.fuzzy = [Row.self، JSON.self، Node.self]
    جرب setupProviders ()
    جرب setupPreparations ()
  }
  /// تكوين مقدمي
  برنامج إعداد func الخاص ()
    جرب addProvider (FluentProvider.Provider.self)
  }
  /// إضافة جميع النماذج التي ينبغي أن يكون لها
  مخططات /// أعدت قبل بدء تشغيل التطبيق
  إعداد func setupPreparations () الخاص {
    preparations.append (Post.self) <- DELETE
  }
}

داخل Sources / App / Routes.swift ، يحذف كل شيء حتى يبدو كما يلي:

استيراد بخار
التمديد قطرة
  func setupRoutes () رميات {
  }
}

3. إضافة التبعيات

في Package.swift ، أضف التبعية التالية (postgresql):

استيراد PackageDescription
دع الحزمة = الحزمة (
  الاسم: "مثال الاختبار" ،
  الأهداف: [
    الهدف (الاسم: "التطبيق") ،
    الهدف (الاسم: "تشغيل" ، التبعيات: ["التطبيق"]) ،
  ]،
  التبعيات: [
    .Package (url: "https://github.com/vapor/vapor.git" ، majorVersion: 2) ،
    .Package (url: "https://github.com/vapor/fluent-provider.git" ، majorVersion: 1) ، <- لا تنسى هذا COMMA ؛)
    .Package (url: "https://github.com/vapor/postgresql-provider.git" ، majorVersion: 2)
  ]،
  استبعاد: [
    "تكوين"،
    "قاعدة البيانات"،
    "الموقع"،
    "عامة"،
    "مصادر"،
  ]
)

احصل الآن على التبعية الجديدة في الجهاز الخاص بك في مثال الاختبار / الدليل ، وأعد إنشاء مشروع Xcode وأعد فتحه:

جلب بخار
بخار xcode -y

في Sources / App / Config + Setup.swift ، أضف PostgreSQLProvider:

استيراد FluentProvider
استيراد PostgreSQLProvider <- إضافة
تهيئة الامتداد {
  إعداد func العمومي ()
    / / السماح للتحويلات غامض لهذه الأنواع
    // (أضف الأنواع الخاصة بك هنا)
    Node.fuzzy = [Row.self، JSON.self، Node.self]
    جرب setupProviders ()
    جرب setupPreparations ()
  }
  /// تكوين مقدمي
  برنامج إعداد func الخاص ()
    جرب addProvider (FluentProvider.Provider.self)
    حاول addProvider (PostgreSQLProvider.Provider.self) <- إضافة
  }
  /// إضافة جميع النماذج التي ينبغي أن يكون لها
  مخططات /// أعدت قبل بدء تشغيل التطبيق
  إعداد func setupPreparations () الخاص {
  }
}
دعونا نتحقق مما إذا كان كل شيء سار على ما يرام حتى الآن ، وتأكد من تحديد My Mac وتشغيله hit ومعرفة ما إذا كان 127.0.0.1:8080 في متصفحك يعرض صفحة فارغة

4. تكوين وإنشاء قاعدة بيانات

داخل التكوين / إنشاء مجلد جديد يسمى الأسرار وداخل أسرار / دليل إنشاء ملف يسمى postgresql.json:

اختبار سبيل المثال /
├── حزمة
/ المصادر /
/ الاختبارات /
├── التكوين /
. ├── app.json
rypt ├── crypto.json
ple ├── droplet.json
├── ├── fluent.json
أسرار ├── ├── / <- إنشاء
└── │ └── postgresql.json <- إنشاء
└── └── server.json
├── عام /
التبعيات /
/ المنتجات /

داخل postgresql.json الكتابة:

{
  "اسم المضيف": "127.0.0.1" ،
  "الميناء": 5432 ،
  "المستخدم": "martinlasek" ،
  "كلمه السر": ""،
  "قاعدة البيانات": "testexample"
}
ملاحظة: يجب عليك استبدال المستخدم martinlasek باسم المستخدم الخاص بك

من الداخل Config / fluent.json قم بتعيين postgresql كسائق

{
  "//": "تكنولوجيا قاعدة البيانات الأساسية لاستخدامها." ،
  "//": "memory: SQLite in-memory DB."،
  "//": "sqlite: قاعدة بيانات SQLite الثابتة (التكوين باستخدام sqlite.json)"،
  "//": "تتوفر برامج تشغيل أخرى من خلال موفري Vapor" ،
  "//": "https://github.com/search؟q=topic:vapor-provider+topic:database"،
  "driver": "postgresql" ، <- تغيير من الذاكرة إلى postgresql
  ...
}

قم بإنشاء testexample لقاعدة البيانات عن طريق كتابة ما يلي:

createb testexample؛

5. إنشاء نموذج المستخدم

داخل Sources / App / Models / إنشاء ملف يسمى User.swift ، تجديد وفتح مشروع Xcode الخاص بك:

المس المصادر / التطبيق / النماذج / User.swift
بخار xcode -y
نظرًا لعدم وجود ملف. swift في الدليل / النماذج ، فلن يعرض Xcode هذا الدليل. لذلك لا يمكنك إنشاء ملف داخل الطرازات / من خلال Xcode

Inside Sources / App / Models / User.swift الصق الكود التالي:

استيراد بخار
استيراد FluentProvider
استيراد HTTP
الفئة النهائية المستخدم: نموذج {
  دع التخزين = التخزين ()
  فار اسم المستخدم: سلسلة
  فار العمر: كثافة العمليات
  init (اسم المستخدم: السلسلة ، العمر: Int) {
    self.username = اسم المستخدم
    self.age = العمر
  }
  / / بدء المستخدم مع بيانات قاعدة البيانات
  الحرف الأول (الصف: الصف) يلقي {
    اسم المستخدم = try row.get ("اسم المستخدم")
    age = try row.get ("age")
  }
  func makeRow () رميات -> صف {
    فار صف = صف ()
    جرب row.set ("اسم المستخدم" ، اسم المستخدم)
    جرب row.set ("العمر" ، العمر)
    صف العودة
  }
}
/// MARK: إعداد بطلاقة
ملحق المستخدم: التحضير {
  // يعد طاولة في قاعدة البيانات
  إعداد func ثابت (_ قاعدة البيانات: قاعدة البيانات) رميات {
    جرب database.create (self) {باني في
      builder.id ()
      builder.string ( "اسم المستخدم")
      builder.int ( "عمر")
    }
  }
  // يحذف الجدول من قاعدة البيانات
  ثابت func العودة (_ قاعدة البيانات: قاعدة البيانات) رميات {
    جرب database.delete (ذاتي)
  }
}
/// MARK: JSON
ملحق المستخدم: JSONConvertible {
  / / تتيح لك بدء المستخدم مع json
  ملاءمة init (json: JSON)
    self.init (
      اسم المستخدم: try json.get ("اسم المستخدم") ،
      العمر: حاول json.get ("العمر")
    )
  }
  / / إنشاء json من مثيل المستخدم
  رمية func makeJSON () -> JSON {
    فار json = JSON ()
    جرب json.set (User.idKey ، المعرف)
    جرب json.set ("اسم المستخدم" ، اسم المستخدم)
    جرِّب json.set ("العمر" ، العمر)
    عودة json
  }
}

أخبر التطبيق الخاص بك عن النموذج الخاص بك عن طريق إضافته داخل Sources / App / Config + Setup.swift

استيراد FluentProvider
استيراد PostgreSQLProvider
تهيئة الامتداد {
  إعداد func العمومي ()
    / / السماح للتحويلات غامض لهذه الأنواع
    // (أضف الأنواع الخاصة بك هنا)
    Node.fuzzy = [Row.self، JSON.self، Node.self]
    جرب setupProviders ()
    جرب setupPreparations ()
  }
  /// تكوين مقدمي
  برنامج إعداد func الخاص ()
    جرب addProvider (FluentProvider.Provider.self)
    جرب addProvider (PostgreSQLProvider.Provider.self)
  }
  /// إضافة جميع النماذج التي ينبغي أن يكون لها
  مخططات /// أعدت قبل بدء تشغيل التطبيق
  إعداد func setupPreparations () الخاص {
    preparations.append (User.self) <- إضافة
  }
}

الآن مرة أخرى ، لنقم بتشغيل - المشروع ، سوف يعد قاعدة البيانات الخاصة بك ويقوم بإنشاء جدول مستخدم. ستظهر لك وحدة التحكم في Xcode شيئًا مثل:

مفتاح التجزئة الحالي "0000000000000000" غير آمن.
قم بتحديث hash.key في Config / crypto.json قبل استخدامه في الإنتاج.
استخدم `openssl rand -base64 ` لإنشاء سلسلة عشوائية.
مفتاح التشفير الحالي "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
قم بتحديث cipher.key في Config / crypto.json قبل استخدامه في الإنتاج.
استخدم `openssl rand -base64 32` لإنشاء سلسلة عشوائية.
إعداد قاعدة البيانات <- هذا هو ما نبحث عنه
لم يتم توفير أمر ، والتقصير لخدمة ...
بدء تشغيل الخادم على 0.0.0.0:8080
إذا لم تسمح لك Xcode بتشغيل مشروعك ، فما عليك سوى تنفيذ vapor xcode -y في الجهاز الطرفي وحاول تشغيله مرة أخرى

6. تنفيذ: إنشاء

في Sources / App / Routes.swift الخاص بك ، قم بتنفيذ مسار جديد يتوقع طلب JSON ، وابدأ مستخدمًا منه واستمر في إرساله إلى قاعدة البيانات:

استيراد بخار
التمديد قطرة
  func setupRoutes () رميات {
    /// إنشاء المستخدم
    /// طريقة HTTP: آخر
    post ("user") {req in
      // تحقق من طلب يتضمن json
      اترك الحارس json = req.json آخر {
        رمي إحباط (.badRequest ، السبب: "لم يتم توفير json")
      }
      السماح للمستخدم: المستخدم
      / / حاول تهيئة المستخدم باستخدام json
      فعل {
        user = try مستخدم (json: json)
      }
      قبض على {
        رمي إحباط (.badRequest ، السبب: "json غير صحيحة")
      }
      // حفظ المستخدم
      جرب user.save ()
      // عودة المستخدم
      العودة حاول user.makeJSON ()
    }
  }
}

إذا قمت الآن بتشغيل التطبيق الخاص بك و POST على 127.0.0.1:8080/user مع JSON صالح:

{
  "اسم المستخدم": "توم كروز" ،
  "العمر": 23
}

سيقوم بإنشاء مستخدم وحفظه في قاعدة البيانات وإرجاع المستخدم الذي تم إنشاؤه بتنسيق JSON إليك. يمكنك استخدام Postman أو إذا كنت تتحدث مع nerdy فقط استخدم كتابتك الطرفية:

curl -H "Content-Type: application / json" -X POST -d '{"username": "Tom Cruise"، "age": 23}' http://127.0.0.1:8080/user

وفي كلتا الحالتين سوف تحصل على استجابة تبدو مثل هذا:

{"id": 1 ، "age": 23 ، "اسم المستخدم": "Tom Cruise"}

7. تنفيذ: قراءة

في Sources / App / Routes.swift الخاص بك ، قم بتنفيذ مسار جديد يتوقع معرفًا ويعيد لك المستخدم الذي يحمل هذا المعرّف بتنسيق JSON:

استيراد بخار
التمديد قطرة
  func setupRoutes () رميات {
    /// إنشاء المستخدم
    /// طريقة HTTP: آخر
    post ("user") {req in
      ...
    }
    /// اقرأ المستخدم بواسطة معرف معين
    /// طريقة HTTP: الحصول عليها
    get ("user"، Int.parameter) {req in
      // الحصول على معرف من رابط
      اسمحوا userId = حاول req.parameters.next (Int.self)
      / / العثور على المستخدم مع معرف معين
      حارس السماح للمستخدم = حاول User.find (userId) آخر {
        رمي Abort (.badRequest ، السبب: "المستخدم بمعرف \ (userId) غير موجود")
      }
      / / عودة المستخدم باسم json
      العودة حاول user.makeJSON ()
    }
  }
}

إذا قمت الآن بتشغيل التطبيق الخاص بك ، نظرًا لأنه عبارة عن مسار GET ، فيمكنك تشغيل 127.0.0.1:8080/user/1 إما في متصفحك أو إذا كنت تتحدث مع nerdy فقط استخدم الكتابة الطرفية:

حليقة http://127.0.0.1:8080/user/1

يجب أن يعيدك JSON للمستخدم ذي المعرف المستخدم في عنوان url الذي يشبه:

{
  "معرف": 1 ،
  "العمر": 23 ،
  "اسم المستخدم": "توم كروز"
}

8. تنفيذ: التحديث

في Sources / App / Routes.swift الخاص بك ، قم بتنفيذ مسار جديد يتوقع JSON- طلب مع معرف للمستخدم لتحديث وإرجاع المستخدم المحدث إليك بتنسيق JSON:

استيراد بخار
التمديد قطرة
  func setupRoutes () رميات {
    /// إنشاء المستخدم
    /// طريقة HTTP: آخر
    post ("user") {req in
      ...
    }
    /// اقرأ المستخدم بواسطة معرف معين
    /// طريقة HTTP: الحصول عليها
    get ("user"، Int.parameter) {req in
      ...
    }
    
    /// تحديث المستخدم بالكامل
    /// طريقة HTTP: وضعت
    وضع ("المستخدم" ، Int.parameter) {مسا في
      // الحصول على userId من url
      اسمحوا userId = حاول req.parameters.next (Int.self)
      // العثور على المستخدم بواسطة معرف معين
      حارس السماح للمستخدم = حاول User.find (userId) آخر {
        رمي Abort (.badRequest ، السبب: "مستخدم بمعرف محدد: \ (userId) لا يمكن العثور عليه")
      }
      // check يتم توفير اسم المستخدم بواسطة json
      اسمحوا لنا اسم المستخدم = req.data ["اسم المستخدم"] ؟. سلسلة أخرى {
        رمي إحباط (.badRequest ، السبب: "لم يتم توفير اسم مستخدم")
      }
      يتم توفير // تحقق من العمر عن طريق json
      اترك الحارس age = req.data ["age"] ؟. int else {
        رمي إحباط (.badRequest ، السبب: "لم يتم توفير العمر")
      }
      / / تعيين قيم جديدة للمستخدم وجدت
      اسم المستخدم = اسم المستخدم
      user.age = العمر
      // احفظ المستخدم بقيم جديدة
      جرب user.save ()
      / / عودة المستخدم باسم json
      العودة حاول user.makeJSON ()
    }
  }
}

إذا قمت الآن بتشغيل التطبيق الخاص بك و PUT إلى 127.0.0.1:8080/user/1 مع JSON صالح:

{
  "اسم المستخدم": "رابط" ،
  "العمر": 41
}

سيقوم بالبحث عن المستخدم ذي المعرف المحدد في عنوان url ، وتحديث خصائصه ، وحفظه مرة أخرى في قاعدة البيانات ، وكذلك إعادته إليك بتنسيق JSON. يمكنك استخدام Postman أو إذا كنت تتحدث مع nerdy فقط استخدم كتابتك الطرفية:

حليقة -H "نوع المحتوى: application / json" -X PUT -d '{"اسم المستخدم": "Yamato"، "age": 41}' http://127.0.0.1:8080/user/1

يجب أن يعيدك JSON للمستخدم المحدّث الذي يشبه:

{
  "معرف": 1 ،
  "اسم المستخدم": "ياماتو"
  "العمر": 41 ،
}

9. تنفيذ: حذف

في Sources / App / Routes.swift الخاص بك ، قم بتنفيذ مسار جديد يتوقع معرفًا ويعيد لك JSON مع رسالة نجاح

استيراد بخار
التمديد قطرة
  func setupRoutes () رميات {
    /// إنشاء المستخدم
    /// طريقة HTTP: آخر
    post ("user") {req in
      ...
    }
    /// اقرأ المستخدم بواسطة معرف معين
    /// طريقة HTTP: الحصول عليها
    get ("user"، Int.parameter) {req in
      ...
    }
    
    /// تحديث المستخدم بالكامل
    /// طريقة HTTP: وضعت
    وضع ("المستخدم" ، Int.parameter) {مسا في
      ...
    }
    /// DELETE user by id
    /// طريقة HTTP: حذف
    delete ("user"، Int.parameter) {req in
      // الحصول على معرف المستخدم من url
      اسمحوا userId = حاول req.parameters.next (Int.self)
      / / العثور على المستخدم مع معرف معين
      حارس السماح للمستخدم = حاول User.find (userId) آخر {
        رمي Abort (.badRequest ، السبب: "المستخدم بمعرف \ (userId) غير موجود")
      }
      // مسح المستخدم
      جرب user.delete ()
      ارجع إلى JSON (العقدة: ["type": "success" ، "message": "تم حذف المستخدم الذي يحمل id \ (userId) بنجاح"])
    }
  }
}

إذا قمت الآن بتشغيل التطبيق الخاص بك و DELETE إلى 127.0.0.1:8080/user/1 ، فسوف يبحث عن المستخدم ذي المعرف المحدد في عنوان url ، وحذفه وإرجاع JSON مع رسالة نجاح بما في ذلك معرف المستخدم. يمكنك استخدام Postman أو إذا كنت تتحدث مع nerdy فقط استخدم كتابتك الطرفية:

حليقة -X DELETE http://127.0.0.1:8080/user/1

يجب أن يعيدك JSON تبدو مثل:

{
  "النوع": "النجاح" ،
  "message": "تم حذف المستخدم ذي المعرف 1 بنجاح"
}

مبروك! قمت بنجاح بتنفيذ API مع CRUD على مستخدم !!

أين أذهب من هنا؟ تعلم كيف تختبر طرقك هنا!

شكرا جزيلا لقراءة! إذا كان لديك أي اقتراحات أو تحسينات ، فأعلمني! أحب أن أسمع منك!

تويتر / جيثب / إنستغرام