Kotsu icon indicating copy to clipboard operation
Kotsu copied to clipboard

Type annotation and validation for data

Open ArmorDarks opened this issue 8 years ago • 5 comments

Well, it turned out that we ending up writing prototypes of datasets in free form quite often. It would be much better if those descriptions had real types annotations, so that we can validate database entries based on it.

So, I went to explore some solutions.

Static type checkers:

Assumes declaring types annotations as part of JavaScript syntax.

  • Flow, popular Facebook's solution;

    type Person = {
      name: string, // required string
      surname?: string, // optional string
      age: number,
      tags: Array<string>
    };
    
  • TypeScript, popular MS solution.

  • Google Closure Compiler (by using comments-based type annotation, see example) (pure js implementation)

The issues with those:

  1. Obviously it's very hard to integrate with CoffeeScript.
  2. Requires additional transpilation (flow should be transpiled with babel (with this?), TS should be compiled)
  3. Doesn't allow to validate anything in runtime (for instance, during Jest tests). Definitely a bummer for our goals.

Flow has sort-of workaround for CoffeeScript with declaring types as comments: https://flowtype.org/blog/2015/02/20/Flow-Comments.html

Runtime type checking and validation

Allows to require entity, which describes dataset, and validate it against dataset in runtime, by invoking validation function.

JSON Schema draft

Those validators expects Object to be described based on JSON Schema which currently has status of draft.

Example:

{
  "title": "Example Schema",
  "type": "object",
  "properties": {
    "firstName": {
      "type": "string"
    },
    "lastName": {
      "type": "string"
    },
    "age": {
      "description": "Age in years",
      "type": "integer",
      "minimum": 0
    }
  },
  "required": ["firstName", "lastName"]
}

This allows to describe Objects according to specs, by using real possible future technology. Besides, JSON Schemas are quite expressive and allows to describe a lot of nuances. Unfortunately, they also very verbose and hard to read or reuse as basement for filling up with real values by hand, because they have different structure from the JSON, which will represent real data set.

JSON Schema-like

Similar to JSON Schema, but with prettier and more compact syntax.

Functions-based

Those validator usually using functions to set types of objects.

Example:

const schema = Joi.object().keys({
  username: Joi.string().alphanum().min(3).max(30).required(),
  password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/),
  access_token: [Joi.string(), Joi.number()],
  birthyear: Joi.number().integer().min(1900).max(2013),
  email: Joi.string().email()
})

or

const check = checkers.shape({
  name: checkers.shape({
    first: checkers.string,
    last: checkers.string
  }),
  age: checkers.number,
  isOld: checkers.bool,
  walk: checkers.func,
  childrenNames: checkers.arrayOf(checkers.string)
});

Inspired by React propTypes

Flow-related

  • flow-runtime (Based on Flow, but for runtime in form of imported functions)

    flow-runtime-error

  • runtime-types (Reads js file with pure Flow types and allows to validate Objects based on converted result)

Misc

Crazy

Use some API-based solutions?

ArmorDarks avatar Feb 19 '17 20:02 ArmorDarks