اصل HATEOAS – ایجاد مسیرهای کامل برای اشیا در چارچوب استراحت جنگو.

پیشینه داستان: Pssft – لطفا نزدیکتر شوید.
بنابراین من در این گروه توسعه دهندگان خاص WhatsApp هستم، جایی که موضوعات مختلف مورد بحث قرار می گیرد و اشکال زدایی جفتی از جمله موارد دیگر انجام می شود. ارزشمندترین آنها اطلاعاتی است که به اشتراک گذاشته می شود – از فرصت های شغلی گرفته تا آخرین چارچوب ها و بهترین شیوه ها.
در یک روز نفرین شده، پیوندی به اشتراک گذاشته شد. این یک پیوند به یک پست وبلاگ توسط مایکروسافت بود، عنوان آن “RESTful web API design” بود. تصمیم گرفتم کامل بخوانم و با مفهومی مواجه شدم که “HATEOAS” است (سرد شو! اطلاعات بیشتر در ادامه). میتوانستم قسم بخورم که قبلاً آن را در جایی دیدهام، اما تا کنون واقعاً به آن فکر نکردهام. به سرعت به جلو، آن را گزگز من ؛) بنابراین من تصمیم گرفتم آن را با استفاده از Django Rest Framework (DRF) پیاده سازی کنم و به شما نشان خواهم داد که چگونه.
————— اما در ابتدا چیزی که در مورد HATEOAS یاد گرفتم اینجاست:
اصل HATEOAS چیست؟
HATEOAS (Hypermedia به عنوان موتور حالت برنامه) یک اصل در طراحی API است که هدف آن کشف بیشتر و توصیفی تر API ها است. در ساده ترین عبارت، به این معنی است که یک پاسخ API باید شامل پیوندها یا ارجاع به منابع مرتبط و اقدامات قابل انجام باشد.
تصور کنید در حال مرور یک وب سایت هستید و با یک صفحه محصول روبرو می شوید. در آن صفحه، نه تنها اطلاعات مربوط به محصول را میبینید، بلکه پیوندهایی به اقدامات مرتبط مانند «افزودن به سبد خرید»، «مشاهده نظرات» یا «محصولات مشابه» را نیز مشاهده میکنید. این پیوندها راهی را در اختیار شما قرار می دهند تا بدون نیاز به ساخت دستی URL یا دانستن کل ساختار وب سایت از قبل، در وب سایت حرکت کنید.
HATEOAS همین مفهوم را برای API ها اعمال می کند. به جای دریافت فقط داده در یک پاسخ API، پاسخ همچنین حاوی پیوندها یا ارجاع به منابع یا اقدامات مرتبط است. این پیوندها می توانند شما را در مورد نحوه تعامل با API و کشف سایر اطلاعات مرتبط راهنمایی کنند. به عنوان مثال، اگر دادههای مربوط به یک کاربر خاص را دریافت میکنید، پاسخ ممکن است شامل پیوندهایی برای بهروزرسانی نمایه، بازیابی سفارشات یا مشاهده دنبالکنندگانش باشد.
با گنجاندن این پیوندها در پاسخهای API، مشتریانی که از API استفاده میکنند، میتوانند راحتتر با API حرکت کرده و با آن تعامل داشته باشند. آنها نیازی به تکیه بر دانش قبلی یا URL های کدگذاری سخت ندارند، اما می توانند پیوندهای ارائه شده توسط API را برای دسترسی به منابع مختلف یا انجام اقدامات دنبال کنند.
به طور خلاصه، HATEOAS استفاده از API را با گنجاندن پیوندها یا مراجع در پاسخهای API ساده میکند و به مشتریان اجازه میدهد تا به صورت پویاتر با API حرکت کرده و با آن تعامل داشته باشند و قابلیتهای آن را بدون دانش قبلی گستردهتر کشف کنند.
صحبت کافی است، در اینجا پاسخ HATEOAS به نظر می رسد:
در این مثال، ما پاسخی برای یک منبع کتاب داریم. پاسخ شامل شناسه کتاب، عنوان و اطلاعات نویسنده است. نویسنده به عنوان یک شی تودرتو، شامل شناسه و نام آنها نشان داده می شود. علاوه بر این، هم کتاب و هم اشیاء نویسنده دارای یک فیلد “پیوندها” هستند.
فیلد “پیوندها” در شیء کتاب، ارجاعاتی به منابع و اقدامات مرتبط ارائه می دهد. در این مورد:
به طور مشابه، فیلد “پیوندها” در شی نویسنده شامل یک پیوند “خود” است که نشانی اینترنتی منبع نویسنده را فراهم می کند: “https://api.example.com/authors/1”.
این پیوندها به مشتریان اجازه می دهد تا با دنبال کردن URL های ارائه شده، بدون نیاز به ساخت دستی آنها یا داشتن دانش قبلی از ساختار API، در API حرکت کنند. مشتریان می توانند به سادگی با دنبال کردن پیوندهای مناسب در پاسخ API به منابع مرتبط مانند بررسی ها یا یافتن کتاب های مشابه دسترسی پیدا کنند.
پیاده سازی پایه در DRF
پیاده سازی در اینجا نسبتاً سریع و آسان است، اما بسته به مقیاس پروژه ممکن است همیشه اینطور نباشد.
من فرض میکنم که شما قبلاً در python، Django و REST دانش دارید، بنابراین من در مورد همه چیزهای ناخوشایند صحبت نمیکنم، فقط در صورت نیاز.
اکنون می دانیم که بیشتر درباره HATEOAS چیست – که پیوندهای هایپر رسانه یا منابع را به پاسخ json API خود متصل می کند. با این مقاله من یک روش ساده برای ایجاد چنین پیوند / مسیری را به شما نشان خواهم داد.
الزامات:
– راه اندازی محیط مجازی (برای ویندوز):
$> cd project_folder
$> pip install virtualenv
$> python -m venv venv
$> .\venv\Scripts\activate
راه اندازی یک پروژه جنگو:
با اجرای دستور زیر در ترمینال خود یک پروژه جنگو جدید ایجاد کنید:
pip install django
pip install djangorestframework
django-admin startproject library_project
یک برنامه جنگو جدید ایجاد کنید:
به دایرکتوری پروژه بروید و یک برنامه جنگو جدید ایجاد کنید، که منطق کتاب ها و نویسندگان را مدیریت می کند:
cd library_project
python manage.py startapp library
مدل ها را تعریف کنید: در library/models.py
فایل، مدل هایی را برای کتاب ها و نویسندگان تعریف کنید. مثلا:
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
def get_absolute_url(self):
return f"/authors/{self.id}/"
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
return f"/books/{self.id}/"
ایجاد سریال ساز: در library/serializers.py
فایل، سریالساز برای مدلهایی که قبلاً تعریف شدهاند ایجاد کنید. شامل SerializerMethodField
برای ایجاد مسیر کامل برای id
رشته.
from rest_framework import serializers
from library.models import Author, Book
class AuthorSerializer(serializers.ModelSerializer):
detail = serializers.SerializerMethodField()
def get_detail(self, obj):
request = self.context.get('request')
if request:
return request.build_absolute_uri(obj.get_absolute_url())
return obj.id
class Meta:
model = Author
fields = '__all__'
class BookSerializer(serializers.ModelSerializer):
detail = serializers.SerializerMethodField()
author = AuthorSerializer()
def get_detail(self, obj):
request = self.context.get('request')
if request:
return request.build_absolute_uri(obj.get_absolute_url())
return obj.id
class Meta:
model = Book
fields = '__all__'
تعریف URL: در library/urls.py
فایل، URL ها را برای نقاط انتهایی API تعریف کنید.
from django.urls import path
from library.views import BookListCreateView, BookRetrieveUpdateDestroyView, AuthorListCreateView
urlpatterns = [
path('books/', BookListCreateView.as_view(), name='book-list-create'),
path('books/<int:pk>/', BookRetrieveUpdateDestroyView.as_view(), name='book-retrieve-update-destroy'),
path('authors/', AuthorListCreateView.as_view(), name='book-list-create'),
]
ایجاد نماها: در library/views.py
فایل، نماهایی برای مدیریت نقاط پایانی API ایجاد کنید.
from rest_framework import generics
from library.models import Book, Author
from library.serializers import BookSerializer, AuthorSerializer
class BookListCreateView(generics.ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
class BookRetrieveUpdateDestroyView(generics.RetrieveUpdateDestroyAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
class AuthorListCreateView(generics.ListCreateAPIView):
queryset = Author.objects.all()
serializer_class = AuthorSerializer
برنامه را در تنظیمات پروژه قرار دهید: در library_project/settings.py
فایل، شامل library
برنامه و پیکربندی چارچوب REST.
INSTALLED_APPS = [
# Other apps...
'library',
'rest_framework',
]
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
]
}
پیوندی به آدرسهای اینترنتی برنامه در فایل urlr.py پروژه اضافه کنید: در library_project/urls.py
فایل، شامل:
from django.contrib import admin
from django.urls import path, include # import include
urlpatterns = [
path('admin/', admin.site.urls),
# include the library app urls module
path('', include('library.urls')),
]
}
Run migrations: مهاجرت های پایگاه داده را برای ایجاد جداول لازم برای مدل ها اعمال کنید:
python manage.py makemigrations
python manage.py migrate
سرور توسعه را راه اندازی کنید: سرور توسعه را برای آزمایش API راه اندازی کنید:
python manage.py runserver
درخواست و پاسخ به این صورت است:
درخواست:
curl --location 'http://127.0.0.1:8000/books/'
واکنش:
[
{
"id": 1,
"detail": "http://127.0.0.1:8000/books/1/",
"author": {
"id": 1,
"detail": "http://127.0.0.1:8000/authors/1/",
"name": "Stephen Nwankwo"
},
"title": "Tales of Ogun"
},
{
"id": 2,
"detail": "http://127.0.0.1:8000/books/2/",
"author": {
"id": 1,
"detail": "http://127.0.0.1:8000/authors/1/",
"name": "Stephen Nwankwo"
},
"title": "Tales of Ogun"
}
]
آیا ما واقعاً به HATEOAS نیاز داریم؟
من تعدادی از APIها را مرور کردم و در واقع با اجرای HATEOS مواجه نشدم. بنابراین در مورد اینکه آیا کسی به آن نیاز دارد یا نه واقعاً به شما بستگی دارد که توسعه دهنده یا مدیر پروژه هستید.
برای کمک به شما در تصمیم گیری، بسته به الزامات و اهداف خاص پروژه شما. در اینجا چند نکته قابل تامل است:
-
قابلیت کشف پیشرفته: HATEOAS ماهیت توصیفی خود را برای APIها فراهم می کند و به مشتریان اجازه می دهد منابع موجود را به صورت پویا کشف و پیمایش کنند. این نیاز مشتریان را به تکیه بر دانش قبلی یا URL های رمزگذاری شده حذف می کند و باعث می شود API بصری تر و استفاده آسان تر باشد.
-
کوپلینگ کاهش یافته: با گنجاندن پیوندها یا ارجاع به منابع مرتبط در پاسخ های API، HATEOAS جفت شدن بین کلاینت ها و سرورها را کاهش می دهد. مشتریان می توانند پیوندهای ارائه شده را برای دسترسی به منابع مختلف دنبال کنند و بدون نیاز به دانستن کل ساختار API از قبل، اقداماتی را انجام دهند. این امر اتصال شل را تقویت می کند و سیستم های انعطاف پذیرتر و قابل گسترش تر را قادر می سازد.
-
مقیاسپذیری بهبود یافته: HATEOAS سرور را قادر میسازد تا تکامل یابد و منابع یا اقدامات جدید را بدون شکستن کلاینتهای موجود اضافه کند. مشتریانی که پیوندهای ارائه شده در پاسخهای API را دنبال میکنند، میتوانند بدون نیاز به تغییر در کد خود، با تغییرات در API سازگار شوند. این باعث میشود که API مقیاسپذیرتر شود و نسخهسازی و سازگاری به عقب را تسهیل کند.
-
سادگی توسعه مشتری: HATEOAS توسعه مشتری را با ارائه یک رویکرد هدایت شده برای تعامل API ساده می کند. مشتریان می توانند به جای ساختن URL ها به صورت دستی یا کدگذاری سخت، به پیوندهای ارائه شده در پاسخ های API تکیه کنند. این باعث کاهش پیچیدگی و خطاهای احتمالی در کد مشتری می شود.
-
سازگاری و مستندسازی: HATEOAS یکپارچگی را ترویج میکند و شکلی از خود مستندسازی را در خود API ارائه میکند. پیوندهای موجود در پاسخها به عنوان مرجعی به اقدامات و منابع موجود عمل میکنند و درک و استفاده مؤثر از API را برای توسعهدهندگان آسانتر میکنند.
با این حال، توجه به این نکته مهم است که اجرای HATEOAS به فرآیند طراحی و توسعه API پیچیدگی میافزاید. این امر مستلزم بررسی دقیق پیوندهایی است که باید در آن گنجانده شوند، ایجاد تعادل بین ارائه اطلاعات کافی و جلوگیری از غلبه بر مشتریان با پیوندهای بیش از حد. علاوه بر این، HATEOAS ممکن است برای همه موارد استفاده از API ضروری یا مناسب نباشد، به خصوص زمانی که دامنه API کوچک است یا تعامل مشتری و سرور ساده است.
در نهایت، تصمیم به استفاده از HATEOAS باید بر اساس عواملی مانند پیچیدگی API شما، سطح مورد نظر از قابلیت کشف و انعطاف پذیری و نیازهای مشتریان شما باشد.
لطفا اگر مقاله را مفید دیدید لایک کنید و نظرات خود را در قسمت نظرات به اشتراک بگذارید.
منابع:
https://learn.microsoft.com/en-us/azure/architecture/best-practices/api-design
https://www.geeksforgeeks.org/hateoas-and-why-its-needed-in-restful-api/
https://www.w3schools.in/restful-web-services/rest-apis-hateoas-concept#google_vignette