@hrefcl/apidoc - v4.0.5
    Preparing search index...

    ๐Ÿ”„ OpenAPI 3.0 Support & Schema Integration

    Complete guide for integrating APIDoc with OpenAPI 3.0 specifications, schema validation, and modern API development workflows.

    APIDoc 4.0 provides comprehensive OpenAPI 3.0 integration for modern API development:

    • ๐Ÿ“„ Schema Export: Convert APIDoc to OpenAPI 3.0
    • ๐Ÿ”„ Bidirectional Sync: Import from OpenAPI specifications
    • โœ… Schema Validation: Automatic request/response validation
    • ๐Ÿงช Interactive Testing: Swagger UI integration
    • ๐Ÿ“‹ Standards Compliance: Full OpenAPI 3.0 specification support
    {
    "name": "My API",
    "version": "1.0.0",
    "description": "RESTful API with OpenAPI support",
    "openapi": {
    "export": true,
    "version": "3.0.3",
    "outputFile": "openapi.json",
    "servers": [
    {
    "url": "https://api.example.com/v1",
    "description": "Production server"
    },
    {
    "url": "https://staging-api.example.com/v1",
    "description": "Staging server"
    }
    ],
    "info": {
    "contact": {
    "name": "API Support",
    "email": "api-support@example.com",
    "url": "https://example.com/support"
    },
    "license": {
    "name": "MIT",
    "url": "https://opensource.org/licenses/MIT"
    }
    }
    }
    }
    /**
    * @api {post} /users Create User
    * @apiName CreateUser
    * @apiGroup Users
    * @apiVersion 1.0.0
    *
    * @apiDescription Creates a new user account with validation and email verification.
    *
    * @apiBody {String{2..50}} name User's full name
    * @apiBody {String} email Valid email address
    * @apiBody {String{8..}} password Strong password
    * @apiBody {String="user","admin","moderator"} [role=user] User role
    * @apiBody {Object} [profile] User profile data
    * @apiBody {String} [profile.bio] Profile biography
    * @apiBody {String[]} [profile.interests] User interests
    *
    * @apiSuccess (201) {Number} id User ID
    * @apiSuccess (201) {String} name User's name
    * @apiSuccess (201) {String} email User's email
    * @apiSuccess (201) {String} role User's role
    * @apiSuccess (201) {Boolean} active Account status
    * @apiSuccess (201) {Object} profile User profile
    * @apiSuccess (201) {Date} createdAt Creation timestamp
    *
    * @apiError (400) {String} error="ValidationError" Validation failed
    * @apiError (400) {String} message Error description
    * @apiError (400) {Object[]} [errors] Field-specific errors
    * @apiError (409) {String} error="ConflictError" Email already exists
    *
    * @apiExample {json} Request Example:
    * {
    * "name": "John Doe",
    * "email": "john@example.com",
    * "password": "securePassword123",
    * "role": "user",
    * "profile": {
    * "bio": "Software developer",
    * "interests": ["technology", "music"]
    * }
    * }
    *
    * @apiSuccessExample {json} Success Response:
    * HTTP/1.1 201 Created
    * {
    * "id": 1,
    * "name": "John Doe",
    * "email": "john@example.com",
    * "role": "user",
    * "active": true,
    * "profile": {
    * "bio": "Software developer",
    * "interests": ["technology", "music"]
    * },
    * "createdAt": "2024-01-15T10:30:00Z"
    * }
    */
    {
    "openapi": "3.0.3",
    "info": {
    "title": "My API",
    "version": "1.0.0",
    "description": "RESTful API with OpenAPI support",
    "contact": {
    "name": "API Support",
    "email": "api-support@example.com",
    "url": "https://example.com/support"
    },
    "license": {
    "name": "MIT",
    "url": "https://opensource.org/licenses/MIT"
    }
    },
    "servers": [
    {
    "url": "https://api.example.com/v1",
    "description": "Production server"
    }
    ],
    "paths": {
    "/users": {
    "post": {
    "tags": ["Users"],
    "summary": "Create User",
    "description": "Creates a new user account with validation and email verification.",
    "operationId": "CreateUser",
    "requestBody": {
    "required": true,
    "content": {
    "application/json": {
    "schema": {
    "$ref": "#/components/schemas/CreateUserRequest"
    },
    "example": {
    "name": "John Doe",
    "email": "john@example.com",
    "password": "securePassword123",
    "role": "user",
    "profile": {
    "bio": "Software developer",
    "interests": ["technology", "music"]
    }
    }
    }
    }
    },
    "responses": {
    "201": {
    "description": "User created successfully",
    "content": {
    "application/json": {
    "schema": {
    "$ref": "#/components/schemas/User"
    },
    "example": {
    "id": 1,
    "name": "John Doe",
    "email": "john@example.com",
    "role": "user",
    "active": true,
    "profile": {
    "bio": "Software developer",
    "interests": ["technology", "music"]
    },
    "createdAt": "2024-01-15T10:30:00Z"
    }
    }
    }
    },
    "400": {
    "description": "Validation error",
    "content": {
    "application/json": {
    "schema": {
    "$ref": "#/components/schemas/ValidationError"
    }
    }
    }
    },
    "409": {
    "description": "Email already exists",
    "content": {
    "application/json": {
    "schema": {
    "$ref": "#/components/schemas/ConflictError"
    }
    }
    }
    }
    }
    }
    }
    },
    "components": {
    "schemas": {
    "CreateUserRequest": {
    "type": "object",
    "required": ["name", "email", "password"],
    "properties": {
    "name": {
    "type": "string",
    "minLength": 2,
    "maxLength": 50,
    "description": "User's full name"
    },
    "email": {
    "type": "string",
    "format": "email",
    "description": "Valid email address"
    },
    "password": {
    "type": "string",
    "minLength": 8,
    "description": "Strong password"
    },
    "role": {
    "type": "string",
    "enum": ["user", "admin", "moderator"],
    "default": "user",
    "description": "User role"
    },
    "profile": {
    "$ref": "#/components/schemas/UserProfile"
    }
    }
    },
    "User": {
    "type": "object",
    "properties": {
    "id": {
    "type": "integer",
    "description": "User ID"
    },
    "name": {
    "type": "string",
    "description": "User's name"
    },
    "email": {
    "type": "string",
    "format": "email",
    "description": "User's email"
    },
    "role": {
    "type": "string",
    "enum": ["user", "admin", "moderator"],
    "description": "User's role"
    },
    "active": {
    "type": "boolean",
    "description": "Account status"
    },
    "profile": {
    "$ref": "#/components/schemas/UserProfile"
    },
    "createdAt": {
    "type": "string",
    "format": "date-time",
    "description": "Creation timestamp"
    }
    }
    },
    "UserProfile": {
    "type": "object",
    "properties": {
    "bio": {
    "type": "string",
    "description": "Profile biography"
    },
    "interests": {
    "type": "array",
    "items": {
    "type": "string"
    },
    "description": "User interests"
    }
    }
    },
    "ValidationError": {
    "type": "object",
    "properties": {
    "error": {
    "type": "string",
    "example": "ValidationError"
    },
    "message": {
    "type": "string",
    "description": "Error description"
    },
    "errors": {
    "type": "array",
    "items": {
    "type": "object",
    "properties": {
    "field": {
    "type": "string"
    },
    "message": {
    "type": "string"
    }
    }
    }
    }
    }
    },
    "ConflictError": {
    "type": "object",
    "properties": {
    "error": {
    "type": "string",
    "example": "ConflictError"
    },
    "message": {
    "type": "string",
    "description": "Error description"
    }
    }
    }
    },
    "securitySchemes": {
    "bearerAuth": {
    "type": "http",
    "scheme": "bearer",
    "bearerFormat": "JWT"
    },
    "apiKey": {
    "type": "apiKey",
    "in": "header",
    "name": "X-API-Key"
    }
    }
    }
    }
    {
    "openapi": {
    "import": true,
    "source": "./specs/openapi.json",
    "generateDocs": true,
    "generateStubs": true,
    "outputDir": "./generated/",
    "options": {
    "includeExamples": true,
    "generateValidation": true,
    "preserveCustom": true
    }
    }
    }
    // scripts/import-openapi.js
    const apidoc = require('@hrefcl/apidoc');
    const fetch = require('node-fetch');
    const fs = require('fs').promises;

    async function importFromURL(url, outputPath) {
    try {
    console.log(`๐Ÿ“ฅ Importing OpenAPI spec from ${url}...`);

    // Fetch OpenAPI specification
    const response = await fetch(url);
    if (!response.ok) {
    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
    }

    const openApiSpec = await response.json();

    // Save to local file
    await fs.writeFile(outputPath, JSON.stringify(openApiSpec, null, 2));

    // Generate APIDoc documentation
    const success = await apidoc.createDoc({
    src: outputPath,
    dest: './docs-from-openapi/',
    openapi: {
    import: true,
    source: outputPath,
    generateDocs: true
    }
    });

    if (success) {
    console.log('โœ… Documentation generated from OpenAPI spec');
    } else {
    throw new Error('Documentation generation failed');
    }

    } catch (error) {
    console.error('โŒ Import failed:', error.message);
    throw error;
    }
    }

    // Usage
    const specUrl = 'https://petstore.swagger.io/v2/swagger.json';
    const localPath = './specs/imported-openapi.json';

    importFromURL(specUrl, localPath);
    /**
    * @api {post} /products Create Product
    * @apiName CreateProduct
    * @apiGroup Products
    *
    * @apiSchema {Object} Product
    * @apiSchema Product.name {String{2..100}} Product name
    * @apiSchema Product.price {Number{0.01..}} Product price
    * @apiSchema Product.category {String="electronics","clothing","books"} Category
    * @apiSchema Product.tags {String[]} Product tags
    * @apiSchema Product.specifications {Object} Technical specifications
    * @apiSchema Product.specifications.weight {Number} Weight in kg
    * @apiSchema Product.specifications.dimensions {Object} Dimensions
    * @apiSchema Product.specifications.dimensions.length {Number} Length in cm
    * @apiSchema Product.specifications.dimensions.width {Number} Width in cm
    * @apiSchema Product.specifications.dimensions.height {Number} Height in cm
    *
    * @apiBody {Product} product Product data
    *
    * @apiSuccess {Number} id Product ID
    * @apiSuccess {Product} product Created product
    *
    * @apiExample {json} Request Example:
    * {
    * "product": {
    * "name": "Wireless Headphones",
    * "price": 99.99,
    * "category": "electronics",
    * "tags": ["wireless", "bluetooth", "music"],
    * "specifications": {
    * "weight": 0.25,
    * "dimensions": {
    * "length": 20,
    * "width": 18,
    * "height": 8
    * }
    * }
    * }
    * }
    */
    /**
    * @api {get} /products/:id Get Product
    * @apiName GetProduct
    * @apiGroup Products
    *
    * @apiParam {Number} id Product ID
    *
    * @apiSuccess {Number} id Product ID
    * @apiSuccess {String} name Product name
    * @apiSuccess {Number} price Product price
    * @apiSuccess {String} category Product category
    * @apiSuccess {String[]} tags Product tags
    * @apiSuccess {Object} specifications Technical specifications
    * @apiSuccess {Boolean} available Availability status
    * @apiSuccess {Number} stock Stock quantity
    * @apiSuccess {Date} createdAt Creation timestamp
    * @apiSuccess {Date} updatedAt Last update timestamp
    *
    * @apiError (404) {String} error="NotFound" Product not found
    * @apiError (400) {String} error="InvalidId" Invalid product ID
    *
    * @apiSuccessExample {json} Success Response:
    * HTTP/1.1 200 OK
    * {
    * "id": 1,
    * "name": "Wireless Headphones",
    * "price": 99.99,
    * "category": "electronics",
    * "tags": ["wireless", "bluetooth", "music"],
    * "specifications": {
    * "weight": 0.25,
    * "dimensions": {
    * "length": 20,
    * "width": 18,
    * "height": 8
    * }
    * },
    * "available": true,
    * "stock": 15,
    * "createdAt": "2024-01-15T09:00:00Z",
    * "updatedAt": "2024-01-15T12:30:00Z"
    * }
    */
    {
    "template": {
    "swaggerUI": {
    "enabled": true,
    "path": "/swagger",
    "theme": "dark",
    "options": {
    "deepLinking": true,
    "displayRequestDuration": true,
    "tryItOutEnabled": true,
    "requestInterceptor": true,
    "responseInterceptor": true
    }
    }
    }
    }
    <!-- template/swagger-ui.html -->
    <!DOCTYPE html>
    <html>
    <head>
    <title>{{title}} - Swagger UI</title>
    <link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
    <link rel="icon" type="image/png" href="./favicon.png" />
    <style>
    html {
    box-sizing: border-box;
    overflow: -moz-scrollbars-vertical;
    overflow-y: scroll;
    }
    *, *:before, *:after {
    box-sizing: inherit;
    }
    body {
    margin: 0;
    background: #fafafa;
    }
    </style>
    </head>
    <body>
    <div id="swagger-ui"></div>

    <script src="./swagger-ui-bundle.js"></script>
    <script src="./swagger-ui-standalone-preset.js"></script>
    <script>
    window.onload = function() {
    const ui = SwaggerUIBundle({
    url: './openapi.json',
    dom_id: '#swagger-ui',
    deepLinking: true,
    presets: [
    SwaggerUIBundle.presets.apis,
    SwaggerUIStandalonePreset
    ],
    plugins: [
    SwaggerUIBundle.plugins.DownloadUrl
    ],
    layout: "StandaloneLayout",
    requestInterceptor: function(request) {
    // Add custom headers
    request.headers['X-Custom-Header'] = 'APIDoc-Generated';
    return request;
    },
    responseInterceptor: function(response) {
    // Log responses for debugging
    console.log('API Response:', response);
    return response;
    }
    });
    };
    </script>
    </body>
    </html>
    /**
    * @api {post} /orders Create Order
    * @apiName CreateOrder
    * @apiGroup Orders
    *
    * @apiBody {Object} order Order data
    * @apiBody {Number} order.customerId Customer ID
    * @apiBody {Object[]} order.items Order items
    * @apiBody {Number} order.items.productId Product ID
    * @apiBody {Number{1..}} order.items.quantity Item quantity
    * @apiBody {Number} [order.items.unitPrice] Custom unit price
    * @apiBody {Object} order.shipping Shipping information
    * @apiBody {String} order.shipping.method Shipping method
    * @apiBody {Object} order.shipping.address Delivery address
    * @apiBody {String} order.shipping.address.street Street address
    * @apiBody {String} order.shipping.address.city City
    * @apiBody {String} order.shipping.address.country Country code
    * @apiBody {String} order.shipping.address.postalCode Postal code
    * @apiBody {Object} [order.payment] Payment information
    * @apiBody {String="credit_card","paypal","bank_transfer"} order.payment.method Payment method
    * @apiBody {String} [order.payment.token] Payment token
    *
    * @apiSuccess {Number} id Order ID
    * @apiSuccess {String} status Order status
    * @apiSuccess {Number} total Order total
    * @apiSuccess {Object[]} items Order items with details
    * @apiSuccess {Object} shipping Shipping information
    * @apiSuccess {Date} estimatedDelivery Estimated delivery date
    *
    * @apiExample {json} Request Example:
    * {
    * "order": {
    * "customerId": 123,
    * "items": [
    * {
    * "productId": 1,
    * "quantity": 2,
    * "unitPrice": 99.99
    * },
    * {
    * "productId": 2,
    * "quantity": 1
    * }
    * ],
    * "shipping": {
    * "method": "express",
    * "address": {
    * "street": "123 Main St",
    * "city": "New York",
    * "country": "US",
    * "postalCode": "10001"
    * }
    * },
    * "payment": {
    * "method": "credit_card",
    * "token": "tok_1234567890"
    * }
    * }
    * }
    */
    /**
    * @api {put} /users/:id Update User
    * @apiName UpdateUser
    * @apiGroup Users
    *
    * @apiParam {Number} id User ID
    *
    * @apiBody {Object} user User update data
    * @apiBody {String{2..50}} [user.name] User's full name
    * @apiBody {String} [user.email] Valid email address
    * @apiBody {Object} [user.profile] User profile data
    * @apiBody {String} [user.profile.bio] Profile biography
    * @apiBody {String[]} [user.profile.interests] User interests
    * @apiBody {Object} [user.profile.social] Social media links
    * @apiBody {String} [user.profile.social.twitter] Twitter handle
    * @apiBody {String} [user.profile.social.linkedin] LinkedIn URL
    * @apiBody {Object} [user.preferences] User preferences
    * @apiBody {Boolean} [user.preferences.emailNotifications] Email notifications
    * @apiBody {Boolean} [user.preferences.smsNotifications] SMS notifications
    * @apiBody {String="light","dark","auto"} [user.preferences.theme] UI theme
    *
    * @apiSuccess {Number} id User ID
    * @apiSuccess {String} name User's name
    * @apiSuccess {String} email User's email
    * @apiSuccess {Object} profile User profile
    * @apiSuccess {Object} preferences User preferences
    * @apiSuccess {Date} updatedAt Last update timestamp
    *
    * @apiExample {json} Partial Update Example:
    * {
    * "user": {
    * "profile": {
    * "bio": "Updated biography",
    * "interests": ["technology", "music", "travel"]
    * },
    * "preferences": {
    * "theme": "dark",
    * "emailNotifications": false
    * }
    * }
    * }
    */
    /**
    * @api {get} /analytics/reports Generate Report
    * @apiName GenerateReport
    * @apiGroup Analytics
    *
    * @apiExtension x-rate-limit {Object} Rate limiting information
    * @apiExtension x-rate-limit.requests {Number} 100 Requests per hour
    * @apiExtension x-rate-limit.window {String} "1h" Time window
    * @apiExtension x-cache-ttl {Number} 300 Cache TTL in seconds
    * @apiExtension x-feature-flag {String} "analytics-v2" Feature flag
    *
    * @apiQuery {String="daily","weekly","monthly"} period Report period
    * @apiQuery {Date} startDate Start date (ISO format)
    * @apiQuery {Date} endDate End date (ISO format)
    * @apiQuery {String[]} [metrics] Specific metrics to include
    *
    * @apiSuccess {Object} report Generated report
    * @apiSuccess {String} report.id Report ID
    * @apiSuccess {String} report.period Report period
    * @apiSuccess {Object} report.data Report data
    * @apiSuccess {Date} report.generatedAt Generation timestamp
    *
    * @apiExample {curl} cURL Example:
    * curl -X GET "https://api.example.com/analytics/reports?period=weekly&startDate=2024-01-01&endDate=2024-01-07" \
    * -H "Authorization: Bearer your-token"
    */
    {
    "paths": {
    "/analytics/reports": {
    "get": {
    "tags": ["Analytics"],
    "summary": "Generate Report",
    "operationId": "GenerateReport",
    "x-rate-limit": {
    "requests": 100,
    "window": "1h"
    },
    "x-cache-ttl": 300,
    "x-feature-flag": "analytics-v2",
    "parameters": [
    {
    "name": "period",
    "in": "query",
    "required": true,
    "schema": {
    "type": "string",
    "enum": ["daily", "weekly", "monthly"]
    }
    }
    ]
    }
    }
    }
    }
    # Generate OpenAPI specification
    apidoc -i src/ -o docs/ --openapi

    # Export to specific file
    apidoc -i src/ -o docs/ --openapi-output openapi.yaml

    # Include Swagger UI
    apidoc -i src/ -o docs/ --openapi --swagger-ui

    # Validate against OpenAPI spec
    apidoc -i src/ -o docs/ --openapi --validate
    # Import from OpenAPI file
    apidoc --import-openapi specs/api.json -o docs/

    # Import from URL
    apidoc --import-openapi https://api.example.com/openapi.json -o docs/

    # Generate code stubs
    apidoc --import-openapi specs/api.json --generate-stubs -o generated/
    • โœ… Use consistent naming conventions
    • โœ… Define reusable components
    • โœ… Include validation constraints
    • โœ… Provide meaningful descriptions
    • โœ… Include comprehensive examples
    • โœ… Document all error scenarios
    • โœ… Use realistic test data
    • โœ… Maintain schema accuracy
    • โœ… Validate schemas in CI/CD
    • โœ… Keep OpenAPI specs synchronized
    • โœ… Version schemas properly
    • โœ… Monitor schema breaking changes
    • โœ… Use schema references for large objects
    • โœ… Minimize schema complexity
    • โœ… Cache generated specifications
    • โœ… Optimize Swagger UI loading

    APIDoc's OpenAPI 3.0 integration provides seamless compatibility with modern API development tools while maintaining the simplicity and power of comment-based documentation.