Logo
⚠️ Unsaved
[M]:

Creating and Using Schemas in Fast-json-stringify

Hey there! If you're looking to supercharge your JSON serialization in Node.js, fast-json-stringify is a fantastic option. The key to getting the most out of this library is understanding how to create effective schemas.

In this notebook, we'll dive deep into schema creation for fast-json-stringify - from basic types to complex nested structures, references, patterns, and more. You'll learn how to craft schemas that not only boost performance but also handle all your data serialization needs.

[1]:
// Install fast-json-stringify
!npm install fast-json-stringify
$ npm install fast-json-stringify

added 11 packages in 2s

33 packages are looking for funding
  run `npm fund` for details
[2]:
// Import the library
const fastJson = require('fast-json-stringify');

console.log("Fast-json-stringify loaded successfully!\n");
Fast-json-stringify loaded successfully!
[M]:

Basic Schema Types

Let's start with the fundamental schema types in fast-json-stringify. The library supports all the standard JSON Schema types.

[3]:
// String schema
const stringSchema = {
type: 'object',
properties: {
name: { type: 'string' },
description: { type: 'string' }
}
};

const stringStringify = fastJson(stringSchema);
const stringData = { name: 'Product', description: 'A great product' };

console.log("String schema result:\n");
console.log(stringStringify(stringData), "\n");
String schema result:
{"name":"Product","description":"A great product"} 
[4]:
// Number schema
const numberSchema = {
type: 'object',
properties: {
integer: { type: 'integer' },
float: { type: 'number' }
}
};

const numberStringify = fastJson(numberSchema);
const numberData = { integer: 42, float: 3.14159 };

console.log("Number schema result:\n");
console.log(numberStringify(numberData), "\n");
Number schema result:
{"integer":42,"float":3.14159} 
[5]:
// Boolean schema
const booleanSchema = {
type: 'object',
properties: {
isActive: { type: 'boolean' },
hasFeature: { type: 'boolean' }
}
};

const booleanStringify = fastJson(booleanSchema);
const booleanData = { isActive: true, hasFeature: false };

console.log("Boolean schema result:\n");
console.log(booleanStringify(booleanData), "\n");
Boolean schema result:
{"isActive":true,"hasFeature":false} 
[6]:
// Null schema
const nullSchema = {
type: 'object',
properties: {
value: { type: 'null' },
optionalValue: { type: ['string', 'null'] }
}
};

const nullStringify = fastJson(nullSchema);
const nullData = { value: null, optionalValue: null };
const nullData2 = { value: null, optionalValue: 'I have a value' };

console.log("Null schema results:\n");
console.log(nullStringify(nullData), "\n");
console.log(nullStringify(nullData2), "\n");
Null schema results:
{"value":null,"optionalValue":null} 
{"value":null,"optionalValue":"I have a value"} 
[M]:

Array Schemas

Arrays are common in JSON data. Let's see how to define schemas for different types of arrays.

[7]:
// Simple array of strings
const stringArraySchema = {
type: 'object',
properties: {
tags: {
type: 'array',
items: { type: 'string' }
}
}
};

const stringArrayStringify = fastJson(stringArraySchema);
const stringArrayData = { tags: ['javascript', 'nodejs', 'json'] };

console.log("String array schema result:\n");
console.log(stringArrayStringify(stringArrayData), "\n");
String array schema result:
{"tags":["javascript","nodejs","json"]} 
[8]:
// Array of objects
const objectArraySchema = {
type: 'object',
properties: {
users: {
type: 'array',
items: {
type: 'object',
properties: {
id: { type: 'integer' },
name: { type: 'string' },
email: { type: 'string' }
}
}
}
}
};

const objectArrayStringify = fastJson(objectArraySchema);
const objectArrayData = {
users: [
{ id: 1, name: 'Alice', email: 'alice@example.com' },
{ id: 2, name: 'Bob', email: 'bob@example.com' },
{ id: 3, name: 'Charlie', email: 'charlie@example.com' }
]
};

console.log("Object array schema result:\n");
console.log(objectArrayStringify(objectArrayData), "\n");
Object array schema result:
{"users":[{"id":1,"name":"Alice","email":"alice@example.com"},{"id":2,"name":"Bob","email":"bob@example.com"},{"id":3,"name":"Charlie","email":"charlie@example.com"}]} 
[9]:
// Mixed array (tuple)
const tupleSchema = {
type: 'object',
properties: {
coordinates: {
type: 'array',
items: [
{ type: 'number' }, // x coordinate
{ type: 'number' }, // y coordinate
{ type: 'string' } // label
]
}
}
};

const tupleStringify = fastJson(tupleSchema);
const tupleData = { coordinates: [10.5, 20.3, 'Point A'] };

