وداع با API های وب

آفلاین
user-avatar
عرفان حشمتی
01 بهمن 1399, خواندن در 6 دقیقه

هنگام ساخت یک برنامه وب تک صفحه‌ای (SPA) یا یک برنامه تلفن همراه، معمولا برای اتصال فرانت-اند و بک-اند باید یک Web API (REST ، GraphQL و موارد دیگر) را پیاده سازی کنیم. از نظر فنی این کار چندان دشوار نیست، اما عواقب ناخوشایندی دارد.

دو سیاره را تصور کنید. سیاره "فرانت-اند" با جاوااسکریپت صحبت می‌کند و سیاره "بک-اند" نیز با جاوااسکریپت یا هر زبان پیشرفته دیگری صحبت می‌کند.

حال بیایید بگوییم که این سیارات برای تشکیل یک کلمه به نام "اپلیکیشن" نیاز به همکاری گسترده دارند.

متأسفانه، سیارات قادر به برقراری ارتباط مستقیم با یکدیگر با استفاده از زبان مادری خود نیستند و باید به شخص ثالثی به نام " web API " اعتماد کنند که به زبانی بسیار پیچیده صحبت می‌کند.

در واقع زبان اکثر API های وب به ترکیبی از URL ها، چند فعل HTTP (GET ، POST و ...) و گاهی JSON محدود شده است.

API های وب که با GraphQL در ارتباطند پیشرفته ترند اما از امکانات یک زبان برنامه نویسی مانند جاوااسکریپت بسیار عقب هستند:

  • پارادایم برنامه نویسی رویه‌ای یا فانکشنال است (بدون برنامه نویسی شی گرا).
  • فقط اساسی‌ترین تایپ‌ها پشتیبانی می‌شوند (Date، Map، Set و ... را فراموش کنید).
  • مفهوم مرجع وجود ندارد (فقط می‌توانید شی‌ها را از نظر مقدار انتقال دهید).

قرار دادن یک زبان ابتدایی بین فرانت و بک، باعث می‌شود منابع زیادی مصرف شوند و تجربه توسعه را خراب می‌کند.

مشکل دیگر این است که API وب یک لایه به مشکلات اضافه می‌کند که شامل طراحی، اجرا، تست، مستندات و موارد دیگر می‌شود و همه اینها برای توسعه دهنده اذیت کننده است.

اما بدترین چیز این است که ساختن API وب شما را مجبور می‌کند کیفیت پایگاه کد خود را پایین بیاورید. در حقیقت خشک و منسجم نگه داشتن کد هنگامی که فرانت وب و بک آن توسط یک API وب از هم جدا می‌شوند، کاملا چالش برانگیز است.

حال تصور کنید که می‌توانیم از شر API وب خلاص شویم. فرض کنید فرانت-اند می‌تواند با استفاده از زبان مادری خود مستقیما با بک-اند ارتباط برقرار کند. به نظر شما این عالی نیست؟

خبر خوب این است که امروزه به لطف مجموعه‌ای از کتابخانه‌ها به نام Layr این امر امکان‌پذیر است.

با بهره گیری از Layr، فرانت و بک از نظر جسمی از هم جدا شده‌اند (در محیط‌های مختلفی اجرا می‌شوند) اما از نظر منطقی متحد می‌شوند (مانند اینکه در یک محیط هستند).

Layr چگونه کار می‌کند؟

  1. قسمت بک وب متشکل از یک یا چند کلاس است که برخی از ویژگی‌ها و متدهای آن به وضوح در معرض دید قرار گرفته است.
  2. فرانت-اند هم برخی از پروکسی‌ها را برای کلاس‌های بک-اند تولید می‌کند و می‌تواند از این پروکسی‌ها مانند کلاس‌های جاوااسکریپت منظم استفاده کند.

در پشت پرده، Layr به مکانیزم RPC متکی است. بنابراین به صورت سطحی می‌توان چیزی مانندCORBA ، Java RMI یا NET CWF. را مشاهده کرد.

اما Layr کاملا متفاوت است:

  • این یک سیستم شی توزیع شده نیست. بک-اند Layr به نوعی stateless است، بنابراین هیچ شی مشترکی در طول پشته وجود ندارد.
  • شامل هیچ کد boilerplate، کد تولید شده، فایل‌های پیکربندی یا مصنوعات نیست.
  • از یک پروتکل سریال سازی ساده اما قدرتمند به نام Deepr استفاده می‌کند که ویژگی‌های منحصر به فردی مانند فراخوانی زنجیره‌ای، دسته بندی خودکار یا اجرای جزئی را امکان‌پذیر می‌سازد.

Layr سفر خود را با JavaScript / TypeScript آغاز می‌کند، اما مسئله‌ای که با آن روبه‌رو است جهانی است و می‌تواند به هر زبان شی گرا منتقل شود.

مثال

بیایید مثال کلاسیک شمارنده را پیاده سازی کنیم تا ببینیم ساخت یک برنامه کامل با Layer چگونه به نظر می‌رسد.

ابتدا مدل داده و منطق تجاری را در قسمت بک-اند پیاده سازی می‌کنیم:

// backend.js

import {
  Component,
  primaryIdentifier,
  attribute,
  method,
  expose
} from '@layr/component';
import {ComponentHTTPServer} from '@layr/component-http-server';

