قبل از اینکه شروع به ساختن web API های خودمون بکنیم، بهتره یه مروری داشته باشیم به اینکه وِب چجوری کار میکنه.
علاوه بر این، ما در این بخش مروری خواهیم داشت بر واژه شناسی در حوزه web API و با اصطلاحاتی از قبیل : endpoint ، resource ، کد های وضعیت HTTP و REST آشنا میشیم. پس حتی اگه در حال حاضر احساس میکنید که شناخت کافی به این موارد دارید، بازم توصیه میکنم که این بخش رو بطور کامل بخونید.

World Wide Web

اینترنت، یک سیستم متشکل از شبکه های کامپیوتری متصل به هم و در هم تنیده هستش که از اواخر دهه ی 60 میلادی تا به الان در زندگی بشر حضور داشته. با اینحال، استفاده اولیه از اینترنت محدود بود به شبکه های مجزای کوچکی که عمدتا دولتی، نظامی یا علمی بودند و اطلاعات را بصورت الکترونیکی رد و بدل میکردند. در دهه ی 80 ، پژوهشکده ها و دانشگاه های بسیاری داشتند از اینترنت بمنظور تبادل داده استفاده میکردن. در اروپا، بزرگترین نقطه ی اتصال اینترنتی واقع بود در CERN ( سازمان تحقیقات اتمی اروپا) در شهر Geneva در کشور سوئیس. آزمایش های صورت گرفته در این سازمان منجر به تولید داده های زیادی میشدند که نیاز بود تا از راه دور با دانشمندانی در سراسر جهان به اشتراک گذاشته شوند.
گر چه در مقایسه با زمانه ی فعلی، استفاده ی کلی از اینترنت در دهه ی 80 بسیار ناچیز بود. بسیاری از افراد به اینترنت دسترسی نداشتند یا اصلا متوجه اهمیت موضوع نبودن. در واقع شمار اندکی از این نقاط اتصال اینترنتی تامین کننده ی همه ی ترافیک حاضر بودن و کامپیوتر هایی هم که از این نقاط اتصال بمنظور تبادل داده استفاده میکردن هم در داخل خود این شبکه کوچک حضور داشتن و بخشی از اون بودن.

همه ی این قضایا با اختراع HTTP در سال 1989 توسط یکی از پژوهشگران CERN به نام " Tim Berners-Lee " برای همیشه تغییر کردن و شبکه جهانی وب مدرن آغاز شد.
اختراع وِی، یعنی : " Hypertext Transfer Protocol (HTTP) " اولین روش استاندارد جهانی بمنظور اشتراک گذاری مستندات در بستر اینترنت بود که آغازگر مفهوم صفحات وِب یا همون web page شد: مستندات مجزایی با یک URL معین که حاوی لینک ها و منابعی چون تصاویر، فایلهای صوتی یا ویدیو هستند.
امروزه وقتیکه اکثر مردم از اینترنت حرف میزنن، منظورشون در اصل همون شبکه جهانی وب هستش که الان تبدیل شده به راه ارتباطی آنلاین میلیاردها انسان و رایانه.

URL ها

یک URL(Uniform Resource Locatore) ، در واقع آدرس یک منبع در بستر اینترنت هستش. برای مثال: homepage گوگل در آدرس " https://www.google.com " قرار داره.
وقتیکه شما میخواهید به این homepage سر بزنید، آدرس URL کاملش رو در مرورگر خودتون تایپ میکنید و سپس مرورگر شما یک درخواست در بستر اینترنت میفرسته و شما بطرز جادویی (اینکه در اصل چه اتفاقی میفته رو یکم جلوتر بررسی میکنیم) به سروری متصل میشید که پاسخی حاوی اطلاعات لازم بمنظور پردازش homepage گوگل رو در اختیار مرورگر شما میذاره.
این الگوی درخواست و پاسخ ، اساس همه ی ارتباطات وِب هستش؛ بدین شکل که یک مشتری یا به اصطلاح client ( که معمولا یک مرورگر یا اَپلیکیشن یا وسیله ای متصل به اینترنت هستش) درخواست یکسری اطلاعات رو میکنه و در مقابل، یک سرور بهش پاسخ میده. از اونجائیکه ارتباطات وِب از طریق HTTP اتفاق میفتن، این قبیل موارد بطور رسمی با عناوین HTTP request (درخواست HTTP) و HTTP response (پاسخ HTTP ) شناخته میشن.
یک URL از چندین قسمت مجزا ساخته میشه. برای نمونه: homepage گوگل که در آدرس : " https://www.google.com " قرار داره رو در نظر بگیرید. اولین قسمت یعنی: " http " اشاره داره به طرح کلی یا به اصطلاح: scheme که به مرورگر میگه که به چه نحوی به موقعیت منابع دسترسی پیدا کنه. قسمت بعدی یعنی: " www.google.com " نام میزبان یا به اصطاح: hostname هستش که در واقع نام اصلی سایته. هر URL حاوی یک طرح کلی و یک میزبان هستش اما بسیاری از صفحات وب حاوی یک مسیر انتخابی یا به اصطلاح optional هم هستن. برای مثال اگر آدرس: " /https://www.python.org/about " رو در نظر بگیرید، قسمت انتهایی یا " /about/ " میشه همون مسیر انتخابی.

