RAJESTARY DIGITAL TECH • SECURITY • EDUCATION
دانش • فناوری • امنیت

دنیای تکنولوژی
از یادگیری شروع می‌شود

آموزش‌های کاربردی، برنامه‌نویسی، امنیت و فناوری برای ساختن، یادگرفتن و بهتر زندگی کردن با تکنولوژی.

LEARN BUILD SECURE CREATE

مستندسازی API با OpenAPI (Swagger)

مستندسازی API با OpenAPI (Swagger)

📖 درس ششم: مستندسازی API با OpenAPI (Swagger)

👋

سلام مهمان عزیز!

برای دسترسی به تمام محتوا و امکانات، وارد شوید.

🎯 هدف این درس: آشنایی با OpenAPI Specification، تولید مستندات تعاملی با Swagger UI، نوشتن Specification استاندارد برای Endpointها و تست API از طریق مستندات.

مهمان عزیز! 👋
تا اینجا یک API کامل با امنیت و احراز هویت ساخته‌ایم. اما اگر کسی بخواهد از API ما استفاده کند، چگونه باید بداند چه Endpointهایی وجود دارد، چه پارامترهایی نیاز است و چه پاسخی دریافت می‌کند؟

اینجاست که مستندسازی اهمیت پیدا می‌کند. یک مستند خوب، API شما را قابل استفاده، قابل فهم و حرفه‌ای می‌کند. در این درس، با استاندارد OpenAPI (که قبلاً با نام Swagger شناخته می‌شد) آشنا می‌شویم و مستندات تعاملی برای API خود تولید می‌کنیم.

💡 OpenAPI چیست؟

OpenAPI یک استاندارد جهانی برای توصیف APIها است. با استفاده از این استاندارد، می‌توانید مستندات API خود را به صورت JSON یا YAML بنویسید و با ابزارهایی مثل Swagger UI، آنها را به صورت تعاملی نمایش دهید. این استاندارد به شما امکان می‌دهد:

  • ✅ مستندات خودکار تولید کنید.
  • ✅ کلاینت‌های مختلف را تولید کنید.
  • ✅ تست تعاملی API را انجام دهید.
  • ✅ مستندات را همیشه به‌روز نگه دارید.

📋 ساختار OpenAPI Specification

یک فایل OpenAPI شامل بخش‌های اصلی زیر است:

  • openapi: نسخه استاندارد OpenAPI.
  • info: اطلاعات کلی درباره API (عنوان، توضیحات، نسخه).
  • servers: آدرس‌های سرور (تولید، توسعه، تست).
  • paths: تمام Endpointها و عملیات‌های آنها.
  • components: اشتراک‌ها (schemas، parameters، responses، security).
  • security: روش‌های احراز هویت.
  • tags: برچسب‌ها برای گروه‌بندی Endpointها.


📋
openapi.yaml (ساختار کلی)

YAML
3.0.0




# نسخه استاندارد OpenAPI
openapi: "3.0.0"

# اطلاعات کلی API
info:
  title: "API مدیریت کاربران"
  description: "یک API کامل برای مدیریت کاربران با احراز هویت JWT"
  version: "1.0.0"
  contact:
    name: "پشتیبانی رجستری"
    email: "support@rajestary.com"

# آدرس‌های سرور
servers:
  - url: "https://api.rajestary.com/v1"
    description: "سرور تولید"
  - url: "http://localhost:8000"
    description: "سرور توسعه"

# روش احراز هویت
security:
  - bearerAuth: []

components:
  securitySchemes:
    bearerAuth:
      type: "http"
      scheme: "bearer"
      bearerFormat: "JWT"

  # مدل‌های داده (Schemas)
  schemas:
    User:
      type: "object"
      properties:
        id:
          type: "integer"
          example: 1
        name:
          type: "string"
          example: "یونس"
        email:
          type: "string"
          example: "younes@example.com"
        role:
          type: "string"
          enum: ["admin", "user", "guest"]
          example: "user"
        created_at:
          type: "string"
          format: "date-time"
    CreateUserRequest:
      type: "object"
      required:
        - "name"
        - "email"
        - "password"
      properties:
        name:
          type: "string"
          minLength: 3
          example: "یونس"
        email:
          type: "string"
          format: "email"
          example: "younes@example.com"
        password:
          type: "string"
          minLength: 6
          example: "password123"
        role:
          type: "string"
          enum: ["admin", "user", "guest"]
          default: "user"

