Swagger چیست؟ آموزش OpenAPI و ساخت مستندات API هوش مصنوعی با FastAPI
Swagger و OpenAPI به توسعهدهندگان کمک میکنند ساختار API، ورودیها، پاسخها، احراز هویت و خطاها را بهصورت استاندارد مستند کنند. در این آموزش، تفاوت Swagger و OpenAPI را بررسی میکنیم و یک API واقعی تولید متن با FastAPI، Swagger UI و API درواره میسازیم.
اگر یک API بدون مستندات در اختیار تیم فرانتاند، اپلیکیشن موبایل یا مشتریان قرار دهید، احتمالاً اولین پرسشهایی که دریافت میکنید اینها خواهند بود:
- آدرس Endpoint چیست؟
- درخواست باید با
GETارسال شود یاPOST؟ - بدنه درخواست چه ساختاری دارد؟
- کدام فیلدها اجباری هستند؟
- کلید API را در کدام Header قرار دهیم؟
- پاسخ موفق چه شکلی است؟
- خطاهای ۴۰۰، ۴۰۱، ۴۲۲، ۴۲۹ و ۵۰۰ چه معنایی دارند؟
- آیا نمونه درخواست برای Python یا JavaScript وجود دارد؟
Swagger و OpenAPI برای حل همین مشکل ساخته شدهاند. با استفاده از آنها میتوان قرارداد API را به شکلی استاندارد و قابلخواندن برای انسان و نرمافزار تعریف کرد.
در این مقاله علاوه بر توضیح مفاهیم، یک پروژه واقعی میسازیم: یک API تولید متن که درخواست کاربر را دریافت میکند، آن را از طریق API درواره به مدل هوش مصنوعی میفرستد و پاسخ را در قالبی مشخص برمیگرداند.
این پروژه بهصورت خودکار دارای Swagger UI، اعتبارسنجی ورودی، احراز هویت، مستندات خطا و فایل OpenAPI خواهد بود.
Swagger چیست؟
Swagger نام مجموعهای از ابزارهای طراحی، مستندسازی، آزمایش و تولید کد برای APIها است.
برخی از ابزارهای شناختهشده خانواده Swagger عبارتاند از:
- Swagger UI
- Swagger Editor
- Swagger Codegen
- Swagger Core
- Swagger CLI
Swagger در ابتدا نام یک Specification برای توصیف APIهای REST بود. این Specification بعداً به پروژه OpenAPI Initiative منتقل شد و نام آن به OpenAPI Specification تغییر کرد.
به همین دلیل، امروزه اصطلاحهای Swagger و OpenAPI گاهی بهجای یکدیگر استفاده میشوند؛ اما از نظر دقیق، این دو یکسان نیستند.
OpenAPI چیست؟
OpenAPI Specification یا OAS یک استاندارد برای توصیف APIهای مبتنی بر HTTP است.
یک سند OpenAPI میتواند مشخص کند:
- چه Endpointهایی در API وجود دارند.
- هر Endpoint از چه متد HTTP استفاده میکند.
- پارامترهای Path و Query چیست.
- بدنه درخواست چه ساختاری دارد.
- پاسخ موفق چگونه است.
- چه خطاهایی ممکن است برگردانده شوند.
- API از چه روش احراز هویتی استفاده میکند.
- آدرس محیط Production و آزمایشی چیست.
- هر فیلد چه نوع داده و محدودیتی دارد.
OpenAPI Initiative این استاندارد را یک روش رسمی برای توصیف HTTP APIها معرفی میکند. چنین توصیفی میتواند برای مستندسازی، تولید Client، ساخت تست و اعمال استانداردهای طراحی API استفاده شود.
فایل OpenAPI معمولاً با یکی از قالبهای زیر نوشته میشود:
- YAML
- JSON
نمونه بسیار ساده:
openapi: 3.1.0
info:
title: AI Text API
version: 1.0.0
paths:
/v1/generate:
post:
summary: Generate text
responses:
"200":
description: Successful response
این فایل به ابزارهایی مانند Swagger UI اجازه میدهد مستندات تعاملی API را تولید کنند.
تفاوت Swagger و OpenAPI چیست؟
| اصطلاح | تعریف |
|---|---|
| OpenAPI | استاندارد توصیف ساختار API |
| Swagger UI | رابط گرافیکی برای نمایش و آزمایش OpenAPI |
| Swagger Editor | محیط نوشتن و اعتبارسنجی فایل OpenAPI |
| Swagger Codegen | ابزار تولید Client SDK یا Server Stub |
| Swagger | نام خانواده ابزارهایی که با OpenAPI کار میکنند |
به زبان ساده، OpenAPI مانند نقشه فنی ساختمان است و Swagger UI ابزاری است که این نقشه را به شکل قابلفهم و تعاملی نمایش میدهد.
Swagger UI چیست؟
Swagger UI فایل OpenAPI را دریافت و آن را به یک صفحه مستندات تعاملی تبدیل میکند.
در این صفحه توسعهدهنده میتواند:
- Endpointها را مشاهده کند.
- Schema ورودی و خروجی را ببیند.
- پارامترها را وارد کند.
- کلید API را تنظیم کند.
- با گزینه
Try it outدرخواست واقعی بفرستد. - کد وضعیت و پاسخ سرور را بررسی کند.
- نمونه درخواست
curlدریافت کند.
Swagger UI برای نمایش تعاملی تعریفهای OpenAPI طراحی شده است.
چرا مستندسازی APIهای هوش مصنوعی مهمتر است؟
APIهای هوش مصنوعی معمولاً فقط چند فیلد ساده دریافت نمیکنند. این APIها ممکن است تنظیماتی مانند موارد زیر داشته باشند:
- شناسه مدل
- پیامهای System و User
- Temperature
- محدودیت طول خروجی
- ابزارهای قابل فراخوانی
- خروجی ساختاریافته
- ورودی تصویر یا فایل
- Streaming
- شناسه کاربر یا پروژه
- Webhook
- وضعیت اجرای غیرهمزمان
اگر این فیلدها مستند نشوند، توسعهدهنده نمیداند هر مقدار چه اثری بر خروجی، هزینه یا زمان پاسخ دارد.
مستندات دقیق همچنین کمک میکند تیمها تفاوت میان خطاهای ورودی، محدودیت نرخ، Timeout و خطای سرویس مدل را تشخیص دهند.
اجزای اصلی یک سند OpenAPI
بخش openapi
نسخه Specification را مشخص میکند:
openapi: 3.1.0
نسخه OpenAPI با نسخه نرمافزار یا API شما یکسان نیست. برای مثال، ممکن است سند شما از OpenAPI 3.1 استفاده کند اما نسخه تجاری API برابر 2.4.0 باشد.
بخش info
اطلاعات اصلی API در این بخش قرار میگیرد:
info:
title: Darvareh AI Gateway
version: 1.0.0
description: API for generating Persian content
بخش servers
آدرس محیطهای مختلف را مشخص میکند:
servers:
- url: https://api.example.com
description: Production
- url: https://staging-api.example.com
description: Staging
بخش paths
تمام Endpointها و عملیات آنها در این قسمت تعریف میشوند:
paths:
/v1/generate:
post:
summary: Generate Persian text
بخش components
Schemaهای قابلاستفاده مجدد، روشهای احراز هویت، Headerها و پاسخهای مشترک در این قسمت تعریف میشوند.
components:
schemas:
GenerateRequest:
type: object
properties:
prompt:
type: string
بخش security
روش احراز هویت را مشخص میکند:
components:
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
رویکرد Code First و Design First
برای ساخت مستندات OpenAPI دو روش اصلی وجود دارد.
روش Code First
ابتدا API را در فریمورکی مانند FastAPI مینویسید. سپس فریمورک فایل OpenAPI را از روی Routeها، مدلها و Type Hintها تولید میکند.
این روش برای پروژههایی مناسب است که:
- تیم کوچکتری دارند.
- API همراه با کد توسعه پیدا میکند.
- سرعت پیادهسازی اهمیت دارد.
- از FastAPI، NestJS یا Spring Boot استفاده میکنند.
روش Design First
ابتدا قرارداد OpenAPI نوشته میشود. سپس تیمهای Backend، Frontend و Mobile بر اساس همان قرارداد توسعه را آغاز میکنند.
این روش برای پروژههایی مناسب است که:
- چند تیم روی یک محصول کار میکنند.
- API عمومی یا سازمانی است.
- قرارداد باید پیش از پیادهسازی تأیید شود.
- چند زبان برنامهنویسی در پروژه استفاده میشود.
- Client SDK از روی قرارداد تولید میشود.
در پروژههای بزرگ میتوان از ترکیب هر دو روش استفاده کرد؛ اما باید فقط یک منبع نهایی حقیقت یا Source of Truth وجود داشته باشد.
پروژه عملی: ساخت API تولید متن با Swagger و درواره
در این پروژه یک API با Endpoint زیر میسازیم:
POST /v1/generate
این Endpoint:
- درخواست کاربر را دریافت میکند.
- کلید دسترسی اپلیکیشن را بررسی میکند.
- ورودی را با Pydantic اعتبارسنجی میکند.
- درخواست را به API درواره میفرستد.
- خروجی مدل را در قالب مشخص برمیگرداند.
- خطاهای متداول را به پاسخ استاندارد تبدیل میکند.
- مستندات Swagger UI را بهصورت خودکار تولید میکند.
نکته مهم این است که کلید API درواره باید فقط در Backend نگهداری شود. نباید آن را داخل کد JavaScript مرورگر یا اپلیکیشن عمومی قرار دهید.
ساخت پروژه
پوشه پروژه را ایجاد کنید:
mkdir swagger-ai-api
cd swagger-ai-api
محیط مجازی پایتون را بسازید:
python -m venv .venv
فعالسازی در Linux و macOS:
source .venv/bin/activate
فعالسازی در Windows PowerShell:
.venv\Scripts\Activate.ps1
وابستگیها را نصب کنید:
pip install fastapi uvicorn openai pydantic python-dotenv
تنظیم متغیرهای محیطی
فایل .env را ایجاد کنید:
DARVAREH_API_KEY=YOUR_DARVAREH_API_KEY
DARVAREH_MODEL=YOUR_MODEL_ID
APP_API_KEY=change-this-long-random-value
کاربرد متغیرها:
DARVAREH_API_KEY: کلید اتصال Backend به دروارهDARVAREH_MODEL: شناسه مدل انتخابشدهAPP_API_KEY: کلیدی که Clientهای اپلیکیشن شما برای دسترسی به API داخلی استفاده میکنند
شناسه مدل را از فهرست مدلهای فعلی درواره انتخاب کنید.
کد کامل FastAPI
فایل main.py را ایجاد کنید:
import os
import secrets
from typing import Annotated
from dotenv import load_dotenv
from fastapi import Depends, FastAPI, HTTPException, Security, status
from fastapi.security import APIKeyHeader
from openai import (
APIConnectionError,
APIStatusError,
APITimeoutError,
AsyncOpenAI,
RateLimitError,
)
from pydantic import BaseModel, ConfigDict, Field
load_dotenv()
DARVAREH_API_KEY = os.environ["DARVAREH_API_KEY"]
MODEL_ID = os.environ["DARVAREH_MODEL"]
APP_API_KEY = os.environ["APP_API_KEY"]
client = AsyncOpenAI(
api_key=DARVAREH_API_KEY,
base_url="https://api.darvareh.ir/v1",
)
app = FastAPI(
title="Persian AI Text API",
summary="API تولید متن فارسی با مدلهای هوش مصنوعی",
description=(
"این API یک ورودی متنی دریافت میکند و با استفاده از "
"مدل انتخابشده در درواره پاسخ تولید میکند."
),
version="1.0.0",
docs_url="/docs",
redoc_url="/redoc",
openapi_url="/openapi.json",
contact={
"name": "API Support",
"url": "https://example.com/support",
},
)
api_key_header = APIKeyHeader(
name="X-API-Key",
scheme_name="ApplicationApiKey",
description="کلید دسترسی اپلیکیشن",
auto_error=False,
)
class ErrorResponse(BaseModel):
code: str = Field(
description="کد قابلپردازش خطا",
examples=["rate_limit_exceeded"],
)
message: str = Field(
description="توضیح قابلنمایش خطا",
examples=["تعداد درخواستها بیش از حد مجاز است."],
)
class GenerateRequest(BaseModel):
model_config = ConfigDict(
json_schema_extra={
"examples": [
{
"prompt": "یک توضیح کوتاه برای محصول قهوه عربیکا بنویس.",
"system_prompt": (
"شما یک نویسنده حرفهای محتوای فروشگاهی هستید."
),
"temperature": 0.4,
"max_output_tokens": 300,
}
]
}
)
prompt: str = Field(
min_length=3,
max_length=4000,
description="دستور یا متن ورودی کاربر",
)
system_prompt: str = Field(
default="شما یک دستیار فارسی دقیق و حرفهای هستید.",
min_length=3,
max_length=2000,
description="دستور سطح سیستم برای تعیین رفتار مدل",
)
temperature: float = Field(
default=0.3,
ge=0,
le=2,
description="میزان تنوع احتمالی پاسخ",
)
max_output_tokens: int = Field(
default=500,
ge=1,
le=4000,
description="حداکثر تعداد توکن خروجی",
)
class GenerateResponse(BaseModel):
model: str = Field(
description="شناسه مدل استفادهشده",
examples=["your-model-id"],
)
content: str = Field(
description="متن تولیدشده توسط مدل",
examples=["قهوه عربیکا با عطر متعادل و طعمی نرم..."],
)
finish_reason: str | None = Field(
default=None,
description="دلیل پایان تولید پاسخ",
examples=["stop"],
)
async def require_application_api_key(
api_key: Annotated[str | None, Security(api_key_header)],
) -> None:
if (
not api_key
or not secrets.compare_digest(api_key, APP_API_KEY)
):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail={
"code": "invalid_api_key",
"message": "کلید دسترسی معتبر نیست.",
},
)
@app.get(
"/health",
summary="بررسی سلامت سرویس",
tags=["System"],
)
async def health_check() -> dict[str, str]:
return {"status": "ok"}
@app.post(
"/v1/generate",
response_model=GenerateResponse,
summary="تولید متن با هوش مصنوعی",
description=(
"ورودی فارسی را دریافت کرده و از طریق API درواره "
"به مدل انتخابشده ارسال میکند."
),
tags=["AI Generation"],
dependencies=[Depends(require_application_api_key)],
responses={
401: {
"model": ErrorResponse,
"description": "کلید دسترسی نامعتبر است.",
},
422: {
"description": "ساختار یا مقدار ورودی معتبر نیست.",
},
429: {
"model": ErrorResponse,
"description": "محدودیت تعداد درخواستها",
},
502: {
"model": ErrorResponse,
"description": "خطا در سرویس مدل",
},
504: {
"model": ErrorResponse,
"description": "پایان مهلت پاسخ سرویس مدل",
},
},
)
async def generate_text(
payload: GenerateRequest,
) -> GenerateResponse:
try:
completion = await client.chat.completions.create(
model=MODEL_ID,
messages=[
{
"role": "system",
"content": payload.system_prompt,
},
{
"role": "user",
"content": payload.prompt,
},
],
temperature=payload.temperature,
max_tokens=payload.max_output_tokens,
)
except RateLimitError as error:
raise HTTPException(
status_code=status.HTTP_429_TOO_MANY_REQUESTS,
detail={
"code": "rate_limit_exceeded",
"message": "ظرفیت درخواست تکمیل است؛ دوباره تلاش کنید.",
},
) from error
except APITimeoutError as error:
raise HTTPException(
status_code=status.HTTP_504_GATEWAY_TIMEOUT,
detail={
"code": "model_timeout",
"message": "پاسخ مدل در زمان مقرر دریافت نشد.",
},
) from error
except APIConnectionError as error:
raise HTTPException(
status_code=status.HTTP_502_BAD_GATEWAY,
detail={
"code": "model_connection_error",
"message": "ارتباط با سرویس مدل برقرار نشد.",
},
) from error
except APIStatusError as error:
raise HTTPException(
status_code=status.HTTP_502_BAD_GATEWAY,
detail={
"code": "model_api_error",
"message": "سرویس مدل پاسخ موفقی برنگرداند.",
},
) from error
message = completion.choices[0].message.content
if not message:
raise HTTPException(
status_code=status.HTTP_502_BAD_GATEWAY,
detail={
"code": "empty_model_response",
"message": "پاسخ قابلاستفادهای از مدل دریافت نشد.",
},
)
return GenerateResponse(
model=MODEL_ID,
content=message,
finish_reason=completion.choices[0].finish_reason,
)
اجرای پروژه
سرور توسعه را اجرا کنید:
uvicorn main:app --reload
پس از اجرا، آدرسهای زیر در دسترس خواهند بود:
Swagger UI:
http://127.0.0.1:8000/docs
ReDoc:
http://127.0.0.1:8000/redoc
OpenAPI JSON:
http://127.0.0.1:8000/openapi.json
FastAPI بهصورت پیشفرض Swagger UI را در /docs، رابط ReDoc را در /redoc و Schema استاندارد OpenAPI را در /openapi.json ارائه میکند. این مسیرها قابل تغییر یا غیرفعالکردن هستند.
آزمایش API در Swagger UI
مرورگر را باز کرده و وارد آدرس زیر شوید:
http://127.0.0.1:8000/docs
سپس:
- روی دکمه
Authorizeکلیک کنید. - مقدار
APP_API_KEYرا وارد کنید. - Endpoint مربوط به
POST /v1/generateرا باز کنید. - روی
Try it outکلیک کنید. - بدنه درخواست را ویرایش کنید.
- گزینه
Executeرا انتخاب کنید.
نمونه درخواست:
{
"prompt": "برای یک فروشگاه آنلاین قهوه، توضیح محصول کوتاه بنویس.",
"system_prompt": "شما نویسنده حرفهای محتوای فروشگاهی هستید.",
"temperature": 0.4,
"max_output_tokens": 300
}
نمونه پاسخ:
{
"model": "your-model-id",
"content": "قهوه عربیکای تازهبرشت با عطر دلنشین، اسیدیته متعادل و طعمی نرم؛ انتخابی مناسب برای شروع یک روز پرانرژی.",
"finish_reason": "stop"
}
Swagger UI علاوه بر پاسخ، کد وضعیت، Headerها، مدت درخواست و نمونه دستور curl را نیز نمایش میدهد.
ارسال درخواست با curl
همین Endpoint را میتوان بیرون از Swagger نیز آزمایش کرد:
curl --request POST \
--url http://127.0.0.1:8000/v1/generate \
--header "Content-Type: application/json" \
--header "X-API-Key: change-this-long-random-value" \
--data '{
"prompt": "سه عنوان برای مقاله آموزش هوش مصنوعی پیشنهاد بده.",
"system_prompt": "پاسخ را به زبان فارسی و خلاصه بنویس.",
"temperature": 0.5,
"max_output_tokens": 200
}'
ساخت OpenAPI بهصورت دستی
FastAPI فایل OpenAPI را از روی کد تولید میکند، اما در روش Design First میتوانید قرارداد را دستی بنویسید.
نمونه قرارداد خلاصهشده پروژه:
openapi: 3.1.0
info:
title: Persian AI Text API
version: 1.0.0
description: API تولید متن فارسی با مدلهای هوش مصنوعی
servers:
- url: https://api.example.com
paths:
/v1/generate:
post:
summary: تولید متن با هوش مصنوعی
security:
- ApiKeyAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/GenerateRequest"
responses:
"200":
description: پاسخ با موفقیت تولید شد
content:
application/json:
schema:
$ref: "#/components/schemas/GenerateResponse"
"401":
description: کلید دسترسی نامعتبر است
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"429":
description: محدودیت تعداد درخواستها
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
components:
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
schemas:
GenerateRequest:
type: object
required:
- prompt
properties:
prompt:
type: string
minLength: 3
maxLength: 4000
example: یک توضیح محصول کوتاه بنویس.
system_prompt:
type: string
default: شما یک دستیار فارسی دقیق هستید.
temperature:
type: number
minimum: 0
maximum: 2
default: 0.3
max_output_tokens:
type: integer
minimum: 1
maximum: 4000
default: 500
GenerateResponse:
type: object
required:
- model
- content
properties:
model:
type: string
content:
type: string
finish_reason:
type:
- string
- "null"
ErrorResponse:
type: object
required:
- code
- message
properties:
code:
type: string
message:
type: string
مستندسازی درست خطاها
یکی از اشتباهات رایج این است که فقط پاسخ موفق 200 مستند شود.
یک API عملی باید خطاهای مهم را نیز تعریف کند:
| کد وضعیت | کاربرد |
|---|---|
| 400 | درخواست از نظر منطقی نامعتبر است |
| 401 | کلید یا اطلاعات احراز هویت معتبر نیست |
| 403 | کاربر اجازه اجرای عملیات را ندارد |
| 404 | منبع موردنظر پیدا نشد |
| 409 | درخواست با وضعیت فعلی منبع تعارض دارد |
| 422 | ورودی با Schema سازگار نیست |
| 429 | محدودیت نرخ درخواست رد شده است |
| 500 | خطای داخلی برنامه |
| 502 | سرویس بالادستی پاسخ نامعتبر داده است |
| 504 | سرویس بالادستی در زمان مقرر پاسخ نداده است |
بهتر است تمام خطاهای API ساختاری ثابت داشته باشند:
{
"code": "rate_limit_exceeded",
"message": "تعداد درخواستها بیش از حد مجاز است.",
"request_id": "req_92f1a"
}
فیلد code برای تصمیمگیری نرمافزار و message برای نمایش یا ثبت توضیح استفاده میشود.
مستندسازی احراز هویت
اگر API شما از API Key استفاده میکند، آن را بهصورت securitySchemes تعریف کنید. نوشتن جمله «کلید را در Header بگذارید» کافی نیست.
تعریف استاندارد باعث میشود:
- دکمه
Authorizeدر Swagger UI نمایش داده شود. - Clientهای تولیدشده روش احراز هویت را بشناسند.
- تستهای خودکار Header لازم را اضافه کنند.
- نام Header برای تمام مصرفکنندگان یکسان باشد.
هرگز کلید واقعی API را در مثالها، فایل OpenAPI عمومی یا Repository قرار ندهید.
مستندسازی APIهای Streaming
اگر API پاسخ را بهصورت تدریجی ارسال میکند، نوع محتوای پاسخ را مشخص کنید.
برای Server-Sent Events معمولاً از این Content Type استفاده میشود:
text/event-stream
نمونه OpenAPI:
responses:
"200":
description: Streaming response
content:
text/event-stream:
schema:
type: string
OpenAPI میتواند نوع پاسخ را توضیح دهد؛ اما Swagger UI لزوماً تمام رفتارهای Streaming را مانند یک Client واقعی نمایش نمیدهد. برای آزمایش دقیق Streaming بهتر است از curl، Postman یا یک Client اختصاصی استفاده شود.
مستندسازی عملیات غیرهمزمان
تولید ویدئو، پردازش فایلهای بزرگ یا اجرای Workflowهای چندمرحلهای ممکن است چند دقیقه زمان ببرد. در این شرایط بهتر است API فوراً یک شناسه Job برگرداند:
{
"job_id": "job_7d819",
"status": "queued"
}
ساختار پیشنهادی Endpointها:
POST /v1/video-jobs
GET /v1/video-jobs/{job_id}
POST /v1/video-jobs/{job_id}/cancel
در OpenAPI باید وضعیتهای احتمالی Job نیز تعریف شوند:
status:
type: string
enum:
- queued
- processing
- completed
- failed
- cancelled
این روش برای ساخت اپلیکیشنی که کاربر در آن درخواست تولید ویدئو ثبت میکند، از نگهداشتن یک اتصال HTTP طولانی قابلمدیریتتر است.
استفاده از Swagger Editor
Swagger Editor برای نوشتن و اعتبارسنجی فایلهای OpenAPI استفاده میشود.
هنگام ویرایش قرارداد میتوانید خطاهایی مانند موارد زیر را سریعتر پیدا کنید:
- تورفتگی اشتباه YAML
- ارجاع نامعتبر با
$ref - پاسخ بدون
description - Schema ناقص
- نوع داده ناسازگار
- Security Scheme اشتباه
- پارامتر Path تعریفنشده
ابزارهای رسمی Swagger شامل Editor برای طراحی API، UI برای نمایش تعاملی و Codegen برای تولید کد هستند.
تولید SDK از OpenAPI
فایل OpenAPI فقط برای مستندات نیست. میتوان از روی آن Client SDK تولید کرد.
برای مثال، ابزار OpenAPI Generator میتواند Clientهایی برای زبانها و پلتفرمهای مختلف بسازد:
- TypeScript
- JavaScript
- Python
- Java
- Kotlin
- C#
- Go
- Swift
- Dart
نمونه دستور:
openapi-generator-cli generate \
-i openapi.yaml \
-g typescript-fetch \
-o clients/typescript
با این روش، تیم فرانتاند مجبور نیست URLها، Typeها و ساختار پاسخ را دستی بازنویسی کند.
بااینحال، کد تولیدشده باید بازبینی و نسخهبندی شود. تولید SDK جایگزین طراحی درست API نیست.
استفاده از OpenAPI برای تست قرارداد
یکی دیگر از کاربردهای OpenAPI، Contract Testing است.
در این نوع تست بررسی میشود که:
- Endpointهای واقعی با سند مطابقت دارند.
- فیلدهای اجباری واقعاً اجباری هستند.
- پاسخها از Schema تعریفشده پیروی میکنند.
- کدهای وضعیت مستندشده بهدرستی برگردانده میشوند.
- تغییر جدید باعث شکستن Clientهای قبلی نشده است.
برای مثال، اگر فیلد content در قرارداد اجباری باشد اما Backend گاهی آن را حذف کند، تست قرارداد باید این ناسازگاری را پیش از انتشار پیدا کند.
تغییرات Breaking در OpenAPI
هر تغییری در API سازگار با نسخه قبلی نیست.
نمونه تغییرات Breaking:
- حذف یک Endpoint
- تغییر نام فیلد
- اجباریکردن یک فیلد اختیاری
- تغییر نوع
stringبهinteger - حذف یکی از مقادیر Enum
- تغییر روش احراز هویت
- تغییر ساختار پاسخ
- تغییر معنای یک کد وضعیت
نمونه تغییرات معمولاً سازگار:
- اضافهکردن Endpoint جدید
- اضافهکردن فیلد اختیاری
- اضافهکردن پاسخ خطای جدید
- اصلاح توضیحات
- اضافهکردن مثال
البته سازگاری واقعی به رفتار Clientها نیز بستگی دارد. بعضی Clientها هنگام مشاهده فیلد ناشناخته خطا میدهند؛ بنابراین تغییرات قرارداد باید با تست مصرفکنندگان بررسی شود.
نسخهبندی API
نسخه API را میتوان در مسیر قرار داد:
/v1/generate
/v2/generate
همچنین نسخه سند در بخش info.version ثبت میشود:
info:
version: 1.2.0
این دو مقدار هدف متفاوتی دارند:
/v1نسخه عمومی قرارداد و مسیر API است.1.2.0نسخه انتشار سند یا پیادهسازی است.
با هر اصلاح جزئی لازم نیست مسیر /v2 ایجاد شود. نسخه اصلی جدید زمانی مناسب است که تغییرات ناسازگار و اجتنابناپذیر باشند.
نکات مهم برای مستندات API هوش مصنوعی
مدلها را ثابت فرض نکنید
بهتر است شناسه مدل در تنظیمات Backend یا متغیر محیطی قرار گیرد. اگر مصرفکننده اجازه انتخاب مدل دارد، فهرست مدلهای مجاز را در Schema یا یک Endpoint جداگانه ارائه کنید.
هزینه و واحد مصرف را توضیح دهید
اگر کاربران بابت مصرف API هزینه پرداخت میکنند، مشخص کنید هزینه بر اساس کدام واحد محاسبه میشود:
- توکن ورودی
- توکن خروجی
- تعداد تصویر
- مدت صوت
- مدت ویدئو
- تعداد عملیات
محدودیت طول را ثبت کنید
حداکثر اندازه Prompt، فایل، تصویر یا خروجی باید در مستندات مشخص باشد.
مثال فارسی ارائه کنید
اگر جامعه هدف فارسیزبان است، فقط نمونههای انگلیسی قرار ندهید. مثالهای فارسی کمک میکنند مشکلات Encoding، راستبهچپ، نیمفاصله و کیفیت خروجی زودتر شناسایی شوند.
پاسخ مدل را تضمین قطعی معرفی نکنید
پاسخ مدلهای مولد میتواند متغیر باشد. مستندات باید بین قرارداد فنی پاسخ و محتوای احتمالی مدل تفاوت قائل شوند.
برای مثال، میتوان تضمین کرد فیلد content یک رشته است؛ اما نمیتوان بدون ارزیابی و کنترل بیشتر تضمین کرد محتوای آن همیشه درست است.
Request ID اضافه کنید
یک شناسه درخواست مانند request_id برای پیگیری خطا، لاگ و پشتیبانی بسیار مفید است.
محدودیت نرخ را مستند کنید
اگر API دارای Rate Limit است، واحد محدودیت، بازه زمانی و رفتار Retry را توضیح دهید. در صورت امکان Headerهای مربوط به محدودیت و زمان تلاش مجدد را نیز مستند کنید.
آیا Swagger UI باید در Production عمومی باشد؟
پاسخ به نوع API بستگی دارد.
اگر API عمومی است، انتشار مستندات بخشی از محصول محسوب میشود. اما اگر API فقط برای کارکنان یا سرویسهای داخلی طراحی شده، بهتر است دسترسی به مستندات کنترل شود.
روشهای متداول عبارتاند از:
- محدودکردن دسترسی با احراز هویت
- استفاده از شبکه داخلی
- انتشار مستندات در Developer Portal
- غیرفعالکردن Swagger UI عمومی
- نگهداری فایل OpenAPI در Repository خصوصی
- ارائه مستندات جداگانه برای API عمومی و داخلی
پنهانکردن Swagger UI بهتنهایی یک راهکار امنیتی کامل نیست؛ Endpointهای واقعی همچنان باید احراز هویت، مجوزدهی، Rate Limit و اعتبارسنجی داشته باشند.
خطاهای رایج در مستندسازی Swagger
مستندات با کد هماهنگ نیست
اگر فایل OpenAPI دستی نوشته میشود، باید در فرایند CI بررسی شود که با پیادهسازی واقعی اختلاف نداشته باشد.
فقط پاسخ موفق مستند شده است
مصرفکننده باید ساختار خطاها و روش برخورد با آنها را نیز بداند.
مثالها واقعی نیستند
نمونههایی مانند "string" یا "example" برای توسعهدهنده ارزش کمی دارند. از دادهای نزدیک به کاربرد واقعی استفاده کنید.
Schema بیش از حد آزاد است
استفاده گسترده از object بدون تعریف Properties، مزیت اصلی OpenAPI را از بین میبرد.
اطلاعات حساس داخل مثال قرار گرفته است
کلید API، اطلاعات کاربر، شماره تماس یا داده واقعی نباید در فایل مستندات ثبت شود.
همه Endpointها در یک گروه قرار گرفتهاند
از Tagها برای دستهبندی استفاده کنید:
- Authentication
- Models
- Text Generation
- Image Generation
- Video Generation
- Jobs
- Billing
- System
توضیح فیلدها مبهم است
بهجای «مقدار تنظیمات»، دقیقاً بنویسید فیلد چه اثری دارد، چه محدودیتی دارد و مقدار پیشفرض آن چیست.
چکلیست OpenAPI برای محیط واقعی
پیش از انتشار API بررسی کنید:
- عنوان و نسخه API مشخص است.
- محیط Production و Staging تعریف شدهاند.
- تمام Endpointها Summary و Description دارند.
- ورودی و خروجی هر عملیات Schema دارد.
- فیلدهای اجباری مشخص شدهاند.
- محدودیت طول و بازه اعداد تعریف شده است.
- Enumها مستند شدهاند.
- احراز هویت در
securitySchemesقرار دارد. - خطاهای اصلی مستند شدهاند.
- نمونه درخواست و پاسخ وجود دارد.
- داده حساس در مثالها نیست.
- Tagها برای دستهبندی تعریف شدهاند.
- فایل OpenAPI در CI اعتبارسنجی میشود.
- تغییرات Breaking پیش از انتشار شناسایی میشوند.
- مستندات با نسخه واقعی سرویس هماهنگ هستند.
- API Key سرویس مدل در Backend نگهداری میشود.
پرسشهای متداول
Swagger چیست؟
Swagger مجموعهای از ابزارها برای طراحی، نمایش، آزمایش و تولید کد از روی قرارداد API است. Swagger UI یکی از شناختهشدهترین ابزارهای این مجموعه محسوب میشود.
OpenAPI چیست؟
OpenAPI استانداردی برای توصیف Endpointها، ورودیها، پاسخها، احراز هویت و سایر اجزای HTTP API است.
تفاوت Swagger و OpenAPI چیست؟
OpenAPI استاندارد توصیف API است، درحالیکه Swagger نام مجموعهای از ابزارهایی است که با این استاندارد کار میکنند.
آیا Swagger فقط برای REST API است؟
کاربرد اصلی OpenAPI و Swagger توصیف HTTP APIها، بهویژه APIهای REST است. برای معماریهای رویدادمحور و Message Brokerها استانداردهایی مانند AsyncAPI نیز وجود دارند.
آیا FastAPI به Swagger نیاز دارد؟
FastAPI مستندات OpenAPI را از روی کد تولید میکند و برای نمایش تعاملی آن از Swagger UI استفاده میکند. معمولاً نیازی نیست Swagger UI را جداگانه نصب کنید.
فایل OpenAPI در FastAPI کجاست؟
بهصورت پیشفرض در این آدرس قرار دارد:
/openapi.json
چگونه Swagger UI را در FastAPI باز کنیم؟
پس از اجرای برنامه، معمولاً این آدرس را باز کنید:
http://127.0.0.1:8000/docs
آیا میتوان از OpenAPI برای ساخت SDK استفاده کرد؟
بله. ابزارهایی مانند OpenAPI Generator و Swagger Codegen میتوانند از روی قرارداد OpenAPI برای زبانهای مختلف Client SDK تولید کنند.
آیا Swagger برای API هوش مصنوعی مناسب است؟
بله. میتوان ورودی مدل، تنظیمات تولید، ساختار پاسخ، خطاها، احراز هویت و عملیات Async را با OpenAPI مستند کرد. بااینحال، رفتار احتمالی و غیرقطعی محتوای مدل باید جدا از قرارداد فنی توضیح داده شود.
چگونه API درواره را در اپلیکیشن خود استفاده کنیم؟
کلید API درواره را در Backend نگه دارید و Client سازگار با OpenAI را با آدرس پایه زیر تنظیم کنید:
https://api.darvareh.ir/v1
سپس Endpoint داخلی خود را با Swagger و OpenAPI مستند کنید تا وبسایت، اپلیکیشن موبایل یا سایر سرویسها بدون دسترسی مستقیم به کلید اصلی، از قابلیت هوش مصنوعی استفاده کنند.
جمعبندی
Swagger و OpenAPI فقط ابزارهایی برای ساخت یک صفحه مستندات زیبا نیستند. آنها قرارداد میان Backend، Frontend، اپلیکیشن موبایل، تیم تست و مصرفکنندگان خارجی API را تعریف میکنند.
در این آموزش یاد گرفتیم چگونه:
- تفاوت Swagger و OpenAPI را تشخیص دهیم.
- ساختار اصلی یک سند OpenAPI را تعریف کنیم.
- با FastAPI مستندات Swagger خودکار بسازیم.
- ورودی و خروجی API هوش مصنوعی را اعتبارسنجی کنیم.
- احراز هویت API Key را در Swagger UI نمایش دهیم.
- خطاهای سرویس مدل را مستند کنیم.
- Backend را به API سازگار با OpenAI درواره متصل کنیم.
- قرارداد OpenAPI را برای تولید SDK و تست استفاده کنیم.
- تغییرات Breaking را پیش از انتشار شناسایی کنیم.
برای شروع، میتوانید یک Endpoint محدود مانند تولید متن، خلاصهسازی یا طبقهبندی پیام بسازید. سپس Schema ورودی، پاسخ موفق، پاسخ خطا و احراز هویت آن را بهطور کامل مستند کنید.
برای دریافت کلید API، مشاهده مدلهای قابلدسترسی و اتصال برنامه خود به مدلهای هوش مصنوعی، از مستندات API درواره استفاده کنید.
مقالات مرتبط
- REST API چیست؟ آموزش طراحی API استاندارد
- HTTP چیست؟ متدها و کدهای وضعیت API
- JSON چیست؟ آموزش JSON در Python و JavaScript
- ساخت SDK و API Client از OpenAPI با هوش مصنوعی
- آموزش اتصال API هوش مصنوعی به اپلیکیشن
- API سازگار با OpenAI چیست؟
- Structured Outputs و JSON Schema در API هوش مصنوعی
منابع
- OpenAPI Initiative
- OpenAPI Specification
- Swagger: What Is OpenAPI?
- Swagger UI
- Swagger Documentation
- FastAPI: Metadata and Docs URLs
- مستندات API درواره
این مقاله صرفاً با هدف آموزش و اطلاعرسانی تهیه شده است. پیش از استفاده عملی، مستندات رسمی سرویسها و صفحه سلب مسئولیت را مطالعه کنید.