All Projects → epiphone → Class Validator Jsonschema

epiphone / Class Validator Jsonschema

Licence: mit
Convert class-validator-decorated classes into JSON schema

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to Class Validator Jsonschema

openapi-schemas
JSON Schemas for every version of the OpenAPI Specification
Stars: ✭ 22 (-81.36%)
Mutual labels:  validation, json-schema, openapi3
Json Schema Spec
The JSON Schema I-D sources
Stars: ✭ 2,441 (+1968.64%)
Mutual labels:  json-schema, api-documentation, validation
Malli
Data-Driven Schemas for Clojure/Script.
Stars: ✭ 667 (+465.25%)
Mutual labels:  json-schema, validation
Pydantic
Data parsing and validation using Python type hints
Stars: ✭ 8,362 (+6986.44%)
Mutual labels:  json-schema, validation
Spectral
A flexible JSON/YAML linter for creating automated style guides, with baked in support for OpenAPI v2 & v3.
Stars: ✭ 876 (+642.37%)
Mutual labels:  json-schema, openapi3
Dredd
Language-agnostic HTTP API Testing Tool
Stars: ✭ 3,770 (+3094.92%)
Mutual labels:  openapi3, validation
Create Openapi Repo
🤖 Generator for GH repo to help you manage the OpenAPI definition lifecycle
Stars: ✭ 513 (+334.75%)
Mutual labels:  openapi3, api-documentation
Apispec
A pluggable API specification generator. Currently supports the OpenAPI Specification (f.k.a. the Swagger specification)..
Stars: ✭ 831 (+604.24%)
Mutual labels:  json-schema, openapi3
Json Schema Validator
A fast Java JSON schema validator that supports draft V4, V6, V7 and V2019-09
Stars: ✭ 292 (+147.46%)
Mutual labels:  json-schema, openapi3
Rest Layer
REST Layer, Go (golang) REST API framework
Stars: ✭ 1,068 (+805.08%)
Mutual labels:  json-schema, api-documentation
Uvicorn Gunicorn Fastapi Docker
Docker image with Uvicorn managed by Gunicorn for high-performance FastAPI web applications in Python 3.6 and above with performance auto-tuning. Optionally with Alpine Linux.
Stars: ✭ 1,014 (+759.32%)
Mutual labels:  json-schema, openapi3
Schemasafe
A reasonably safe JSON Schema validator with draft-04/06/07/2019-09 support.
Stars: ✭ 67 (-43.22%)
Mutual labels:  json-schema, validation
Ghlocalapi
(Unofficial) Google Home local API documentation.
Stars: ✭ 334 (+183.05%)
Mutual labels:  openapi3, api-documentation
Swagger Cli
Swagger 2.0 and OpenAPI 3.0 command-line tool
Stars: ✭ 321 (+172.03%)
Mutual labels:  json-schema, validation
Full Stack Fastapi Postgresql
Full stack, modern web application generator. Using FastAPI, PostgreSQL as database, Docker, automatic HTTPS and more.
Stars: ✭ 7,635 (+6370.34%)
Mutual labels:  json-schema, openapi3
Jsonschema
An implementation of the JSON Schema specification for Python
Stars: ✭ 3,474 (+2844.07%)
Mutual labels:  validation, json-schema
Swagger Parser
Swagger 2.0 and OpenAPI 3.0 parser/validator
Stars: ✭ 710 (+501.69%)
Mutual labels:  json-schema, validation
svelte-form
JSON Schema form for Svelte v3
Stars: ✭ 47 (-60.17%)
Mutual labels:  validation, json-schema
Openapi Viewer
Browse and test a REST API described with the OpenAPI 3.0 Specification
Stars: ✭ 82 (-30.51%)
Mutual labels:  openapi3, api-documentation
Fastapi
FastAPI framework, high performance, easy to learn, fast to code, ready for production
Stars: ✭ 39,588 (+33449.15%)
Mutual labels:  json-schema, openapi3

class-validator-jsonschema

codecov npm version

Convert class-validator-decorated classes into OpenAPI-compatible JSON Schema. The aim is to provide a best-effort conversion: since some of the class-validator decorators lack a direct JSON Schema counterpart, the conversion is bound to be somewhat opinionated. To account for this multiple extension points are available.

Installation

npm install class-validator-jsonschema

Note the peer dependency versions in package.json. Try installing a previous major version of class-validator-jsonschema in case you're stuck with older peer dependencies.

Usage

import { IsOptional, IsString, MaxLength } from 'class-validator'
import { validationMetadatasToSchemas } from 'class-validator-jsonschema'

class BlogPost {
  @IsString() id: string

  @IsOptional()
  @MaxLength(20, { each: true })
  tags: string[]
}

const schemas = validationMetadatasToSchemas()
console.log(schemas)

which prints out:

{
  "BlogPost": {
    "properties": {
      "id": {
        "type": "string"
      },
      "tags": {
        "items": {
          "maxLength": 20,
          "type": "string"
        },
        "type": "array"
      }
    },
    "required": ["id"],
    "type": "object"
  }
}

validationMetadatasToSchemas takes an options object as an optional parameter. Check available configuration objects and defaults at options.ts.

Adding and overriding default converters

With options.additionalConverters you can add new validation metadata converters or override the existing ones. Let's say we want to, for example, add a handy description field to each @IsString()-decorated property:

import { ValidationTypes } from 'class-validator'

// ...

const schemas = validationMetadatasToSchemas({
  additionalConverters: {
    [ValidationTypes.IS_STRING]: {
      description: 'A string value',
      type: 'string',
    },
  },
})