# مسیرها (Paths)
paths:
  # ... Endpointها در ادامه تعریف می‌شوند ...

📝 نوشتن Specification برای Endpointها

حالا بیایید Specification کامل برای API کاربران و احراز هویت را بنویسیم:



📝
openapi.yaml (کامل)

YAML
3.0.0




# ========== مسیرهای احراز هویت ==========
paths:
  "/auth/register":
    post:
      tags:
        - "احراز هویت"
      summary: "ثبت‌نام کاربر جدید"
      description: "یک کاربر جدید با ایمیل و رمز عبور ثبت‌نام می‌کند"
      operationId: "registerUser"
      requestBody:
        required: true
        content:
          "application/json":
            schema:
              $ref: "#/components/schemas/CreateUserRequest"
      responses:
        "201":
          description: "ثبت‌نام با موفقیت انجام شد"
          content:
            "application/json":
              schema:
                type: "object"
                properties:
                  status:
                    type: "string"
                    example: "success"
                  message:
                    type: "string"
                    example: "User registered successfully"
                  data:
                    type: "object"
                    properties:
                      user:
                        $ref: "#/components/schemas/User"
                      token:
                        type: "string"
                      expires_in:
                        type: "integer"
        "422":
          description: "خطای اعتبارسنجی"
          content:
            "application/json":
              schema:
                $ref: "#/components/schemas/ValidationError"

  "/auth/login":
    post:
      tags:
        - "احراز هویت"
      summary: "ورود کاربر"
      description: "کاربر با ایمیل و رمز عبور وارد می‌شود"
      operationId: "loginUser"
      requestBody:
        required: true
        content:
          "application/json":
            schema:
              type: "object"
              required:
                - "email"
                - "password"
              properties:
                email:
                  type: "string"
                  format: "email"
                  example: "younes@example.com"
                password:
                  type: "string"
                  example: "password123"
      responses:
        "200":
          description: "ورود با موفقیت انجام شد"
          content:
            "application/json":
              schema:
                type: "object"
                properties:
                  status:
                    type: "string"
                    example: "success"
                  message:
                    type: "string"
                    example: "Login successful"
                  data:
                    type: "object"
                    properties:
                      user:
                        $ref: "#/components/schemas/User"
                      token:
                        type: "string"
                      expires_in:
                        type: "integer"
        "401":
          description: "اطلاعات ورود نادرست"
          content:
            "application/json":
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  "/auth/me":
    get:
      tags:
        - "احراز هویت"
      summary: "دریافت اطلاعات کاربر فعلی"
      description: "اطلاعات کاربر احراز هویت شده را بازمی‌گرداند"
      operationId: "getCurrentUser"
      security:
        - bearerAuth: []
      responses:
        "200":
          description: "اطلاعات کاربر"
          content:
            "application/json":
              schema:
                type: "object"
                properties:
                  status:
                    type: "string"
                    example: "success"
                  data:
                    $ref: "#/components/schemas/User"
        "401":
          description: "احراز هویت نشده"
          content:
            "application/json":
              schema:
                $ref: "#/components/schemas/ErrorResponse"