پس بطور خلاصه، هر URL مثل: " /https://python.org/about " از سه قسمت تشکیل میشه:

  • یک طرح کلی – https
  • یک نام میزبان – www.python.org
  • و یک مسیر آپشنال - /about/

مجموعه پروتکل اینترنت

صرف دونستن و وجود یک URL کافی نیست، بلکه مجموعه ای از تکنولوژی های دیگه هم باید بدرستی (با همدیگه) کار کنن تا مشتری رو به سرور متصل و یک صفحه وب رو بارگذاری کنن. کل این قضیه رو بهش میگن: " مجموعه پروتکل اینترنت " و کتاب های زیادی هم در این باره نوشته شدن که دقیق پرداختن بهش خارج از حوصله این دوره است و ما فقط درباره مفاهیم پایه ای در این باره صحبت میکنیم.
وقتیکه یک کاربر آدرسِ: " https://www.google.com " رو در مرورگرش وارد میکنه و کلید " Enter " رو فشار میده، چندین اتفاق میفتن. اول از همه مرورگر لازمه که سرور مورد نظر رو در گستره ی اینترنت پیداش کنه؛ برای اینکار از یک DNS(domain name service) استفاده میکنه تا نام دامنه که در اینجا : " google.com " هستش رو به
یک IP Address ترجمه کنه، که اون هم به نوبه ی خودش یک دنباله ی منحصربفرد از اعداد هستش که نمایانگر هر وسیله ی متصل به اینترنته. علت اینکه ما از نام دامنه ها استفاده میکنیم اینه که بخاطر سپردن نام یک دامنه مثل: " google.com " ، راحت از به خاطر سپردن یک آی پی آدرس مثل: " 172.217.164.68 " هستش.
بعد از اینکه مرورگر به آی پی آدرس یک دامنه دسترسی پیدا کرد، نیازمند روشی برای برقراری یک ارتباط پایدار با با سرور مورد نظر خواهد بود. این امکان از طریق TCP(Transmission Control Protocol) میسر میشه که یک تبادل قابل اطمینان، مرتب و خطایابی شده ی بایت های داده رو بین دو اَپلیکیشن فراهم میکنه.

بمنظور برقراری یک ارتباط TCP بین دو کامپیوتر، به اصطلاح یک " handshake " سه طرفه بین کلایِنت و سرور اتفاق میفته:

  1. کلاینت با ارسال یک SYN خواستار برقراری یک ارتباط میشه.
  2. سرور در پاسخ، این درخواست رو با ارسال یک SYN-ACK تصدیق میکنه و یک پارامتر اتصال در اختیارش قرار میده.
  3. کلاینت به سرور یک ACK برمیگردونه و اتصال رو تایید میکنه.

بعد اینکه اتصال TCP برقرار شد، دو کامپیوتر ارتباط خودشون رو از طریق HTTP شروع میکنن.

متد های HTTP

هر صفحه ی وِب، شامل دو چیزه: یکی آدرس (URL) و یکی هم لیستی از اقدامات تایید شده که به عنوان مِتد های HTTP شناخته میشن. تا اینجای کار ما عمدتا درباره ی دریافت یک صفحه ی وب صحبت کردیم. اما علاوه بر این، امکان ایجاد و ویرایش و حذف محتوا هم وجود داره.
وبسایت Facebook رو در نظر بگیرید. بعد از وارد شدن، میتونید مطالب حاضر در تایم لاین خودتون رو بخونید، یک پست جدید بسازید، یا یک پستی که از قبل وجود داشته رو ویرایش/حذف کنید. در اصطلاح، چهار عملِ Create-Read-Update-Delete با عنوان " CRUD " شناخته میشن و نمایانگرِ اکثریت قریب به اتفاق اقداماتی هستن که بصورت آنلاین انجام میپذیرن.
پروتکل HTTP شامل شماری از مِتد های درخواست(request methods) هستش که میتونن به هنگام درخواست اطلاعات مورد استفاده قرار بگیرن. حالا اگه بخواهیم 4 مِتد رایج HTTP که متناظر با همین عملکرد CRUD هستن رو معرفی کنیم، باید به: POST، GET، PUT و DELETE اشاره کنیم.

CRUD Diagram

بمنظور ایجاد محتوای جدید از POST ، خواندن محتوا از GET ، بروزرسانی محتوا از PUT ، و حذف کردن محتوا از DELETE استفاده میکنیم.

Endpoint ها

وبسایت های مرسوم متشکل از یکسری کد های HTML & CSS و JS و تصاویر و از این قبیل چیزها هستن که یک URL اختصاصی برای هر صفحه ای دارن؛ مثل: " /example.com/1 " . یک web API هم به URL ها متکیه اما به جای ارائه ی صفحات وِبی که توسط انسان ها مورد استفاده هستند، اِند پوینت هایی (endpoitnt) رو تولید میکنه که بهشون میگن:" API endpoints ". یک اِند پوینت متشکل از داده هایی (معمولا) در فرمت JSON و لیستی از متد های HTTP تایید شده و در دسترس هستش.

برای مثال ما میتونستیم اِندپوینت هایی مطابق زیر برای یک وبسایت جدید با نام فرضی " mysite " داشته باشیم:

Example


https://www.mysite.com/api/users # GET returns all users
https://www.mysite.com/api/users/<id> # GET returns a single user


در اِندپوینت اولی: " /api/users/ " ، یک درخواست GET لیستی از همه ی کاربران در دسترس رو برمیگردونه. این نوع از اِندپوینت ها که چندین منبع داده رو برمیگردونن، به عنوان یک " collection " شناخته میشن.
اِندپوینت دومی: " <api/users/<id/ " ، فقط یک کاربر رو نمایش میده؛ در واقع درخواست GET فقط همون یدونه کاربر رو بهمون برمیگردونه.
اگر یک مِتد POST به اِندپوینت اول اضافه میکردیم، میتونستیم یک کاربر جدید ایجاد کنیم و اگر به اِندپوینت دوم مِتد DELETE رو اضافه میکردیم میتونستیم یک کاربر رو حذف کنیم.
در ادامه این فصل با این قبیل از اِندپوینت ها که با عنوان : " API endpoints " شناخته میشن بیشتر آشنا میشیم اما در نهایت، ایجاد یک API شامل ایجاد یکسری اِندپوینت میشه: URL هایی که داده هایی رو با فرمت JSON و متد های HTTP مربوطه به نمایش میگذارن.

HTTP

ما تا همینجاش هم کلی در مورد HTTP صحبت کردیم ولی الان وقتشه که تشریحی از اینکه واقعا چیه و چجوری کار میکنه داشته باشیم.
پروتکل HTTP یک پروتکل درخواست-پاسخ بین دو کامپیوتری هستش که با یک ارتباط TCP به هم متصل هستن. کامپیوتری که درخواست ها رو ایجاد میکنه به عنوان مشتری یا کلایِنت شناخته میشه و کامپیوتری که پاسخ هایی متناظر ارائه میده به عنوان سِرور شناخته میشه. معمولا کلاینت، یک مرورگر وب هستش اما میتونه یک اَپلیکیشن iOS یا هر وسیله ی دیگه ای که به اینترنت متصله باشه. همه چیزی که ما لازم داریم تا یک لپ تاپ رو تبدیل به یک سرور کنیم، تعدادی نرم افزار ویژه و یک اتصال اینترنت متداوم هستش.
هر پیام HTTP متشکل از یک لاین وضعیت، header و یک بدنه ی اختیاری برای داده هستش. بعنوان نمونه در پایین یک پیام HTTP ساده آورده شده که یک مرورگر بمنظور دسترسی به homepage گوگل که در آدرس: " https://www.google.com " قرار داره، درخواستش رو داده:

Example


GET / HTTP / 1.1
Host: google.com
Accept_Language: en-US