class Counter extends Component {
  // We need a primary identifier so a Counter instance
  // can be transported between the frontend and the backend
  // while keeping it's identity
  @expose({get: true, set: true}) @primaryIdentifier() id;

  // The counter value is exposed to the frontend
  @expose({get: true, set: true}) @attribute() value = 0;

  // And the "business logic" is exposed as well
  @expose({call: true}) @method() increment() {
    this.value++;
  }
}

// Lastly, we serve the Counter class through an HTTP server
const server = new ComponentHTTPServer(Counter, {port: 3210});
server.start();

عجیب است! همه این کدها فقط برای یک مثال ساده "شمارنده" است؟ مطمئنا بیش از اندازه به نظر می‌رسد. اما در واقع یک بک-اند کامل شامل یک مدل داده، برخی منطق‌های تجاری و یک سرور HTTP که همه چیز را نشان می‌دهد، پیاده سازی کرده‌ایم.

اکنون که بک-اند را داریم، می‌توانیم فرانت را نیز توسعه دهیم:

// frontend.js

import {ComponentHTTPClient} from '@layr/component-http-client';

(async () => {
  // We create a client to connect to the backend server
  const client = new ComponentHTTPClient('http://localhost:3210');

  // We get a proxy to the Counter backend class
  const Counter = await client.getComponent();

  // Lastly, we consume the Counter
  const counter = new Counter();
  console.log(counter.value); // => 0
  await counter.increment();
  console.log(counter.value); // => 1
  await counter.increment();
  console.log(counter.value); // => 2
})();

اینجا چه اتفاقی می‌افتد؟ با فراخوانی متد ()counter.increment مقدار شمارنده افزایش می‌یابد. توجه داشته باشید که این متد در فرانت-اند وجود ندارد و در بک-اند پیاده سازی می‌گردد، بنابراین در این محیط اجرا می‌شود. اما از دید فرانت-اند، محیط اجرای واقعی اهمیتی ندارد. این واقعیت که متد از راه دور اجرا می‌شود، می‌تواند به عنوان جزئیات پیاده سازی شناخته شود.

کلاس Counter در فرانت-اند را می‌توان برای پیاده سازی ویژگی‌هایی که مخصوص فرانت-اند هستند توسعه داد. در اینجا مثالی از نحوه نادیده گرفتن متد ()increment برای نمایش پیام هنگامی که شمارنده به یک مقدار خاص می‌رسد، آورده شده است:

class ExtendedCounter extends Counter {
  async increment() {
    // We call the `increment()` method in the backend
    await super.increment();

    // We execute some additional code in the frontend
    if (this.value === 3)
      console.log('The counter value is 3');
    }
  }
}

چیزی است که هنگام اتصال مجدد فرانت و بک به نظر می‌رسد. خیلی جالب است، نه؟

Catch چیست؟

چرا همه API وب می‌سازند، در حالی که ما می‌توانیم بدون آنها کار کنیم؟

یک دلیل خوب برای پیاده سازی API وجود دارد و آن زمانی است که شما می‌خواهید بک-اند خود را از طریق یک پروتکل ثابت مانند REST در معرض برخی از توسعه دهندگان خارجی قرار دهید. اما بیایید رو راست باشیم، اکثریت قریب به اتفاق برنامه‌ها این نیاز را ندارند و اگر معلوم شد که شما به یک API وب نیاز دارید، می‌توانید پس از آن در صورت استفاده از روش "بدون API" برای تمام نیازهای داخلی خود، آن را اضافه کنید.

دلیل دیگر این است که وقتی در یک برنامه بزرگ با میلیون‌ها کاربر کار می‌کنید. در واقع راحتی کار توسط Layr بدون هزینه هم نیست، بنابراین اگر بهینه‌ترین برنامه ممکن را می‌خواهید، بهتر است از یک راه حل سطح پایین استفاده کنید.

سرانجام اگر می‌خواهید فرانت-اند یا بک-اند را به زبانی غیر از جاوااسکریپت پیاده سازی کنید، همچنان می‌توانید از Layr در یک طرف استفاده کنید. سپس باید یک سرور یا API کلاینت را پیاده سازی کنید که بتواند با پروتکل Deepr در طرف دیگر ارتباط برقرار کند.

جمع‌بندی

حذف Web API به شما امکان می‌دهد تا با افزایش کیفیت پایگاه کد، با سرعت بسیار بالا یک برنامه فول-استک بسازید.

با استفاده از Layr در چندین پروژه از جمله برخی از پروژه‌های صنعتی، من توانستم به طور متوسط ​​50 درصد از کد را کاهش داده و بهره وری خود را بسیار افزایش دهم.

جنبه مهم دیگر تجربه توسعه است. از آنجا که فرانت-اند و بک-اند توسط یک API وب از هم جدا نمی‌شوند، احساسی شبیه ایجاد یک برنامه مستقل خواهید داشت و بسیار سرگرم کننده‌تر است.

منبع

چه امتیازی به این مقاله می دید؟
خیلی بد
بد
متوسط
خوب
عالی

دیدگاه‌ها و پرسش‌ها

برای ارسال دیدگاه لازم است، ابتدا وارد سایت شوید.

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

آفلاین
user-avatar
عرفان حشمتی @heshmati74
مهندس معماری سیستم های کامپیوتری، طراح و توسعه دهنده وب سایت
دنبال کردن

گفتگو‌ برنامه نویسان

بخشی برای حل مشکلات برنامه‌نویسی و مباحث پیرامون آن وارد شو