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

Add vendor examples extension support to Swagger converter #224

Closed
ostridm opened this issue Feb 9, 2024 · 0 comments · Fixed by #225
Closed

Add vendor examples extension support to Swagger converter #224

ostridm opened this issue Feb 9, 2024 · 0 comments · Fixed by #225
Assignees
Labels
Type: enhancement New feature or request.

Comments

@ostridm
Copy link
Contributor

ostridm commented Feb 9, 2024

Description

Vendors are extending the specification in order to overcome some drawbacks utilizing same extension names with different approach, e.g.:

Possible solution

Implement limited support for vendor examples:

  • exclude vendor examples handling for the OAS 3 and above specification versions.
  • maintain backward compatibility for Swagger by introducing options for oas2har function, which allow enabling vendor examples inclusion explicitly.
  • implement an ad-hoc solution, maximizing support of the variety of different example structural representation introduced by vendors (see below).

Vendor examples representation

API connect/Smartbear:

x-example: value1
x-example: 
  key1: value1
  key2: value2

Redocly:

x-example:
  text/plain: value1
x-example: 
  application/json:
      key1: value1
      key2: value2

Schemathesis:

x-example: value1
x-examples: 
  application/json:
      key1: value1
      key2: value2

Other:

x-example: value1
x-example:
  example-name: value1
x-examples: 
  example-name:
      key1: value1
      key2: value2

Vendor example inclusion

When vendor examples inclusion is enabled, the following rules should apply:

  • prefer x-example / x-examples if any unless example exists
  • when looking for vendor example, try to extract x-example primitive value first
  • when primitive value is not extracted, try to traverse the x-example / x-exmples structured object looking for the object in hierarchy which is satisfied to schema keys matching, e.g. such object must not have any key which is not listed in schema.
  • when no any vendor example satisfies schema keys match, ignore the vendor examples and try to infer the sample value in existing way.

Expected behaviour

Pass the my-schema.yaml (see below) to the oas2har as follows:

import { oas2har } from '@har-sdk/oas';
import { readFile } from 'fs';
import { promisify } from 'util';
import { load } from 'js-yaml';

const content = await promisify(readFile)(
  './my-schema.yaml',
  'utf8'
);

const result = oas2har(load(content) as OpenAPIV2.Document, {includeVendorExamples: true});
my-schema.yaml
swagger: '2.0'
info:
  title: Sample API
  version: 1.0.0
host: example.com
schemes:
  - https
paths:
  /sample/{id}:
    put:
      consumes:
        - application/x-www-form-urlencoded
      produces:
        - application/json
      parameters:
        - name: id
          in: path
          required: true
          type: integer
          default: 0
          x-example: 123
        - name: filter
          in: query
          required: false
          type: string
          default: 'default_filter'
          x-example: 'x_example_filter'
        - name: Authorization
          in: header
          required: true
          type: string
          default: 'Bearer default_jwt_token'
          x-example: 'Bearer x_example_jwt_token'
        - name: name
          in: formData
          type: string
          default: default_name
          x-example: x_example_name
      responses:
        '201':
          description: ''
  /sample:
    post:
      consumes:
        - application/json
      produces:
        - application/json
      parameters:
        - name: payload
          in: body
          required: true
          schema:
            type: object
            properties:
              name:
                type: string
                default: 'default_name'
              age:
                type: integer
                default: 10
            x-example:
              name: x_example_name
              age: 30
      responses:
        '201':
          description: ''
    patch:
      consumes:
        - application/json
      produces:
        - application/json
      parameters:
        - name: payload
          in: body
          required: true
          schema:
            type: object
            properties:
              name:
                type: string
                default: 'default_name'
              age:
                type: integer
                default: 10
            x-example:
              applictaion/json:
                name: x_example_name
                age: 30
      responses:
        '201':
          description: ''

Expected result

HarEntry takes its sample values for the header, path, query, posdData parameters from the x-example node.

  {
    "queryString": [
      {
        "name": "filter",
        "value": "x_example_filter"
      }
    ],
    "cookies": [],
    "method": "PUT",
    "headers": [
      {
        "value": "application/x-www-form-urlencoded",
        "name": "content-type"
      },
      {
        "value": "application/json",
        "name": "accept"
      },
      {
        "value": "Bearer x_example_jwt_token",
        "name": "authorization"
      }
    ],
    "httpVersion": "HTTP/1.1",
    "headersSize": 0,
    "bodySize": 0,
    "postData": {
      "mimeType": "application/x-www-form-urlencoded",
      "text": "name=x_example_name"
    },
    "url": "https://example.com/sample/123?filter=x_example_filter"
  }

HarEntry takes its sample values for the body parameter from the x-example performing traversal of the vendor examples until schema matched.

  {
    "queryString": [],
    "cookies": [],
    "method": "POST",
    "headers": [
      {
        "value": "application/json",
        "name": "content-type"
      },
      {
        "value": "application/json",
        "name": "accept"
      }
    ],
    "httpVersion": "HTTP/1.1",
    "headersSize": 0,
    "bodySize": 0,
    "postData": {
      "mimeType": "application/json",
      "text": "{\"name\":\"x_example_name\",\"age\":30}"
    },
    "url": "https://example.com/sample"
  }
ostridm added a commit that referenced this issue Feb 12, 2024
ostridm added a commit that referenced this issue Feb 13, 2024
ostridm added a commit that referenced this issue Feb 13, 2024
ostridm added a commit that referenced this issue Feb 13, 2024
ostridm added a commit that referenced this issue Feb 13, 2024
@ostridm ostridm self-assigned this Feb 13, 2024
@ostridm ostridm added the Type: enhancement New feature or request. label Feb 13, 2024
@ostridm ostridm changed the title Add x-example vendor extension support in Swagger converter Add vendor examples extension support to Swagger converter Feb 13, 2024
ostridm added a commit that referenced this issue Feb 15, 2024
ostridm added a commit that referenced this issue Feb 15, 2024
ostridm added a commit that referenced this issue Feb 16, 2024
ostridm added a commit that referenced this issue Feb 16, 2024
ostridm added a commit that referenced this issue Feb 16, 2024
ostridm added a commit that referenced this issue Feb 16, 2024
ostridm added a commit that referenced this issue Feb 16, 2024
ostridm added a commit that referenced this issue Feb 16, 2024
ostridm added a commit that referenced this issue Feb 16, 2024
ostridm added a commit that referenced this issue Feb 16, 2024
ostridm added a commit that referenced this issue Feb 16, 2024
ostridm added a commit that referenced this issue Feb 16, 2024
ostridm added a commit that referenced this issue Feb 16, 2024
ostridm added a commit that referenced this issue Feb 27, 2024
ostridm added a commit that referenced this issue Feb 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: enhancement New feature or request.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant