تا الان چندین API حرفهای با DRF ساختهاید. فیلتر و جستجو و صفحهبندی دارید. احراز هویت و مجوزها را اضافه کردید. نسخهبندی را هم یاد گرفتید. اما یک چیز هنوز کم است: مستندات. اگر مستندات خوبی نداشته باشید، هیچکس نمیداند چطور از API شما استفاده کند. توسعهدهندهها مجبور میشوند کد شما را بخوانند. وقتشان تلف میشود. احتمال دارد از API شما دوری کنند.
نگهداری مستندات دستی هم تقریباً غیرممکن است. چون هر بار که API را تغییر میدهید، باید مستندات را هم بهروز کنید. یک جا را فراموش میکنید. مستندات از کد جلوتر میماند یا عقب. دیگر نمیشود به آن اعتماد کرد.
راه حل: مستندسازی خودکار.
یک بار ابزار را تنظیم میکنید. بعد هر تغییری در کد بدهید، مستندات خودکار بهروز میشود. همیشه دقیق. همیشه قابل اعتماد. در این درس، دو کتابخانه محبوب را یاد میگیرید. drf-spectacular که نسخه OpenAPI 3.1 تولید میکند و توسط خود DRF توصیه میشود. و drf-yasg که OpenAPI 2 تولید میکند و سالهاست در پروژههای زیادی استفاده شده است.
با Swagger UI آشنا میشوید. یک صفحه تعاملی که توسعهدهندهها میتوانند مستقیماً در مرورگر API شما را تست کنند. بدون Postman، بدون نوشتن کد. ReDoc را هم میبینید. یک خروجی مرتب و خوانا برای مطالعه و چاپ. در انتها یاد میگیرید چطور با docstring و توضیحات داخل ویوها، مستندات را کاملتر کنید.
این درس API شما را از یک محصول خوب به یک محصول حرفهای تبدیل میکند. مستندات خوب یعنی مشتریان راضیتر و زمان پشتیبانی کمتر.
استفاده از drf-yasg
از بین ابزارهای مختلف برای مستندسازی خودکار API در Django، یکی از قدیمیترین و محبوبترینها drf-yasg است. این کتابخانه، مستندات Swagger (نسخه OpenAPI 2.0) را از روی کدهای شما تولید میکند.
نکته مهمی که باید بدانید: drf-yasg دیگر بهروزرسانی فعال ندارد. پروژههای جدید معمولاً از drf-spectacular استفاده میکنند که OpenAPI 3.0 پشتیبانی میکند. اما اگر روی پروژه قدیمی کار میکنید که قبلاً از drf-yasg استفاده میکرده، دانستن نحوه کار با آن برای شما مفید است.
قدم اول: نصب
pip install drf-yasg
اگر میخواهید از قابلیت اعتبارسنجی (Validation) استفاده کنید، بسته کاملتر را نصب کنید:
pip install drf-yasg[validation]
قدم دوم: اضافه کردن به settings.py
# settings.py
INSTALLED_APPS = [
...
'drf_yasg', # اضافه شود
...
]
قدم سوم: تنظیم مسیرها در urls.py
در فایل urls.py اصلی پروژه، تنظیمات زیر را اضافه کنید:
# urls.py
from django.urls import path, include, re_path
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
schema_view = get_schema_view(
openapi.Info(
title="API Documentation", # عنوان API شما
default_version='v1', # نسخه پیشفرض
description="توضیحات API شما", # توضیحات کلی
terms_of_service="https://www.example.com/terms/",
contact=openapi.Contact(email="contact@example.com"),
license=openapi.License(name="BSD License"),
),
public=True, # اگر True باشد، همه میتوانند ببینند
permission_classes=(permissions.AllowAny,), # دسترسی همگانی
)
urlpatterns = [
# مسیرهای معمولی API شما
path('api/', include('myapp.urls')),
# مستندات Swagger
re_path(r'^swagger(?P<format>\.json|\.yaml)$',
schema_view.without_ui(cache_timeout=0),
name='schema-json'),
path('swagger/',
schema_view.with_ui('swagger', cache_timeout=0),
name='schema-swagger-ui'),
path('redoc/',
schema_view.with_ui('redoc', cache_timeout=0),
name='schema-redoc'),
]
قدم چهارم: مشاهده مستندات
بعد از راهاندازی سرور، آدرسهای زیر در دسترس هستند:
| آدرس | توضیح |
| /swagger/ | صفحه تعاملی Swagger UI برای تست API |
| /redoc/ | مستندات خوانا و مرتب ReDoc |
| /swagger.json | فایل مشخصات JSON |
| /swagger.yaml | فایل مشخصات YAML |
سفارشیسازی با @swagger_auto_schema
یکی از قوتهای drf-yasg این است که میتوانید توضیحات API خود را با دکوریتور @swagger_auto_schema سفارشی کنید:
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from rest_framework import generics
class ProductListView(generics.ListAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
@swagger_auto_schema(
operation_description="دریافت لیست همه محصولات",
manual_parameters=[
openapi.Parameter(
'category',
openapi.IN_QUERY,
description="فیلتر بر اساس دستهبندی",
type=openapi.TYPE_STRING
),
],
responses={200: ProductSerializer(many=True)}
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
تنظیمات اضافی در settings.py
میتوانید رفتار Swagger UI را با تنظیمات زیر تغییر دهید:
SWAGGER_SETTINGS = {
'USE_SESSION_AUTH': True, # دکمه لاگین به Swagger اضافه شود
'SECURITY_DEFINITIONS': {
'Basic': {
'type': 'basic'
},
'Bearer': {
'type': 'apiKey',
'name': 'Authorization',
'in': 'header'
}
},
'VALIDATOR_URL': None, # اعتبارسنجی آنلاین را غیرفعال کنید
}
نکته نهایی
drf-yasg یک ابزار قدرتمند است و سالها در پروژههای زیادی استفاده شده. اما برای پروژههای جدید، توصیه میکنم از drf-spectacular استفاده کنید . در بخش بعدی، این ابزار مدرنتر را یاد میگیرید که از OpenAPI 3.0 پشتیبانی میکند.
استفاده از drf-spectacular
اگر بخواهید API خود را با استاندارد مدرن OpenAPI 3 مستند کنید، drf-spectacular انتخاب اول است. این کتابخانه توسط خود DRF توصیه میشود و جایگزین اصلی روش قدیمی drf-yasg شده است .
چرا drf-spectacular؟
مهمترین تفاوت drf-spectacular با drf-yasg در نسخه OpenAPI است. drf-yasg از OpenAPI 2.0 استفاده میکند. در حالی که drf-spectacular از OpenAPI 3.0 و 3.1 پشتیبانی میکند .
استاندارد OpenAPI 3 قابلیتهای بیشتری دارد. مستندات دقیقتری تولید میکند. با ابزارهای مدرنتری هماهنگ است.
علاوه بر این، drf-spectacular:
- به طور فعال بهروزرسانی میشود
- از Django 5 و DRF 3.17 پشتیبانی میکند
- با کتابخانههای محبوب مثل django-filter و SimpleJWT هماهنگ است
قدم اول: نصب
pip install drf-spectacular
اگر میخواهید فایلهای Swagger UI و ReDoc را خودتان روی سرور میزبانی کنید (نه از CDN)، بسته sidecar را هم نصب کنید:
pip install drf-spectacular-sidecar
قدم دوم: تنظیم در settings.py
# settings.py
INSTALLED_APPS = [
...
'rest_framework',
'drf_spectacular', # اضافه شود
]
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}
SPECTACULAR_SETTINGS = {
'TITLE': 'API Documentation', # عنوان API شما
'DESCRIPTION': 'مستندات کامل API پروژه', # توضیحات کلی
'VERSION': '1.0.0',
'SERVE_INCLUDE_SCHEMA': False,
}
خط DEFAULT_SCHEMA_CLASS بسیار مهم است. این خط به DRF میگوید برای تولید schema از drf-spectacular استفاده کند.
قدم سوم: تنظیم مسیرها در urls.py
# urls.py
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView, SpectacularRedocView
urlpatterns = [
# مسیرهای معمولی API شما
path('api/', include('myapp.urls')),
# خروجی JSON schema
path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
# Swagger UI (رابط تعاملی)
path('api/docs/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
# ReDoc (مستندات خوانا)
path('api/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
]
قدم چهارم: مشاهده مستندات
بعد از راهاندازی سرور، مستندات شما در آدرسهای زیر در دسترس است:
| آدرس | توضیح |
| /api/docs/ | Swagger UI. صفحه تعاملی که میتوانید API را تست کنید |
| /api/redoc/ | ReDoc. مستندات مرتب و خوانا برای مطالعه |
| /api/schema/ | فایل OpenAPI خام (فرمت JSON) |
سفارشیسازی با @extend_schema
یکی از قوتهای drf-spectacular دکوریتور @extend_schema است. با آن میتوانید توضیحات API خود را کامل کنید
from drf_spectacular.utils import extend_schema, OpenApiParameter, OpenApiExample
from rest_framework import generics
class ProductListView(generics.ListAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
@extend_schema(
summary="دریافت لیست محصولات",
description="لیست همه محصولات را برمیگرداند. قابل فیلتر با دستهبندی.",
parameters=[
OpenApiParameter(
name='category',
type=str,
location=OpenApiParameter.QUERY,
description='فیلتر بر اساس نام دستهبندی',
required=False,
),
],
responses={200: ProductSerializer(many=True)},
examples=[
OpenApiExample(
'مثال موفق',
value=[{'id': 1, 'name': 'لپتاپ', 'price': 1200}],
response_only=True,
),
],
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
تنظیمات پیشرفته در SPECTACULAR_SETTINGS
میتوانید رفتار مستندات را با تنظیمات زیر سفارشی کنید:
SPECTACULAR_SETTINGS = {
'TITLE': 'API Documentation',
'DESCRIPTION': 'مستندات کامل API',
'VERSION': '1.0.0',
'SERVE_INCLUDE_SCHEMA': False,
'SWAGGER_UI_DIST': 'SIDECAR', # اگر از sidecar استفاده میکنید
'REDOC_DIST': 'SIDECAR',
'TAGS': ['products', 'users', 'orders'], # دستهبندی endpoints
'SCHEMA_PATH_PREFIX': '/api/', # پیشوند مسیرها
}
خروجی schema با دستور مدیریتی
میتوانید فایل schema را در ترمینال هم تولید کنید:
python manage.py spectacular --file schema.yaml
این فایل برای ابزارهای خودکار مثل تولید SDK در زبانهای مختلف قابل استفاده است .
نکته مهم درباره drf-yasg
اگر پروژهتان از drf-yasg استفاده میکند، مهاجرت به drf-spectacular امکانپذیر است. دکوریتور @swagger_auto_schema با @extend_schema معادل است . اما اگر پروژه جدیدی شروع میکنید، مستقیماً از drf-spectacular استفاده کنید.
ایجاد Swagger UI و Redoc
بعد از نصب و تنظیم drf-spectacular، حالا میتوانید مستندات API خود را ببینید. دو صفحه اصلی در اختیار دارید. هر کدام برای یک هدف خاص طراحی شده است.
Swagger UI
صفحه تعاملی برای تست API. کاربر میتواند بدون نوشتن کد، درخواست بفرستد و خروجی را ببیند.
آدرس این صفحه معمولاً /api/docs/ یا /swagger/ است. بعد از تنظیم مسیرها در urls.py، کافی است مرورگر را باز کنید.
http://127.0.0.1:8000/api/docs/
در این صفحه چه میبینید؟
لیست همه endpointهای API شما. هر کدام با متدهای HTTP مجاز (GET، POST، PUT، DELETE). دکمه "Try it out" که با کلیک روی آن میتوانید پارامترها را وارد کنید و درخواست بفرستید. خروجی سرور در همان صفحه نشان داده میشود.
برای تست API نیازی به Postman ندارید. همه چیز در مرورگر انجام میشود.
ReDoc
صفحه مستندات ایستا و خوانا. برای مطالعه و چاپ طراحی شده است. خبری از دکمه Try it out نیست. فقط توضیحات، پارامترها، و نمونه خروجیها را نشان میدهد.
آدرس این صفحه:
http://127.0.0.1:8000/api/redoc/
ReDoc برای توسعهدهندهای که میخواهد مستندات API را بخواند و با ساختار آن آشنا شود، عالی است. ظاهر مرتبی دارد. دستهبندی endpointها را خوب نشان میدهد.
تفاوت این دو صفحه
| ویژگی | Swagger UI | ReDoc |
| تعاملی | بله (میتوانید تست کنید) | خیر |
| مناسب برای | تست و توسعه | مطالعه و مرور |
| نمایش پارامترها | بله، با فرم ورودی | بله، به صورت متن |
| سرعت بارگذاری | کمی کندتر | سریعتر |
| استفاده از | توسعهدهنده در حین کار | خواندن و مستندات |
سفارشیسازی ظاهر Swagger UI
میتوانید ظاهر Swagger UI را تغییر دهید. مثلاً ترتیب endpointها را بر اساس دستهبندی مرتب کنید.
در فایل settings.py، به SPECTACULAR_SETTINGS اضافه کنید:
SPECTACULAR_SETTINGS = {
...
'TAGS': [
{'name': 'products', 'description': 'عملیات مربوط به محصولات'},
{'name': 'users', 'description': 'عملیات مربوط به کاربران'},
{'name': 'orders', 'description': 'عملیات مربوط به سفارشها'},
],
}
سپس در ویوها، هر کدام را به یک تگ اختصاص دهید:
@extend_schema(tags=['products'])
class ProductListView(ListAPIView):
...
حالا در Swagger UI، endpointها بر اساس تگها دستهبندی میشوند.
افزودن احراز هویت به Swagger UI
اگر API شما نیاز به توکن دارد، باید دکمه "Authorize" را در Swagger UI فعال کنید.
در settings.py:
SPECTACULAR_SETTINGS = {
...
'SWAGGER_UI_SETTINGS': {
'persistAuthorization': True, # توکن را در مرورگر نگه دارد
},
'SECURITY': [{'BearerAuth': []}],
}
# اضافه کردن تعریف امنیت
REST_FRAMEWORK = {
...
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}
SPECTACULAR_SETTINGS['SECURITY_DEFINITIONS'] = {
'BearerAuth': {
'type': 'apiKey',
'name': 'Authorization',
'in': 'header',
'description': 'توکن خود را به این شکل وارد کنید: Token your_token_here',
},
}
حالا در صفحه Swagger UI، یک دکمه "Authorize" ظاهر میشود. کاربر توکن خود را وارد میکند و میتواند APIهای نیازمند احراز هویت را تست کند.
اگر صفحه سفید دیدید
گاهی بعد از تنظیم، Swagger UI درست کار نمیکند و صفحه سفید نشان میدهد.
بررسی کنید:
- آیا سرور را بعد از تغییرات ریستارت کردهاید؟
- آیا آدرس درست را وارد کردهاید؟ (/api/docs/ نه /api/schema/)
- آیا در urls.py از SpectacularSwaggerView.as_view(url_name='schema') استفاده کردهاید؟
- ترمینال را نگاه کنید. خطایی وجود دارد؟
تمرین
یک پروژه ساده با دو API بسازید. یکی برای محصولات، یکی برای کاربران. drf-spectacular را نصب و تنظیم کنید.
Swagger UI را باز کنید. هر دو API را ببینید. دکمه Try it out را بزنید و درخواست بفرستید.
سپس ReDoc را باز کنید. تفاوت ظاهر این دو صفحه را مقایسه کنید.
توضیح سرگذاری با docstring در ویوها
docstring همان توضیحاتی است که در ابتدای یک تابع یا کلاس مینویسید. در پایتون، این توضیحات با سه کوتیون شروع و تمام میشوند.
این توضیحات معمولاً برای برنامهنویسی دیگر نوشته میشوند. اما در drf-spectacular، این docstringها میتوانند مستقیماً به مستندات API شما تبدیل شوند.
docstring در سطح ویو
وقتی برای یک ویو توضیح مینویسید، drf-spectacular آن را به عنوان توضیحات کلی آن endpoint در نظر میگیرد.
from rest_framework import generics
from .models import Product
from .serializers import ProductSerializer
class ProductListView(generics.ListAPIView):
"""
دریافت لیست همه محصولات
این endpoint لیست کامل محصولات را برمیگرداند.
"""
queryset = Product.objects.all()
serializer_class = ProductSerializer
نتیجه در Swagger UI و ReDoc: همان متنی که در docstring نوشتهاید، در بخش توضیحات endpoint نمایش داده میشود.
docstring در سطح متد
اگر از APIView استفاده میکنید، میتوانید برای هر متد جداگانه توضیح بنویسید:
from rest_framework.views import APIView
from rest_framework.response import Response
class ProductDetailView(APIView):
def get(self, request, pk):
"""
دریافت جزئیات یک محصول
شناسه محصول را بگیرید و اطلاعات کامل آن را برگردانید.
"""
product = Product.objects.get(pk=pk)
serializer = ProductSerializer(product)
return Response(serializer.data)
def delete(self, request, pk):
"""
حذف یک محصول
این عملیات فقط برای ادمین مجاز است.
"""
product = Product.objects.get(pk=pk)
product.delete()
return Response(status=204)
در Swagger UI، هر متد توضیحات جداگانه خود را دارد.
فرمت docstring
میتوانید docstring را ساده بنویسید. drf-spectacular محتوای آن را بدون تغییر به مستندات منتقل میکند.
"""
این یک توضیح ساده است.
میتوانید چند خط بنویسید.
نویسنده: ...
تاریخ: ...
"""
نیازی به فرمت خاصی نیست. هر چیزی که بنویسید، همان طور نمایش داده میشود.
تفاوت docstring با decorator @extend_schema
این دو مستقل از هم کار میکنند. drf-spectacular ابتدا docstring را میخواند، سپس @extend_schema را. اگر هر دو را نوشته باشید، هر دو تأثیر دارند.
@extend_schema(
summary="لیست محصولات",
description="توضیحات اضافه از طریق دکوریتور"
)
class ProductListView(generics.ListAPIView):
"""
دریافت لیست همه محصولات
این endpoint لیست کامل محصولات را برمیگرداند.
"""
queryset = Product.objects.all()
serializer_class = ProductSerializer
در این مثال، توضیحات نهایی ترکیبی از docstring و @extend_schema خواهد بود. summary فقط از دکوریتور میآید. description هر دو را میتواند شامل شود.
اگر از ViewSet استفاده میکنید
در ViewSet، میتوانید docstring را هم در سطح کلاس بنویسید، هم در سطح اکشن:
from rest_framework.viewsets import ModelViewSet
class ProductViewSet(ModelViewSet):
"""
عملیات CRUD برای محصولات
این ViewSet شامل لیست، ساخت، جزئیات، بروزرسانی و حذف است.
"""
queryset = Product.objects.all()
serializer_class = ProductSerializer
def list(self, request):
"""
دریافت لیست همه محصولات با صفحهبندی
"""
return super().list(request)
def create(self, request):
"""
ساخت محصول جدید
فقط کاربران لاگین شده میتوانند محصول بسازند.
"""
return super().create(request)
docstring کلاس ViewSet به عنوان توضیحات کلی نمایش داده میشود. docstring هر متد هم در عملیات مربوطه ظاهر میشود.
آیا drf-spectacular خودکار docstring را میخواند؟
بله. بدون نیاز به تنظیم اضافه. به محض اینکه drf-spectacular را فعال کنید، شروع به خواندن docstringها میکند.
تنها شرط این است که DEFAULT_SCHEMA_CLASS را به درستی تنظیم کرده باشید:
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}
نکات مهم
docstring جایگزین @extend_schema نیست. اگر نیاز به تنظیمات خاصی دارید، از دکوریتور استفاده کنید.
میتوانید docstring را به زبان فارسی بنویسید. drf-spectacular آن را بدون مشکل نمایش میدهد.
اگر docstring خیلی طولانی است، در Swagger UI ممکن است قسمتی از آن مخفی شود. برای توضیحات کوتاه و مفید مناسب است.
تمرین
API خود را باز کنید. به یکی از ویوها یک docstring ساده اضافه کنید. مثلاً:
"""
لیست همه مقالات با امکان فیلتر بر اساس نویسنده
"""
سپس Swagger UI را رفرش کنید. ببینید توضیحات شما در کجا نمایش داده میشود.
جمع بندی این درس
در این درس، با ابزارهایی آشنا شدید که API شما را از یک محصول خوب به یک محصول حرفهای تبدیل میکند. drf-yasg را دیدید. کتابخانه قدیمی اما همچنان پرکاربرد که مستندات Swagger (OpenAPI 2.0) تولید میکند. برای پروژههایی که سالها پیش شروع شدهاند، همچنان انتخاب رایجی است. drf-spectacular را یاد گرفتید. ابزار مدرن و توصیه شده توسط خود DRF. از OpenAPI 3.0 پشتیبانی میکند. به طور فعال بهروزرسانی میشود. برای پروژههای جدید، انتخاب اول است.
با Swagger UI آشنا شدید. صفحه تعاملی که توسعهدهنده میتواند بدون Postman، مستقیماً در مرورگر API را تست کند. دکمه "Try it out" برای هر endpoint، فرم ورودی، و نمایش خروجی. ReDoc را دیدید. نسخه خوانا و مرتب مستندات. برای مطالعه و چاپ عالی است. بدون ابزارهای اضافی، فقط توضیحات و پارامترها و نمونه خروجی. در انتها یاد گرفتید چطور با docstringها، مستندات خود را غنیتر کنید. بدون کد اضافه، فقط با نوشتن توضیحات در بالای ویوها.
از این درس چه چیزی باید به خاطر بسپارید؟
- مستندات خودکار را از روز اول فعال کنید. یک بار تنظیم میشود و تا آخر عمر API همراه شماست.
- drf-spectacular را برای پروژههای جدید انتخاب کنید. نه drf-yasg. چون استاندارد OpenAPI 3.0 را پشتیبانی میکند.
- Swagger UI و ReDoc را هر دو در دسترس بگذارید. هر کدام کاربرد متفاوتی دارد.
- docstring بنویسید. حتی یک خط توضیح کوتاه، ارزشش را دارد.
- اگر API عمومی است، مستندات را در دسترس همه قرار دهید. اگر خصوصی است، با مجوزها محدودیت بگذارید.
درس بعدی چیست؟
حالا API شما مستندات حرفهای دارد. هر کسی میتواند ببیند چطور از آن استفاده کند. اما یک سؤال باقی میماند: آیا API شما درست کار میکند؟
تا الان همه تستها را دستی انجام دادهاید. با مرورگر یا Postman. اما پروژه که بزرگ میشود، تست دستی دیگر جواب نمیدهد. یک جا را فراموش میکنید. یک باگ در محیط تولید دیر متوجه میشوید.
در درس بعدی، با تست نویسی در DRF آشنا میشوید. یاد میگیرید چطور با کد، API خود را تست کنید. قبل از اینکه به دست کاربر برسد، مطمئن شوید همه چیز درست کار میکند.