اولین خط معروفه به خط درخواست که مِتد HTTP مورد استفاده (GET) ، مسیر (/) و ورژن HTTP که "1.1" هستش رو معلوم میکنه.
دو خط بعدی header ها رو عنوان میکنن: Host نام دامنه و Accept_language زبان مورد استفاده رو معین میکنه. لیست بلندی از این HTTP header ها وجود دارند.
پیام های HTTP یک قسمت سومی هم دارن که به عنوان بدنه پیام شناخته میشه، اما ما این قسمت رو فقط در اون دسته ای از پیام های HTTP مشاهده میکنیم که به عنوان پاسخ از سمت سرور ارسال میشن و حاوی داده هستن.

بمنظور ساده تر شدن ماجرا اجازه بدید که فرض کنیم homepage گوگل فقط یه کد HTML با مضمون : " !Hello, World " در خودش داره، در اونصورت پیام HTTP که بعنوان پاسخ از طرف سرور گوگل دریافت میکنیم به شکل زیر خواهد بود:

Example


HTTP/1.1 200 OK
Date: Mon, 24 Jan 2022 23:26:07 GMT
Server: gws
Accept-Ranges: bytes
Content-Length: 13
Content-Type: text/html; charset=UTF-8

Hello, world!


اولین خط معروفه به خط پاسخ که مشخص میکنه ما داریم از HTTP/1.1 استفاده میکنیم. کد وضعیت : " 200 OK " نشون میده که درخواست مشتری موفقیت آمیز بود.
پنج خط بعدی هم header ها هستن؛ و نهایتا بعد از یک خط فاصله، بدنه ی اصلی محتوای حاضر رو میبینیم: " !Hello, World ".

هر پیام HTTP ، چه درخواست باشه یا چه پاسخ، فُرمت زیر رو داره:

Diagram


Response/request line
Headers…

(optional) Body


اکثر صفحات وِب شامل منابع متعددی ان که نیازمند چندین چرخه ی درخواست/پاسخ هستن. برای مثال اگر یک صفحه وب شامل کد HTML و یک فایل CSS و یک تصویر بود، 3 تا چرخه ی رفت و برگشتی بین کلایِنت و سِرور لازم بود تا این صفحه وب میتونست بطور کامل در مرورگر پردازش بشه.

کد وضعیت

همینکه مرورگر شما یک درخواست رو روی یک URL اجرا کنه، هیچ ضمانتی نیست که همه چیز واقعا کار کنه! واسه همین یک لیست بلند از کد های وضعیت HTTP وجود داره که هر پاسخ HTTP رو همراهی کنن.

شما میتونید نوع کلی هر کد وضعیتی رو بر اساس فُرمت بندی زیر تشخیص بدید:

  • 1) (Success) 2xx : اقدام درخواستی از طرف کلایِنت دریافت، تفهیم، و پذیرفته شد
  • 2) (Redirection) 3xx : جابه جایی URL درخواستی
  • 3) (Client Error) 4xx : بروز یک اِرور ، معمولا به خاطر یک درخواست اشتباه از طرف کلایِنت
  • 4) (Server Error) 5xx : عدم موفقیت سِرور در پاسخ به درخواست مطرح شده

نیازی نیست که همه ی کد های وضعیت رو حفظ کنید. با گذر زمان و تمرین کردن با اکثر کد های وضعیت رایج از قبیل: 200(OK) ، 201(Created) ، 301(Moved Permanently) ، 404(Not Found) ، و 500(Server Error) آشنا میشید.

چیز مهمی که باید به خاطر بسپارید اینه که در حالت کلی فقط 4 خروجی احتمال داره برای هر درخواست HTTP رخ بده:

  • 1) 2xx : کار کرد
  • 2) 3xx : یجوری جابه جا یا منتقل شده
  • 3) 4xx : اِرور از طرف کلایِنت
  • 4) 5xx : اِرور از طرف سرور

این کد های وضعیت بطور خودکار در ابتدای هر پیام HTTP و در لاین درخواست/پاسخ قرار میگیرن.

Statelessness

یک نکته نهایی لازم به ذکر اینه که HTTP یک پروتکل بدون حالت یا به اصطلاح stateless هستش. این بدین معناست که هر جفت درخواست/پاسخ از جفت قبلیش جداست؛ به عبارتی هیچگونه ذخیره سازی از فعل و افعالات گذشته در حافظه صورت نمیگیره. اطلاعات به خاطر سپرده شده، حالت سیستم نامیده میشه که در علوم کامپیوتر هم بهش میگن: " state " .