# ========== مسیرهای کاربران (فقط ادمین) ==========
  "/users":
    get:
      tags:
        - "کاربران"
      summary: "دریافت لیست کاربران"
      description: "لیست تمام کاربران را با صفحه‌بندی بازمی‌گرداند. فقط ادمین دسترسی دارد."
      operationId: "getUsers"
      security:
        - bearerAuth: []
      parameters:
        - name: "page"
          in: "query"
          description: "شماره صفحه"
          schema:
            type: "integer"
            default: 1
        - name: "limit"
          in: "query"
          description: "تعداد آیتم در هر صفحه"
          schema:
            type: "integer"
            default: 10
            maximum: 100
        - name: "name"
          in: "query"
          description: "فیلتر بر اساس نام"
          schema:
            type: "string"
        - name: "role"
          in: "query"
          description: "فیلتر بر اساس نقش"
          schema:
            type: "string"
            enum: ["admin", "user", "guest"]
      responses:
        "200":
          description: "لیست کاربران"
          content:
            "application/json":
              schema:
                type: "object"
                properties:
                  status:
                    type: "string"
                  data:
                    type: "object"
                    properties:
                      data:
                        type: "array"
                        items:
                          $ref: "#/components/schemas/User"
                      pagination:
                        type: "object"
                        properties:
                          current_page:
                            type: "integer"
                          per_page:
                            type: "integer"
                          total:
                            type: "integer"
                          total_pages:
                            type: "integer"
        "401":
          description: "احراز هویت نشده"
        "403":
          description: "دسترسی غیرمجاز"

    post:
      tags:
        - "کاربران"
      summary: "ایجاد کاربر جدید"
      description: "یک کاربر جدید ایجاد می‌کند. فقط ادمین دسترسی دارد."
      operationId: "createUser"
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          "application/json":
            schema:
              $ref: "#/components/schemas/CreateUserRequest"
      responses:
        "201":
          description: "کاربر با موفقیت ایجاد شد"
          content:
            "application/json":
              schema:
                type: "object"
                properties:
                  status:
                    type: "string"
                  message:
                    type: "string"
                  data:
                    $ref: "#/components/schemas/User"
        "422":
          description: "خطای اعتبارسنجی"
        "403":
          description: "دسترسی غیرمجاز"

  "/users/{id}":
    get:
      tags:
        - "کاربران"
      summary: "دریافت یک کاربر"
      description: "اطلاعات یک کاربر خاص را بازمی‌گرداند"
      operationId: "getUser"
      security:
        - bearerAuth: []
      parameters:
        - name: "id"
          in: "path"
          required: true
          description: "شناسه کاربر"
          schema:
            type: "integer"
      responses:
        "200":
          description: "اطلاعات کاربر"
          content:
            "application/json":
              schema:
                type: "object"
                properties:
                  status:
                    type: "string"
                  data:
                    $ref: "#/components/schemas/User"
        "404":
          description: "کاربر پیدا نشد"

    put:
      tags:
        - "کاربران"
      summary: "بروزرسانی کاربر"
      description: "اطلاعات کاربر را بروزرسانی می‌کند"
      operationId: "updateUser"
      security:
        - bearerAuth: []
      parameters:
        - name: "id"
          in: "path"
          required: true
          schema:
            type: "integer"
      requestBody:
        required: true
        content:
          "application/json":
            schema:
              type: "object"
              properties:
                name:
                  type: "string"
                  minLength: 3
                email:
                  type: "string"
                  format: "email"
                password:
                  type: "string"
                  minLength: 6
                role:
                  type: "string"
                  enum: ["admin", "user", "guest"]
      responses:
        "200":
          description: "بروزرسانی موفق"
          content:
            "application/json":
              schema:
                type: "object"
                properties:
                  status:
                    type: "string"
                  message:
                    type: "string"
                  data:
                    $ref: "#/components/schemas/User"
        "404":
          description: "کاربر پیدا نشد"
        "422":
          description: "خطای اعتبارسنجی"

    delete:
      tags:
        - "کاربران"
      summary: "حذف کاربر"
      description: "یک کاربر را حذف می‌کند. فقط ادمین دسترسی دارد."
      operationId: "deleteUser"
      security:
        - bearerAuth: []
      parameters:
        - name: "id"
          in: "path"
          required: true
          schema:
            type: "integer"
      responses:
        "204":
          description: "حذف موفق"
        "404":
          description: "کاربر پیدا نشد"
        "403":
          description: "دسترسی غیرمجاز"

🎨 راه‌اندازی Swagger UI

برای نمایش مستندات به صورت تعاملی، از Swagger UI استفاده می‌کنیم. این ابزار یک رابط کاربری زیبا برای مشاهده و تست Endpointها فراهم می‌کند.



🎨
swagger-ui.php

PHP
8.2




<?php

// فایل: public/swagger-ui.php
// این فایل برای نمایش Swagger UI استفاده می‌شود

📂 ساختار فایل‌های مستندات

برای مدیریت بهتر، فایل‌های OpenAPI را به این شکل سازماندهی می‌کنیم:



📂
API Documentation Structure

Directory




# ساختار فایل‌های مستندات
docs/
├── openapi.yaml          # فایل اصلی OpenAPI
├── swagger-ui/           # فایل‌های Swagger UI
│   ├── index.html
│   ├── swagger-ui.css
│   └── swagger-ui-bundle.js
└── openapi.json          # نسخه JSON (برای برخی ابزارها)

# برای استفاده از CDN (روش ساده‌تر):
public/
└── api-docs.php          # نمایش Swagger UI با CDN

🧪 تست API از طریق Swagger UI

یکی از مزیت‌های بزرگ Swagger UI امکان تست Endpointها به صورت تعاملی است. برای تست احراز هویت، ابتدا باید توکن را دریافت کنید و سپس آن را در دکمه “Authorize” قرار دهید.

💡 مراحل تست با Swagger UI:

  1. ✅ به آدرس https://your-domain.com/api-docs.php بروید.
  2. ✅ Endpoint POST /auth/register یا POST /auth/login را باز کنید.
  3. ✅ روی دکمه “Try it out” کلیک کنید.
  4. ✅ اطلاعات مورد نیاز را وارد کنید و “Execute” را بزنید.
  5. ✅ توکن دریافت شده را کپی کنید.
  6. ✅ روی دکمه “Authorize” کلیک کنید و توکن را با فرمت Bearer {token} وارد کنید.
  7. ✅ حالا می‌توانید Endpointهای محافظت‌شده را تست کنید.

🔴 خطاهای رایج در مستندسازی

  • ❌ اشتباه: فراموش کردن به‌روزرسانی مستندات هنگام تغییر API.
  • ✅ درست: مستندات را همزمان با کد به‌روزرسانی کن.
  • ❌ اشتباه: استفاده از مثال‌های نامناسب یا نامفهوم.
  • ✅ درست: از مثال‌های واقعی و واضح استفاده کن.
  • ❌ اشتباه: عدم مشخص کردن Security Scheme برای Endpointهای محافظت‌شده.
  • ✅ درست: برای هر Endpoint محافظت‌شده، security را مشخص کن.
  • ❌ اشتباه: نوشتن مستندات بسیار طولانی و بدون ساختار.
  • ✅ درست: از ساختار مناسب و بخش‌بندی استفاده کن.

💎 نکات کلیدی درس

  • ✅ OpenAPI یک استاندارد جهانی برای مستندسازی API است.
  • ✅ مستندات OpenAPI می‌تواند به صورت YAML یا JSON نوشته شود.
  • ✅ Swagger UI ابزاری برای نمایش تعاملی مستندات OpenAPI است.
  • ✅ Specification شامل info، servers، paths، components و security است.
  • components/schemas برای تعریف مدل‌های داده استفاده می‌شود.
  • components/securitySchemes برای تعریف روش‌های احراز هویت استفاده می‌شود.
  • ✅ با Swagger UI می‌توان Endpointها را به صورت تعاملی تست کرد.
  • ✅ مستندات باید همیشه با کد هماهنگ باشد.

🛠️ پروژه عملی درس ششم

مهمان عزیز، حالا مستندات کامل برای API خود بنویس!

مسئله:

یک مستند کامل OpenAPI برای API محصولات خود ایجاد کن:

  • ✅ مستندات کامل برای تمام Endpointهای محصولات.
  • ✅ مدل‌های داده (Product، CreateProductRequest، UpdateProductRequest).
  • ✅ پارامترهای صفحه‌بندی و فیلتر.
  • ✅ احراز هویت JWT برای Endpointهای محافظت‌شده.
  • ✅ کدهای وضعیت و پاسخ‌های مختلف.
  • ✅ مثال‌های واقعی برای هر Endpoint.

🧪 راه‌حل پروژه (پاسخ)

مراحل پیاده‌سازی:

  • 1️⃣ یک فایل openapi.yaml جدید با ساختار کامل ایجاد کن.
  • 2️⃣ مدل Product را با تمام ویژگی‌ها تعریف کن.
  • 3️⃣ تمام Endpointهای /products و /products/{id} را مستند کن.
  • 4️⃣ پارامترهای category، min_price، max_price و search را اضافه کن.
  • 5️⃣ Swagger UI را راه‌اندازی کن و مستندات را تست کن.

