microsoft / vscode-json-languageservice

JSON language service extracted from VSCode to be reused, e.g in the Monaco editor.
Other
237 stars 103 forks source link

OpenApi schema validation #162

Open DumpySquare opened 1 year ago

DumpySquare commented 1 year ago

Greetings,

I'm wondering if this team has been thinking about if/how to support an openapi spec?

So, in short, the native vscode schema validation has been a pivotal tool with our bigger declarative APIs. It is easy enough to setup file/language associations or $schema references for these individual endpoints.

The problem changes when we start talking about an OpenAPI spec. Now we have many schemas for many different endpoints.

As a prototype, I am able to open a json TextDocument and provide a codeLens with the method/url/schema-ref. On the back side I have an array of tuples that tracks each document with the openapi details like method/url/schema. So, when needed, I can use the current text document to find all the additional information.

I have some ideas on how to get this working and would like some input on how these ideas might fit into your bigger goals;

  1. Add a function/parameter to the text document or json language server to specify the exact json schema to validate the document with.

    This would allow me to dynamically provide the necessary schema for each document that gets opened

  2. Extend language server to process openapi spec

For option 2, something like this, could provide enough detail for this service to process;

{
    "$schema": "https://comby.com/some/public/openapi_spec.json",
    "url": "/api/books/",
    "method": "POST",
    "body": {
        "title": "Great Book",
        "author": "Brooks Books",
        "type": "unicorn",
        "pages": 543
    }
}
jeremyfiel commented 1 month ago

You can do this with schema registration in your settings.json

This assumes your files have .openapi.. You can update it if you use another file naming pattern.

"json.schemas": [
    {
      "fileMatch": [
        "*.openapi.json"
      ],
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "$id": "https://platform.openai.com/schemas/function-calling",
        "title": "OpenAI Function Calling",
        "$defs": {
          "objectWithProperties": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "array",
                  "boolean",
                  "integer",
                  "null",
                  "number",
                  "object",
                  "string"
                ]
              },
              "name": {
                "type": "string"
              },
              "description": {
                "type": "string"
              },
              "parameters": {
                "type": "object",
                "required": [
                  "type",
                  "required",
                  "properties"
                ],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "object"
                    ]
                  },
                  "required": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "properties": {
                    "$ref": "#/$defs/propertiesObject"
                  }
                },
                "additionalProperties": false
              },
              "enum": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "items": {
                "oneOf": [
                  {
                    "$ref": "#/$defs/objectWithProperties"
                  },
                  {
                    "type": "string"
                  }
                ]
              },
              "required": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "properties": {
                "$ref": "#/$defs/propertiesObject"
              },
              "$ref": {
                "type": "string"
              }
            },
            "additionalProperties": false
          },
          "propertiesObject": {
            "type": "object",
            "patternProperties": {
              ".*": {
                "$ref": "#/$defs/objectWithProperties"
              }
            },
            "additionalProperties": false
          }
        },
        "type": "object",
        "required": [
          "name",
          "description",
          "parameters"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "parameters": {
            "type": "object",
            "required": [
              "type",
              "required",
              "properties"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "object"
                ]
              },
              "required": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "properties": {
                "$ref": "#/$defs/propertiesObject"
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      }
    }
  ]

OR you can use the url property to point to the OAI repo for the correct schema.

"json.schemas": [
    {
      "fileMatch": [ "*.openapi.json" ], 
      "url": "https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/schemas/v3.0/schema.json"
    }
  ],
"yaml.schemas": [
  {
    "fileMatch": [ "*.openapi.yaml", "*openapi.yml"],
    "url": "https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/schemas/v3.0/schema.yaml"
  }
]