بدون حالت بودن فواید بسیاری برای HTTP داره. از اونجائیکه همه ی سیستم های ارتباطی الکترونیکی در طول زمان دچار فقدان سیگنال میشن، در صورت نبود یک پروتکل بدون حالت، حتی اگر یک چرخه ی درخواست/ پاسخ هم به درستی کامل نمیشد اشیاء مدام از کار می افتادن. به همین خاطر، HTTP به عنوان یک پروتکل توزیع شده ی بسیار انعطاف پذیر شناخته میشه.
جنبه منفیش هم اینه که مدیریت حالت یا همون state ، در وب اَپلیکیشن ها خیلی خیلی مهمه چون بخاطر همین state هستش که یک وب سایت به خاطر میاره شما وارد شدین یا اینکه یک وبسایت تجاری میتونه سبد خرید شما رو مدیریت کنه. این قضیه در ارتباط با نحوه ی استفاده ما از وب سایت های مدرن خیلی اساسیه، اما هنوز در HTTP پشتیبانی نمیشه.
قبلا ها این state روی سرور ها نگه داری میشد ولی رفته رفته در فریمورک های فرانت-اِند مدرن مثل: React ، Angular و Vue به سمت کلایِنت سوق پیدا کرد(کلایِنت رو میشه همون مرورگر وب دونست اینجا). در بخش های جلوتر وقتیکه بخواهیم در مورد احراز هویت کاربر صحبت کنیم، چیزای بیشتری راجع به state یاد میگیریم ولی فعلا یادتون باشه که HTTP یک پروتکل بدون حالت یا همون stateless هستش. این بدون حالت بودن از بابت اینکه بخواهیم اطلاعاتی رو بین دو کامپیوتر رد و بدل کنیم خیلی خوب و قابل اطمینانه، اما ضعفش در بیاد سپردن هر چیزیه که خارج از یک جفت درخواست/پاسخ اتفاق میفته.

REST

در سال 2000 میلادی، آقای " Roy Fielding " معماریِ REpresentational State Transfer (REST) رو در پایان نامه خودش مطرح کرد که رویکردی برای ایجاد API هستش.

کلی کتاب درباره ی این که چه چیزی یک API رو واقعا RESTful میکنه نوشته شدن، اما 3 تا مورد اصل کاری هستن و ما هم روی همون ها تمرکز میکنیم.

هر RESTful API :

  • بدون حالت هستش، مثله HTTP
  • از متد های رایج HTTP پشتیبانی میکنه(GET ، POST ، PUT ، DELETE و ... )
  • داده ها رو یا در فرمت JSON و یا در فرمت XML برمیگردونه

هر RESTful API باید حداقل این سه تا اصل رو داشته باشه. این استاندارد مهمه چون یک روش ثابت هم بمنظور طراحی و هم بمنظور استفاده از web API ها هستش.

جمع بندی

با وجود اینکه زیرساخت شبکه جهانی وب مدرن از تکنولوژی ها بسیاری ساخته شده اما ما به عنوان توسعه دهنده مجبور نیستیم که همه شون رو خودمون از صفر پیاده کنیم. ترکیب صحیح جنگو و فریمورک REST جنگو، عمده ی پیچیدگی web API ها رو مدیریت میکنه. اگر چه مهمه که در حالت کلی، درک درستی از نحوه قرار گرفتن همه ی این اجزا در کنار هم داشته باشیم.
نهایتا یک web API مجموعه ای از اِندپوینت هاست که بخش های مشخصی از یک دیتابیس رو قابل دسترس میکنن و به نمایش میگذارن. ما به عنوان توسعه دهنده میایم و URL های هر اِندپوینت ، داده های در دسترس، و مِتد های HTTP قابل اجرا رو کنترل میکنیم. با استفاده از header هایی که بهشون اشاره کردیم هم میتونیم سطوح و مجوز های دسترسی تعیین کنیم که در ادامه فصل شاهدشون خواهیم بود.


***: از اونجائیکه نمیشه RESTful API رو بصورت ترجمه شده در ضمن دوره آورد، ممنون میشیم اگر خودتون سعی کنید با ریتم متن بخونیدش و جلو برید.

***: از این به بعد به جای آوردن نام کامل Django REST Framework ، بصورت مخفف از: "DRF" استفاده میکنیم.