C.W.K.
Stream
Lesson 03 of 08 · published

Constraints — Length, Range, Pattern, Format

~12 min · json-schema, constraints, validation, regex

Level 0Plaintext
0 XP0/64 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

Beyond type: how to say 'string but only a UUID'

String constraints

  • minLength, maxLength — character-count bounds.
  • pattern — ECMAScript-style regex. The string must match.
  • format — predefined named formats (email, uri, date, date-time, uuid, ipv4, ipv6, hostname, regex).

Number constraints

  • minimum, maximum — inclusive bounds.
  • exclusiveMinimum, exclusiveMaximum — exclusive bounds.
  • multipleOf — must be a multiple of this value (use 1 to enforce integer-like in a number field).

'format' is advisory by default

Crucial gotcha: in Draft 2020-12, format keywords are annotations, not constraints, by default. "format": "email" doesn't reject invalid emails unless you configure your validator to enforce formats. ajv: { formats: addFormats } from ajv-formats. Python jsonschema: pass format_checker=Draft202012Validator.FORMAT_CHECKER.

The format trap: teams ship a schema with "format": "email", run it with default ajv, and assume malformed emails get rejected. They don't. Test the negative case — pass an obviously broken value and confirm the validator complains. If it doesn't, your formats are off.

Code

String constraints·json
{
  "type": "object",
  "properties": {
    "username": {
      "type": "string",
      "minLength": 3,
      "maxLength": 32,
      "pattern": "^[a-z0-9_-]+$"
    },
    "email":   { "type": "string", "format": "email" },
    "website": { "type": "string", "format": "uri" },
    "id":      { "type": "string", "format": "uuid" }
  }
}
Number constraints·json
{
  "type": "object",
  "properties": {
    "age":      { "type": "integer", "minimum": 0, "maximum": 150 },
    "latitude": { "type": "number", "minimum": -90, "maximum": 90 },
    "step":     { "type": "number", "multipleOf": 0.5 },
    "price":    { "type": "number", "exclusiveMinimum": 0 }
  }
}
Enable format checking (ajv + ajv-formats)·javascript
import Ajv from 'ajv/dist/2020.js';
import addFormats from 'ajv-formats';

const ajv = new Ajv();
addFormats(ajv);  // 'email', 'uri', 'date-time', etc. now actually enforced

const validate = ajv.compile(schema);
const valid = validate(data);

External links

Exercise

Write a schema for a user signup payload: username (alphanumeric + underscore, 3-32 chars), email (format), age (integer 13-120), country (string, exactly 2 letters). Validate three samples — one valid, one with an out-of-range age, one with a malformed email. Confirm the email error only appears when format checking is enabled.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.