console.log("Tuple schema result:\n");
console.log(tupleStringify(tupleData), "\n");
Tuple schema result:
{"coordinates":[10.5,20.3,"Point A"]} 
[M]:

Nested Object Schemas

Real-world JSON often contains deeply nested objects. Let's see how to handle them.

[10]:
// Nested object schema
const nestedSchema = {
type: 'object',
properties: {
user: {
type: 'object',
properties: {
id: { type: 'integer' },
name: { type: 'string' },
contact: {
type: 'object',
properties: {
email: { type: 'string' },
phone: { type: 'string' },
address: {
type: 'object',
properties: {
street: { type: 'string' },
city: { type: 'string' },
zipCode: { type: 'string' }
}
}
}
}
}
}
}
};

const nestedStringify = fastJson(nestedSchema);
const nestedData = {
user: {
id: 42,
name: 'John Doe',
contact: {
email: 'john@example.com',
Nested object schema result:
{"user":{"id":42,"name":"John Doe","contact":{"email":"john@example.com","phone":"555-1234","address":{"street":"123 Main St","city":"Anytown","zipCode":"12345"}}}} 
[M]:

Schema References and Definitions

For complex schemas, you can use references to avoid repetition and make your schemas more maintainable.

[11]:
// Schema with references
const refSchema = {
type: 'object',
definitions: {
address: {
type: 'object',
properties: {
street: { type: 'string' },
city: { type: 'string' },
state: { type: 'string' },
zipCode: { type: 'string' }
}
}
},
properties: {
name: { type: 'string' },
homeAddress: { $ref: '#/definitions/address' },
workAddress: { $ref: '#/definitions/address' }
}
};

const refStringify = fastJson(refSchema);
const refData = {
name: 'Jane Smith',
homeAddress: {
street: '456 Oak Ave',
city: 'Someville',
state: 'CA',
zipCode: '94321'
},
workAddress: {
street: '789 Corporate Blvd',
city: 'Businesstown',
state: 'CA',
zipCode: '94567'
}
Schema with references result:
{"name":"Jane Smith","homeAddress":{"street":"456 Oak Ave","city":"Someville","state":"CA","zipCode":"94321"},"workAddress":{"street":"789 Corporate Blvd","city":"Businesstown","state":"CA","zipCode":"94567"}} 
[M]:

Pattern Properties

Sometimes you need to handle objects with dynamic keys. Pattern properties let you define schemas for keys that match a pattern.

[12]:
// Pattern properties schema
const patternSchema = {
type: 'object',
properties: {
name: { type: 'string' }
},
patternProperties: {
'^metric_': { type: 'number' },
'^flag_': { type: 'boolean' }
}
};

const patternStringify = fastJson(patternSchema);
const patternData = {
name: 'System Stats',
metric_cpu: 45.2,
metric_memory: 72.8,
metric_disk: 30.5,
flag_active: true,
flag_warning: false
};

console.log("Pattern properties schema result:\n");
console.log(patternStringify(patternData), "\n");
Pattern properties schema result:
{"name":"System Stats","metric_cpu":45.2,"metric_memory":72.8,"metric_disk":30.5,"flag_active":true,"flag_warning":false} 
[M]:

Additional Properties

You can control how unknown properties are handled using the additionalProperties keyword.

[13]:
// Schema with additional properties allowed
const additionalAllowedSchema = {
type: 'object',
properties: {
id: { type: 'integer' },
name: { type: 'string' }
},
additionalProperties: true
};

const additionalAllowedStringify = fastJson(additionalAllowedSchema);
const additionalAllowedData = {
id: 123,
name: 'Product',
price: 99.99, // Additional property
inStock: true // Additional property
};

console.log("Schema with additional properties allowed:\n");
console.log(additionalAllowedStringify(additionalAllowedData), "\n");
Schema with additional properties allowed:
{"id":123,"name":"Product","price":99.99,"inStock":true} 
[14]:
// Schema with additional properties disallowed
const additionalDisallowedSchema = {
type: 'object',
properties: {
id: { type: 'integer' },
name: { type: 'string' }
},
additionalProperties: false
};

const additionalDisallowedStringify = fastJson(additionalDisallowedSchema);
const additionalDisallowedData = {
id: 123,
name: 'Product',
price: 99.99, // Will be ignored
inStock: true // Will be ignored
};

console.log("Schema with additional properties disallowed:\n");
console.log(additionalDisallowedStringify(additionalDisallowedData), "\n");
Schema with additional properties disallowed:
{"id":123,"name":"Product"} 
[15]:
// Schema with typed additional properties
const additionalTypedSchema = {
type: 'object',
properties: {
id: { type: 'integer' },
name: { type: 'string' }
},
additionalProperties: { type: 'string' } // All additional properties must be strings
};

const additionalTypedStringify = fastJson(additionalTypedSchema);
const additionalTypedData = {
id: 123,
name: 'Product',
category: 'Electronics', // String additional property
description: 'A great product' // String additional property
};

console.log("Schema with typed additional properties:\n");
console.log(additionalTypedStringify(additionalTypedData), "\n");
Schema with typed additional properties:
{"id":123,"name":"Product","category":"Electronics","description":"A great product"} 
[M]:

Required Properties

While fast-json-stringify doesn't validate data, the required keyword can help document which properties are expected.

[16]:
// Schema with required properties
const requiredSchema = {
type: 'object',
required: ['id', 'name'],
properties: {
id: { type: 'integer' },
name: { type: 'string' },
description: { type: 'string' }
}
};

const requiredStringify = fastJson(requiredSchema);
const requiredData = {
id: 456,
name: 'Required Product',
description: 'This product has required fields'
};

console.log("Schema with required properties:\n");
console.log(requiredStringify(requiredData), "\n");

// Note: fast-json-stringify doesn't validate, so missing required properties will just be omitted
const missingRequiredData = {
id: 789,
description: 'Missing the name property'
};

console.log("Data missing required property:\n");
console.log(requiredStringify(missingRequiredData), "\n");
Error during execution: "name" is required!Schema with required properties: {"id":456,"name":"Required Product","description":"This product has required fields"} Data missing required property:
[M]:

Real-world Example: API Response Schema

Let's put it all together with a real-world example of an API response schema.

[17]:
// API response schema
const apiResponseSchema = {
type: 'object',
definitions: {
error: {
type: 'object',
properties: {
code: { type: 'string' },
message: { type: 'string' }
}
},
user: {
type: 'object',
properties: {
id: { type: 'integer' },
username: { type: 'string' },
email: { type: 'string' },
role: { type: 'string' }
}
}
},
properties: {
success: { type: 'boolean' },
timestamp: { type: 'string' },
data: {
type: 'object',
properties: {
users: {
type: 'array',
items: { $ref: '#/definitions/user' }
},
pagination: {
type: 'object',
properties: {
page: { type: 'integer' },
pageSize: { type: 'integer' },
[18]:
// Successful API response
const successResponse = {
success: true,
timestamp: new Date().toISOString(),
data: {
users: [
{ id: 1, username: 'user1', email: 'user1@example.com', role: 'admin' },
{ id: 2, username: 'user2', email: 'user2@example.com', role: 'user' },
{ id: 3, username: 'user3', email: 'user3@example.com', role: 'user' }
],
pagination: {
page: 1,
pageSize: 10,
totalPages: 3,
totalItems: 25
}
},
error: null
};

console.log("Successful API response:\n");
console.log(apiResponseStringify(successResponse), "\n");
Successful API response:
{"success":true,"timestamp":"2025-03-13T19:02:07.135Z","data":{"users":[{"id":1,"username":"user1","email":"user1@example.com","role":"admin"},{"id":2,"username":"user2","email":"user2@example.com","role":"user"},{"id":3,"username":"user3","email":"user3@example.com","role":"user"}],"pagination":{"page":1,"pageSize":10,"totalPages":3,"totalItems":25}},"error":null} 
[19]:
// Error API response
const errorResponse = {
success: false,
timestamp: new Date().toISOString(),
data: {
users: [],
pagination: {
page: 0,
pageSize: 0,
totalPages: 0,
totalItems: 0
}
},
error: {
code: 'AUTH_ERROR',
message: 'Authentication failed. Please log in again.'
}
};

console.log("Error API response:\n");
console.log(apiResponseStringify(errorResponse), "\n");
Error API response:
{"success":false,"timestamp":"2025-03-13T19:02:07.822Z","data":{"users":[],"pagination":{"page":0,"pageSize":0,"totalPages":0,"totalItems":0}},"error":{"code":"AUTH_ERROR","message":"Authentication failed. Please log in again."}} 
[M]:

Performance Considerations

When creating schemas for fast-json-stringify, keep these performance tips in mind:

  1. Be specific with types: The more specific your schema, the better the performance optimization.
  2. Use references for repeated structures: This reduces schema size and improves maintainability.
  3. Consider additionalProperties: Setting additionalProperties: false can improve performance by ignoring unexpected fields.
  4. Avoid complex patterns: While pattern properties are powerful, complex regex patterns can slow things down.

Wrapping Up

Creating effective schemas is the key to getting the most out of fast-json-stringify. With the techniques we've covered, you can build schemas for everything from simple objects to complex nested structures with dynamic properties.

Remember that fast-json-stringify is focused on serialization performance, not validation. If you need validation too, consider using a library like Ajv alongside fast-json-stringify.

Sign in to save your work and access it from anywhere