Swagger UI

repository·main·Indexed 12 days ago

https://github.com/swagger-api/swagger-ui

A tool for visualizing and interacting with API resources directly from an OpenAPI (formerly Swagger) Specification. It provides a graphical interface for exploring endpoints, viewing parameters, and making API calls. Available as the standard swagger-ui module for SPAs, swagger-ui-dist for server-side projects, and swagger-ui-react for React applications. Version 5.32.13 supports OpenAPI specifications 2.0 through 3.2.0.

Tokens
28.7K
Snippets
93
Records
119
Agent score
92%

What's inside Swagger UI

  1. Getting started with Swagger UI

    main

    Swagger UI is a tool for visualizing and interacting with API resources. Documentation for using, customizing, and developing Swagger UI is organized into three main areas:

    Usage

    Covers installation, configuration, CORS, OAuth2, deep linking, version detection, and known limitations.

    Customization

    Covers the Plugin API, creating custom layouts, and using plug-points to extend functionality.

    Development

    Covers setting up the local development environment and available scripts.

  2. Use swagger-ui-dist as a dependency-free module

    main

    The swagger-ui-dist package provides the entire Swagger UI distribution folder as a dependency-free npm module. This is ideal if you want to manage assets manually without letting npm install additional dependencies for you.

    If you prefer to have npm manage all necessary dependencies automatically, use the swagger-ui package instead.

  3. What is a Swagger UI plugin?

    main

    A plugin is a function that returns an object used to augment or modify Swagger UI's functionality. The returned object can contain state plugins (actions, reducers, selectors), components, wrappers for existing logic, and helper functions.

    Important: Dependency Management Swagger UI does not have built-in dependency management for plugins. If your plugin depends on another, you must ensure the dependent plugin is loaded after the plugin it relies on.

    Important: Semantic Versioning Swagger UI's internal APIs are not part of the public contract and may change without a major version update. If your plugin consumes or overrides internal core APIs, it is recommended to pin your dependency to a specific minor version using a tilde (e.g., "swagger-ui": "~3.11.0") in your package.json.

    const MyPlugin = function(system) {
      return {
        // plugin implementation
      };
    };
  4. Configure deep-linking behavior with docExpansion

    main

    If you want to link to a specific tag or operation while ensuring all other parts of the specification remain collapsed, combine deepLinking: true with docExpansion: 'none'.

    Because the deep link takes precedence over the docExpansion setting, Swagger UI will collapse everything except for the specific tag or operation targeted by the URL fragment.

    SwaggerUIBundle({
      url: "https://petstore.swagger.io/v2/swagger.json",
      dom_id: "#swagger-ui",
      deepLinking: true,
      docExpansion: 'none'
    });
  5. What are Providers in Swagger UI

    main

    Providers act as generic bridges to third-party components within Swagger UI. They serve two primary architectural purposes:

    1. Plugin Extensibility: Because providers are loaded through the getComponent mechanism, plugins can use them to override third-party components.
    2. Decoupling: They prevent the core library from being tightly coupled to specific third-party implementations, allowing for easier swaps or updates without breaking the core logic.
  6. Override JSON Schema input components

    main

    Swagger UI uses specific component names to map OpenAPI Specification schema information to input components. You can define custom input components by matching the following naming convention:

    1. If format is defined: JsonSchema_${type}_${format}
    2. Fallback (if format not defined or component missing): JsonSchema_${type}
    3. Default: JsonSchema_string

    Example: Implementing a Date-Picker To integrate a library like react-datepicker for format: date and format: date-time, you must provide components named JsonSchema_string_date and JsonSchema_string_date-time.

    import React from "react";
    import DatePicker from "react-datepicker";
    import "react-datepicker/dist/react-datepicker.css";
    
    const JsonSchema_string_date = (props) => {
      const dateNumber = Date.parse(props.value);
      const date = dateNumber ? new Date(dateNumber) : new Date();
    
      return (
        <DatePicker
          selected={date}
          onChange={d => props.onChange(d.toISOString().substring(0, 10))}
        />
      );
    }
    
    const JsonSchema_string_date_time = (props) => {
      const dateNumber = Date.parse(props.value);
      const date = dateNumber ? new Date(dateNumber) : new Date();
    
      return (
        <DatePicker
          selected={date}
          onChange={d => props.onChange(d.toISOString())}
          showTimeSelect
          timeFormat="p"
          dateFormat="Pp"
        />
      );
    }
    
    export const DateTimeSwaggerPlugin = {
      components: {
        JsonSchema_string_date: JsonSchema_string_date,
        "JsonSchema_string_date-time": JsonSchema_string_date_time
      }
    };
  7. How the Swagger UI plugin system works

    main

    The system is the central JavaScript object that powers the Swagger UI application at runtime. It acts as a registry and dependency injector, holding:

    • React components
    • Bound Redux actions and reducers
    • Bound Reselect state selectors
    • A system-wide collection of available components
    • Built-in helpers (e.g., getComponent, makeMappedContainer, getStore)
    • Library references (system.React, system.Im for Immutable.js)
    • User-defined helper functions

    The system is constructed during initialization by "compiling" each plugin provided via the presets and plugins configuration options.

  8. Understand forbidden header name limitations in Swagger UI

    main

    When using Swagger UI in a web browser, certain HTTP header names cannot be manually controlled or modified by the application due to browser security restrictions. This is a limitation of the browser environment, not Swagger UI itself.

    Impact on OpenAPI 3.0: The most significant impact is that OpenAPI 3.0 Cookie parameters cannot be controlled when running Swagger UI in a browser. You cannot manually set or override cookies via the Swagger UI interface for these requests.

  9. How the Swagger-UI plugin system works

    main

    Swagger-UI uses a plugin system to extend its core functionality. A plugin is a factory function that receives a toolbox argument and returns an object containing different types of extensions. These extensions are merged into a global system object and then bound to the application state.

    Plugin Types

    • statePlugins: Used to manage application state via namespaces. Each namespace can contain:
      • selectors: Functions used to query the state. They are passed a getState function to ensure they remain decoupled from specific state instances.
      • reducers: Functions that modify the state. They receive the current state (which is an Immutable object) and an action, returning a new state.
      • actions: Functions that trigger state changes.
        • Synchronous actions must return a plain object (e.g., { type: 'ACTION_NAME', payload: ... }) for the reducer to handle.
        • Asynchronous actions must return a function that receives the system as an argument, allowing it to call other actions.
      • wrapActions: A way to intercept and replace existing actions. This is useful for adding side effects (like logging) while still calling the original action.
    • components: A map of names to React components.
    • fn: A collection of common utility functions.

    The toolbox Argument

    The plugin factory function receives a toolbox object. This object provides access to the entire plugin system at the time the plugin is called and includes a reference to the Immutable library (e.g., toolbox.Im), so plugin authors do not need to bundle it themselves.

    export function SomePlugin(toolbox) {
      return {
        statePlugins: { /* ... */ },
        components: { /* ... */ },
        fn: { /* ... */ }
      };
    }
  10. Implement custom error transformers

    main

    Error transformers allow you to intercept and modify error messages generated by Redux error actions before they are processed by the reducer. This is useful for making error messages more user-friendly or adjusting metadata like line numbers.

    Data Contract

    Input: The transform function receives an Immutable List of Immutable Maps representing the current errors.

    Output: The function must return a List of Immutable Maps with the same structure.

    Required Keys: To ensure compatibility with the UI, every error map returned by your transformer must contain the following keys:

    • line
    • level
    • message
    • source
    • type

    Deleting Errors

    To completely remove an error from the state, return null in place of that error within the returned list. The system will automatically filter out null values before returning the final error array.

    export function transform(errors) {
      return errors.map(err => {
        err.line += 10
        return err
      })
    }
  11. Use the Swagger UI plugin system to override internals

    main

    Swagger UI exposes most of its internal logic through a plugin system. You can create plugins to wrap, extend, or override core behaviors.

    Warning on Semantic Versioning: Internal APIs are not part of the public contract and may change without a major version bump. To ensure stability when using internal APIs, pin your dependency to a specific minor version using a tilde in your package.json:

    {
      "dependencies": {
        "swagger-ui": "~3.11.0"
      }
    }
  12. Run Cypress end-to-end integration tests

    main

    Swagger UI uses Cypress for end-to-end testing. You can run the test suites using the following commands:

    • Run the full suite (headless): Starts the required servers, runs Cypress headless, and shuts down the servers automatically.
    • Run interactively: Opens the Cypress runner to debug or run individual specs.
    • Run a single spec (headless): Requires starting the servers in one terminal and running the spec command in a second terminal.
    # Run the full suite
    npm run cy:ci
    
    # Open Cypress runner for interactive debugging
    npm run cy:dev
    
    # Run a single spec headless
    npm run cy:start
    # in a second terminal:
    npm run cy:run -- --spec "test/e2e-cypress/e2e/features/deep-linking.cy.js"