📝 تمرین‌های عملی

🧪 تمرین ۱ (ساده):

مستندات OpenAPI را برای Endpointهای احراز هویت (register، login، me) کامل کن و با Swagger UI تست کن.

🧪 تمرین ۲ (متوسط):

یک فایل openapi.json از فایل openapi.yaml تولید کن. از ابزارهای آنلاین یا کتابخانه‌های PHP برای تبدیل استفاده کن.

🧪 تمرین ۳ (چالشی):

یک سیستم تولید خودکار مستندات از کد PHP پیاده‌سازی کن. با استفاده از Reflection یا Attributes (PHP 8)، مستندات OpenAPI را از کد کنترلرها استخراج کن.


🏁 جمع‌بندی درس

مهمان عزیز، در این درس یاد گرفتی:

  • ✅ OpenAPI Specification چیست و چرا اهمیت دارد.
  • ✅ چگونه یک مستند کامل OpenAPI در قالب YAML بنویسی.
  • ✅ چگونه مدل‌های داده (Schemas) را در OpenAPI تعریف کنی.
  • ✅ چگونه Endpointها، پارامترها و پاسخ‌ها را مستند کنی.
  • ✅ چگونه احراز هویت JWT را در OpenAPI تعریف کنی.
  • ✅ چگونه Swagger UI را راه‌اندازی و استفاده کنی.
  • ✅ چگونه API خود را به صورت تعاملی با Swagger UI تست کنی.

حالا API شما مستندات حرفه‌ای و تعاملی دارد. در درس بعدی، با تکنیک‌های بهینه‌سازی عملکرد (Caching) آشنا می‌شویم. آماده‌ای؟ 🚀


🗺️ نقشه راه دوره: شما اینجا هستید!

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

درس عنوان درس آنچه یاد می‌گیرید
۱ مفاهیم پایه API HTTP، REST، معماری Client-Server
۲ پیاده‌سازی RESTful API با PHP خام مسیریابی، متدها، پارامترها، پاسخ‌های JSON
۳ مدیریت داده‌ها و پایگاه‌داده اتصال PDO، CRUD، تراکنش‌ها، Pagination
۴ اعتبارسنجی و احراز هویت JWT، Roles/Permissions، Middleware
۵ امنیت API پیشرفته OWASP Top 10، SQLi، XSS، CSRF، Rate Limiting
۶ مستندسازی API با OpenAPI Swagger، OpenAPI Specification، مستندات تعاملی
۷ Caching و افزایش عملکرد Redis، ETag، Cache-Control، Query Optimization
۸ API Versioning و مدیریت چرخه حیات استراتژی‌های نسخه‌بندی، Deprecation، Backward Compatibility
۹ تست و دیباگ API حرفه‌ای PHPUnit، Mocking، Logging، Postman Collection
۱۰ پروژه نهایی: API فروشگاهی پروژه کامل فروشگاه اینترنتی با تمام قابلیت‌ها

🔗 لینک‌های مرتبط

👤
نویسنده
📅
تاریخ انتشار 29 مرداد 1405
🔄
آخرین بروزرسانی 30 مرداد 1405

نظر خود را بنویسید

با ثبت نظر، به بهبود محتوای ما کمک کنید

امتیاز شما به این مطلب (اختیاری)
برای امتیازدهی، روی ستاره‌ها کلیک کنید
نام شما در سایت نمایش داده می‌شود
ایمیل شما محفوظ می‌ماند
0 کاراکتر | حداقل ۱۰ کاراکتر
نظر سازنده و مفید بنویسید
ارسال دیدگاه: +۵ امتیاز
امتیازدهی: +۲ امتیاز
نشان شما: مبتدی
لطفاً از کلمات محترمانه استفاده کنید. دیدگاه‌های توهین‌آمیز حذف می‌شوند.
⚠️

هشدار مهم!

برای اتصال به درگاه پرداخت و انجام تراکنش، لطفاً VPN یا فیلترشکن خود را خاموش کنید.

⏳ ادامه در
5
ثانیه