JSON tools
Email in JSON Schema: Validate Type, Presence and Format
Define an email field in JSON Schema, enable format checks explicitly, and test missing, null and malformed values without claiming delivery.
State whether the address is required
An email field in JSON Schema usually needs three separate decisions: whether the property must exist, whether its value must be a string, and whether the validator should check an email address format. Adding an email format to a property does not by itself require that property to appear in the object.
Start with the form or API contract. For a fictional notification request, suppose exactly one property named email is required and must contain a nonempty address string. The following draft-07 example expresses that small contract without including unrelated account fields.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"email": {"type": "string", "minLength": 1, "format": "email"}
},
"required": ["email"],
"additionalProperties": false
}
The example {"email":"reader@example.com"} is a synthetic passing fixture. An empty object must fail the required-property rule. A null or numeric email value must fail the type rule. An empty string must fail the nonempty requirement, regardless of how the selected format checker handles it.
Confirm that format actually runs
Do not infer email checking from a successful schema compilation. Format behavior depends on the schema dialect, validator and configuration. The JSON Schema string reference distinguishes format annotations from validation behavior, so the application's test must include a malformed address.
For an Ajv 8 example, the official format documentation describes the separate ajv-formats package. Register the supported formats before compiling the schema. Keep the dependency versions in the project lockfile and rerun the same fixtures when changing validator settings.
const Ajv = require("ajv");
const addFormats = require("ajv-formats");
const ajv = new Ajv({allErrors: true, strict: true});
addFormats(ajv);
const validate = ajv.compile(schema);
const accepted = validate({email: "reader@example.com"});
const rejected = validate({email: "not-an-address"});
Here schema refers to the object shown above. Expected results are accepted equal to true and rejected equal to false. Copy or process the validator's errors immediately after a failed call if you need them; a later validation call can replace the diagnostic state.
Build a useful fixture matrix
Include a valid ordinary address, an address with a plus tag, the missing property, null, a number, an empty string and text with no at sign. Also include an unexpected extra property so the test proves that additionalProperties is enforced. Each rejection should identify its actual cause rather than report every problem as an invalid address.
Decide separately whether an optional email may be omitted. If it may, remove email from required while keeping the property definition. If explicit null is also allowed, describe that as a separate contract change. Do not make those changes simply to silence a failing fixture; the server and the interface must agree about their meaning.
Leading or trailing whitespace needs an intentional normalization policy. If the application trims it, do that before validation in a documented step and test both the raw input and submitted value. Avoid silently lowercasing the entire address as a supposed universal correction.
Separate syntax from ownership and delivery
A passing format check does not prove that the mailbox exists, accepts mail or belongs to the person using your application. Those questions require the application's delivery and confirmation workflow. Keep any verification token, expiry and account state on the server under the project's normal controls.
Internationalized addresses also need a deliberate policy. Check whether the selected validator and delivery service support the address form you intend to accept. Do not promise universal mailbox support based on one regular expression or a single ASCII fixture.
Review inferred schemas before using them
The local JSON Schema Generator From JSON can infer an initial shape from a sample object. A sample string alone cannot establish that it is an email address, that ownership was verified or that the field is mandatory in every request. Add the intended rules yourself and execute the passing and failing fixtures in the selected validator.
Show users a clear field message for an address problem and a different message for a delivery failure. Keeping those stages separate makes both debugging and the user experience more accurate.


