Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] OpenAPI import does not seem to honor default variables in servers declaration #1640

Closed
jn73 opened this issue Aug 14, 2019 · 12 comments · Fixed by #2151
Closed

[Bug] OpenAPI import does not seem to honor default variables in servers declaration #1640

jn73 opened this issue Aug 14, 2019 · 12 comments · Fixed by #2151
Assignees
Labels
PA-importers Package: Insomnia Importers

Comments

@jn73
Copy link

jn73 commented Aug 14, 2019

  • Insomnia Version: 6.6.2
  • Operating System: MacOS mojave 10.14.6

Details

I'm trying to import an OpenAPI 3 spec that uses variables in the server url. Default values are provided for these in the variables declaration. This results in an error when i try to import the file: Invalid URL: http://{host}:{port}/{basePath}

If I replace the url with the following string it works: http://localhost:8080/filemanagement

OpenAPI yaml file (parts of it - but it can be used to reproduce the bug and import works after replacing the servers/url part):

openapi: 3.0.2
info:
  description: OpenAPI definition for filemanagment services
  license:
    name: todo
    url: todo
  title: filemanagement
  version: 0.1.0
servers:
  - description: Devserver
    url: http://{host}:{port}/{basePath}
    variables:
      host:
        default: localhost
        description: Various servers (production, local development etc).
      port:
        default: "8080"
        description: Port to reach server on.
        enum:
          - "8080"
          - "9090"
      basePath:
        default: filemanagement
        description: API version, for information on other supported versions see those
          specifications.
tags:
  - description: Operations for managing file storages such as S3.
    name: storages
  - description: Operations for managing files connected to data sources.
    name: files

paths:
  /files:
    get:
      operationId: find_files
      parameters:
        - description: Search for files based on metadata.
          explode: true
          in: query
          name: metadata
          required: false
          schema:
            type: string
          style: form
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FileDescription'
          description: List of files matching the search criteria. List will be empty
            if no files match the criteria.
      tags:
        - files
      x-openapi-router-controller: filemanagement_service.controllers.files_controller
@welcome
Copy link

welcome bot commented Aug 14, 2019

👋 Thanks for opening your first issue! If you're reporting a 🐞 bug, please make sure
you include steps to reproduce it. If you're requesting a feature 🎁, please provide real
use cases that would benefit. 👪

To help make this a smooth process, please be sure you have first read the
contributing guidelines.

@ukiahsmith
Copy link

Looks like an issue with SwaggerParser seeing the template as incorrect syntax.

This is the error I have in the dev tools using your file.

[openapi3] Import file validation failed SyntaxError: Error resolving $ref pointer "//#/components/schemas/FileDescription". 
Token "components" does not exist.
    at Pointer.module.exports.Pointer.resolve (bundle.js:73541)
    at $Ref.module.exports.$Ref.resolve (bundle.js:67922)
    at $Refs.module.exports.$Refs._resolve (bundle.js:262539)
    at dereference$Ref (bundle.js:120025)
    at bundle.js:119984
    at Array.forEach (<anonymous>)
    at crawl (bundle.js:119977)
    at bundle.js:119990
    at Array.forEach (<anonymous>)

@jn73
Copy link
Author

jn73 commented Sep 19, 2019