which now outputs:

{
  "BlogPost": {
    "properties": {
      "id": {
        "description": "A string value",
        "type": "string"
      }
      // ...
    }
  }
}

An additional converter can also be supplied in form of a function that receives the validation metadata item and global options, outputting a JSON Schema property object (see below for usage):

type SchemaConverter = (
  meta: ValidationMetadata,
  options: IOptions
) => SchemaObject | void

Custom validation classes

class-validator allows you to define custom validation classes. You might for example validate that a string's length is between given two values:

import {
  Validate,
  ValidationArguments,
  ValidatorConstraint,
  ValidatorConstraintInterface,
} from 'class-validator'

// Implementing the validator:

@ValidatorConstraint()
export class CustomTextLength implements ValidatorConstraintInterface {
  validate(text: string, validationArguments: ValidationArguments) {
    const [min, max] = validationArguments.constraints
    return text.length >= min && text.length <= max
  }
}

// ...and putting it to use:

class Post {
  @Validate(CustomTextLength, [0, 11])
  title: string
}

Now to handle your custom validator's JSON Schema conversion include a CustomTextLength converter in options.additionalConverters:

const schemas = validationMetadatasToSchemas({
  additionalConverters: {
    CustomTextLength: (meta) => ({
      maxLength: meta.constraints[1],
      minLength: meta.constraints[0],
      type: 'string',
    }),
  },
})

Decorating with additional properties

Validation classes can also be supplemented with the JSONSchema decorator. JSONSchema can be applied both to classes and individual properties; any given keywords are then merged into the JSON Schema derived from class-validator decorators:

import { JSONSchema } from 'class-validator-jsonschema'

@JSONSchema({
  description: 'A User object',
  example: { id: '123' },
})
class BlogPost {
  @IsString()
  @JSONSchema({
    description: 'User primary key',
    format: 'custom-id',
  })
  id: string
}

Results in the following schema:

{
  "BlogPost": {
    "description": "A User object",
    "example": { "id": "123" },
    "properties": {
      "id": {
        "description": "User primary key",
        "format": "custom-id",
        "type": "string"
      }
    },
    "required": ["id"],
    "type": "object"
  }
}

JSONSchema decorators also flow down from parent classes into inherited validation decorators. Note though that if the inherited class uses JSONSchema to redecorate a property from the parent class, the parent class JSONSchema gets overwritten - i.e. there's no merging logic.

Custom handlers

Alternatively JSONSchema can take a function of type (existingSchema: SchemaObject, options: IOptions) => SchemaObject. The return value of this function is then not automatically merged into existing schema (i.e. the one derived from class-validator decorators). Instead you can handle merging yourself in whichever way is preferred, the idea being that removal of existing keywords and other more complex overwrite scenarios can be implemented here.

@ValidateNested and arrays

class-validator supports validating nested objects via the @ValidateNested decorator. Likewise JSON Schema generation is supported out-of-the-box for nested properties such as

@ValidateNested()
user: UserClass

However, due to limitations in Typescript's reflection system we cannot infer the inner type of a generic class. In effect this means that properties like

@ValidateNested({ each: true })
users: UserClass[]

@ValidateNested()
user: Promise<UserClass>

would resolve to classes Array and Promise in JSON Schema. To work around this limitation we can use @Type from class-transformer to explicitly define the nested property's inner type:

import { Type } from 'class-transformer'
import { validationMetadatasToSchemas } from 'class-validator-jsonschema'
const { defaultMetadataStorage } = require('class-transformer/cjs/storage') // See https://github.com/typestack/class-transformer/issues/563 for alternatives

class User {
  @ValidateNested({ each: true })
  @Type(() => BlogPost) // 1) Explicitly define the nested property type
  blogPosts: BlogPost[]
}

const schemas = validationMetadatasToSchemas({
  classTransformerMetadataStorage: defaultMetadataStorage, // 2) Define class-transformer metadata in options
})

Note also how the classTransformerMetadataStorage option has to be defined for @Type decorator to take effect.

Using a custom validation metadataStorage

Under the hood we grab validation metadata from the default storage returned by class-validator's getMetadataStorage(). In case of a version clash or something you might want to manually pass in the storage:

const schemas = validationMetadatasToSchemas({
  classValidatorMetadataStorage: myCustomMetadataStorage,
})

Limitations

There's no handling for class-validators validation groups or conditional decorator (@ValidateIf) out-of-the-box. The above-mentioned extension methods can be used to fill the gaps if necessary.

The OpenAPI spec doesn't currently support the new JSON Schema draft-06 keywords const and contains. This means that constant value decorators such as @IsEqual() and @ArrayContains() translate to quite complicated schemas. Hopefully in a not too distant future these keywords are adopted into the spec and we'll be able to provide neater conversion.

Handling null values is also tricky since OpenAPI doesn't support JSON Schema's type: null, providing its own nullable keyword instead. The default @IsEmpty() converter for example opts for nullable but you can use type: null instead via options.additionalConverters:

// ...
additionalConverters: {
  [ValidationTypes.IS_EMPTY]: {
    anyOf: [
      {type: 'string', enum: ['']},
      {type: 'null'}
    ]
  }
}

TODO

  • [x] handle skipMissingProperties and @isDefined()
  • [x] decorators for overwriting prop schemas
  • [ ] optional property descriptions (e.g. A Base64-encoded string)
  • [ ] optional draft-06 keywords
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].