Sorry for the late reply.. :( I made a temporary fix and forgot about this. Anyway.. that error message is because my example was incomplete. The definitions for the $ref is missing. Here's a more complete file that wont import and don't give that error:

openapi: 3.0.2
info:
  description: This API is for administrating files and file storages.
  license:
    name: Some license
  title: File and Storage API
  version: 0.1.0
servers:
  - description: Devserver
    url: http://{host}:{port}/{basePath}
    variables:
      host:
        default: localhost
        description: Various servers (production, local development etc).
      port:
        default: "8080"
        description: Port to reach server on.
        enum:
          - "8080"
          - "9090"
      basePath:
        default: filemanagement
        description:
          API version, for information on other supported versions see those
          specifications.
tags:
  - description: Operations for managing file storages such as S3.
    name: storages
  - description: Operations for managing files connected to data sources.
    name: files
paths:
  /files:
    get:
      operationId: find_files
      parameters:
        - description: Search for files based on file properties.
          explode: true
          in: query
          name: datasourceId
          required: false
          schema:
            type: string
          style: form
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FileDescription"
          description:
            List of files matching the search criteria. List will be empty
            if no files match the criteria.
      tags:
        - files
components:
  schemas:
    FileDescription:
      description:
        A metadata representation of a file. I.e. this entity does not
        include the raw file content.
      example:
        path: path
        name: name
        datasourceId: datasourceId
        createdTime: 0
        id: id
        storageId: storageId
      properties:
        id:
          type: string
        name:
          type: string
        path:
          type: string
        storageId:
          type: string
        createdTime:
          format: int64
          type: integer

@jn73
Copy link
Author

jn73 commented Sep 19, 2019

After replacing the url it works:
url: http://localhost:8080/

@gamezfreak
Copy link

I'm seeing this problem too with Insomnia 7.0.5 on macOS 10.15.1

The import failure happens when I use a variable for the server port.
http://petstore.swagger.io:{port}/{basepath} - fails
http://petstore.swagger.io:1234/{basepath} - OK
http://petstore.swagger.io:{port} - fails
http://petstore.swagger.io:1234 - OK

I started with the petstore sample from the OAS specification repo
https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore.yaml

Then modified the servers block to be

servers:
  - url: http://petstore.swagger.io:{port}/{basePath}
    variables:
      basePath:
        default: "v1"
      port:
        default: "1234"

Insomnia shows two errors

  1. Import Failed - TypeError: result.summary[_models__WEBPACK_IMPORTED_MODULE_11__workspace.type] is not iterable
  2. Failed to import - Import failed - Invalid URL http://petstore.swagger.io:{port}/{basePath}

import_error_1
import_error_2

I don't get any syntax errors about the file and it imports successfully into Postman 7.13.0. Hoping to get things working with Insomnia though :)

Full modified petstore.yaml showing the problem

openapi: "3.0.0"
info:
  version: 1.0.0
  title: Swagger Petstore
  license:
    name: MIT
servers:
  - url: http://petstore.swagger.io:{port}/{basePath}
    variables:
      basePath:
        default: "v1"
      port:
        default: "1234"
paths:
  /pets:
    get:
      summary: List all pets
      operationId: listPets
      tags:
        - pets
      parameters:
        - name: limit
          in: query
          description: How many items to return at one time (max 100)
          required: false
          schema:
            type: integer
            format: int32
      responses:
        '200':
          description: A paged array of pets
          headers:
            x-next:
              description: A link to the next page of responses
              schema:
                type: string
          content:
            application/json:    
              schema:
                $ref: "#/components/schemas/Pets"
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
    post:
      summary: Create a pet
      operationId: createPets
      tags:
        - pets
      responses:
        '201':
          description: Null response
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /pets/{petId}:
    get:
      summary: Info for a specific pet
      operationId: showPetById
      tags:
        - pets
      parameters:
        - name: petId
          in: path
          required: true
          description: The id of the pet to retrieve
          schema:
            type: string
      responses:
        '200':
          description: Expected response to a valid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Pet"
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
components:
  schemas:
    Pet:
      type: object
      required:
        - id
        - name
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        tag:
          type: string
    Pets:
      type: array
      items:
        $ref: "#/components/schemas/Pet"
    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: integer
          format: int32
        message:
          type: string

@vitaliis
Copy link

Not sure if it is the same or not, but I also can not import OpenAPI to insomnia because of 2 errors.

  1. Import failed TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined
  2. failed to import 'Import failed' Cannot read property 'map' of undefined.
    This happens then you press "Import from File" button in a fresh workspace for example.

The first error is also shown when you go to Application > Preferences under "Data" tab and use "Import from clipboard" option.

Sadly, currently it seems impossible to import an OpenAPI spec into insomnia.

@skorokithakis
Copy link

skorokithakis commented May 1, 2020

I'm affected by this bug as well. I get "Cannot read property 'map' of undefined." whether I import from URL or file.

@sylann
Copy link

sylann commented May 6, 2020

Exactly in the same situation as @vitalis. Also I just wanted to point out that the bug does not occur when you directly copy&paste your openapi.json inside of the Insomnia Rest Designer text editor.

@develohpanda
Copy link
Contributor

develohpanda commented May 6, 2020

I recently built functionality to honor default variables in an OpenAPI spec server, as part of the openapi-2-kong package, but the logic is fairly generic and should be usable by insomnia-importers as well. With some adaptation, I believe this would solve the original bug reported.

const protocolSearchValue = /{([^}]+)}(?=:\/\/)/g; // positive lookahead for ://
const pathSearchValue = /{([^}]+)}(?!:\/\/)/g; // negative lookahead for ://
export function resolveUrlVariables(url: string, variables?: OA3Variables): string {
const protocolResolved = resolveVariables(url, protocolSearchValue, 'http', variables);
const pathResolved = resolveVariables(protocolResolved, pathSearchValue, '.*', variables);
return pathResolved;
}
export function resolveVariables(
str: string,
regExp: RegExp,
fallback: string,
variables?: OA3Variables,
): string {
let resolved = str;
let shouldContinue = true;
do {
// Regexp contain the global flag (g), meaning we must execute our regex on the original string.
// https://stackoverflow.com/a/27753327
const [replace, name] = regExp.exec(str) || [];
const value = variables?.[name]?.default || fallback;
shouldContinue = !!name;
resolved = replace ? resolved.replace(replace, value) : resolved;
} while (shouldContinue);
return resolved;
}

In terms of importing, I wasn't able to reproduce the errors being reported (on v7.1.1).

@vitaliis or @SylannBin, could you please share some reproduction steps for what you're seeing? Are you facing this with the example specification (#1640 (comment)) or a different one?

@develohpanda develohpanda added the PA-importers Package: Insomnia Importers label May 6, 2020
@sylann
Copy link

sylann commented May 8, 2020

First, I'm on Macos Catalina, and I use Insomnia Version 7.1.1 (7.1.1.3350)

Steps to reproduce:

  1. In the data menu, click on "Import data"
  2. Choose any option as long as you use the data given below

image

From clipboard

Copy the content of data below and choose From clipboard

I get the following error alone and the text is not selectable.

TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined

From url

http://localhost:8000/openapi.json

image

From file

image

AND

image

OpenAPI json schema

It's based of the fastapi doc for Oauth2 bearer token login, so I think it represents a fairly common case.

See data
{
  "openapi": "3.0.2",
  "info": {
    "title": "FastAPI",
    "version": "0.1.0"
  },
  "paths": {
    "/login/access-token": {
      "post": {
        "tags": [
          "Users"
        ],
        "summary": "Login Access Token",
        "description": "Login and get an access token with your credentials.",
        "operationId": "login_access_token_login_access_token_post",
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/Body_login_access_token_login_access_token_post"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccessTokenSchema"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AccessTokenSchema": {
        "title": "AccessTokenSchema",
        "required": [
          "access_token",
          "token_type"
        ],
        "type": "object",
        "properties": {
          "access_token": {
            "title": "Access Token",
            "type": "string"
          },
          "token_type": {
            "title": "Token Type",
            "type": "string"
          }
        }
      },
      "Body_login_access_token_login_access_token_post": {
        "title": "Body_login_access_token_login_access_token_post",
        "required": [
          "username",
          "password"
        ],
        "type": "object",
        "properties": {
          "grant_type": {
            "title": "Grant Type",
            "pattern": "password",
            "type": "string"
          },
          "username": {
            "title": "Username",
            "type": "string"
          },
          "password": {
            "title": "Password",
            "type": "string"
          },
          "scope": {
            "title": "Scope",
            "type": "string",
            "default": ""
          },
          "client_id": {
            "title": "Client Id",
            "type": "string"
          },
          "client_secret": {
            "title": "Client Secret",
            "type": "string"
          }
        }
      },
      "HTTPValidationError": {
        "title": "HTTPValidationError",
        "type": "object",
        "properties": {
          "detail": {
            "title": "Detail",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            }
          }
        }
      },
      "ValidationError": {
        "title": "ValidationError",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "type": "object",
        "properties": {
          "loc": {
            "title": "Location",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "msg": {
            "title": "Message",
            "type": "string"
          },
          "type": {
            "title": "Error Type",
            "type": "string"
          }
        }
      }
    },
    "securitySchemes": {
      "OAuth2PasswordBearer": {
        "type": "oauth2",
        "flows": {
          "password": {
            "scopes": {},
            "tokenUrl": "/login/access-token"
          }
        }
      }
    }
  }
}

@develohpanda
Copy link
Contributor

develohpanda commented May 10, 2020

Thanks for that @SylannBin! A missing servers declaration wasn't handled by the openapi3 importer previously, resulting in those errors. I'm willing to say @vitaliis is experiencing the same thing as well.

That has been resolved by #2007 though, and will be included in the next release of Insomnia Core. I confirmed by importing that specification successfully while running on the latest develop.

image

Also I just wanted to point out that the bug does not occur when you directly copy&paste your openapi.json inside of the Insomnia Rest Designer text editor.

This is because Designer already includes the fix 😄

@vitaliis
Copy link

Right. The issue is gone when you add the servers section. I also see the following error, but again it is also resolved after adding the servers section.
image

Good that it is generally resolved by #2007. Thanks, @develohpanda for the info!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PA-importers Package: Insomnia Importers
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants