🔌 Dymo API in Zod
Take the Zod validation to the next level with built-in resilience system.
Overview
In order to facilitate the use of Dymo API in applications that integrate Zod, we have launched a new library specialized in projects that use Zod as a validation system. This integration includes the complete resilience system for reliable API operations.
Installation
npm install @dymo-api/zod
#or
pnpm install @dymo-api/zod
#or
yarn add @dymo-api/zod
Plugin Features
Password (Coming Soon)
User-Agent Validation (Coming Soon)
Resilience System
All Zod SDK integrations come with the built-in resilience system that provides:
- 🔄 Automatic Retries: Configurable retry attempts with exponential backoff
- 🚦 Rate Limiting: Intelligent tracking and management of API rate limits
- 🛡️ Fallback Data: Automatic generation of safe fallback responses when API is unavailable
- ⚡ Smart Error Handling: Differentiates between retry-worthy and non-retry-worthy errors
Basic Configuration
import { z } from "zod";
import DymoAPIZod from "@dymo-api/zod";
// Basic setup with resilience
const dymo = new DymoAPIZod({
apiKey: "PRIVATE_TOKEN_HERE",
resilience: {
fallbackEnabled: true, // Enable fallback data generation
retryAttempts: 2, // Number of additional retry attempts
retryDelay: 1000 // Base delay in milliseconds
}
});
// Create schema with automatic validation and resilience
const emailSchema = dymo.emailSchema();
const phoneSchema = dymo.phoneSchema();
const ipSchema = dymo.ipSchema();
Production vs Development
const productionClient = new DymoAPIZod({
apiKey: "PRIVATE_TOKEN_HERE",
resilience: {
fallbackEnabled: true, // Keep users working during outages
retryAttempts: 2, // 1 normal + 2 retries = 3 total attempts
retryDelay: 500 // Faster retries for better UX
}
});
Benefits:
- ✅ User experience maintained during API issues
- ✅ Balanced retry speed and reliability
- ✅ Automatic fallback to safe responses
Usage Examples
Email Validation with Resilience
import { z } from "zod";
import DymoAPIZod from "@dymo-api/zod";
const dymo = new DymoAPIZod({
apiKey: "PRIVATE_TOKEN_HERE",
resilience: {
fallbackEnabled: true,
retryAttempts: 2,
retryDelay: 1000
}
});
// Create email schema with automatic resilience
const emailSchema = dymo.emailSchema();
// Use in validation pipeline
const userSchema = z.object({
email: emailSchema,
name: z.string().min(2)
});
try {
const validatedUser = await userSchema.parseAsync({
email: "[email protected]",
name: "John Doe"
});
console.log("Valid user:", validatedUser.email);
} catch (error) {
console.log("Validation failed:", error.message);
}
Phone Validation with Resilience
// Phone validation with automatic retries
const phoneSchema = dymo.phoneSchema();
const registrationSchema = z.object({
phone: phoneSchema,
country: z.string().length(2)
});
try {
const validated = await registrationSchema.parseAsync({
phone: "+34617509462",
country: "ES"
});
console.log("Valid phone:", validated.phone);
} catch (error) {
console.log("Phone validation failed:", error.message);
}
IP Validation with Resilience
// IP validation with resilience
const ipSchema = dymo.ipSchema();
const accessLogSchema = z.object({
ip: ipSchema,
timestamp: z.date(),
userAgent: z.string()
});
try {
const validated = await accessLogSchema.parseAsync({
ip: "192.168.1.1",
timestamp: new Date(),
userAgent: "Mozilla/5.0..."
});
console.log("Valid IP:", validated.ip);
} catch (error) {
console.log("IP validation failed:", error.message);
}
Error Handling
Monitoring Resilience
Monitor console for resilience warnings to understand API behavior and troubleshooting issues.
Common log messages:
[WARN] [Dymo API] Client xxx is rate limited. Waiting 60 seconds...
[WARN] [Dymo API] Attempt 1 failed. Retrying in 1000ms...
[WARN] [Dymo API] Request failed after 3 attempts. Using fallback data.
Fallback Behavior
When fallbackEnabled: true and all retries fail:
// The system will return structured fallback data
try {
const result = await dymo.emailSchema().parseAsync("invalid@email");
// If API fails completely, you get fallback data:
// { email: "invalid@email", allow: false, reasons: ["INVALID"] }
console.log("Fallback result:", result);
} catch (error) {
// Only thrown if even fallback fails
console.error("Complete failure:", error);
}
Rate Limiting
The Zod SDK automatically handles rate limiting:
// Automatic rate limit handling
const validateMultiple = async (emails: string[]) => {
const results = await Promise.allSettled(
emails.map(email => dymo.isValidEmail(email))
);
// The SDK will automatically:
// 1. Track rate limits per client
// 2. Wait for `retry-after` headers
// 3. Not retry on 429 responses
return results.map(result =>
result.status === 'fulfilled' ? result.value : null
);
};
Best Practices
Schema Design
// Good: Combine Zod validation with Dymo resilience
const userRegistrationSchema = z.object({
email: dymo.emailSchema(), // Auto-resilience
phone: dymo.phoneSchema(), // Auto-resilience
ip: dymo.ipSchema(), // Auto-resilience
password: z.string().min(8).regex(/[A-Z]/), // Local validation
age: z.number().min(18).max(120) // Local validation
});
// All Dymo validations will have automatic retries and fallbacks
Benefits:
- ✅ Automatic retries for external validations
- ✅ Local validations are fast and don't hit API
- ✅ Clear separation of concerns
Performance Optimization
// Cache validated emails to reduce API calls
const emailCache = new Map<string, boolean>();
const cachedEmailValidation = z.string().transform(async (email) => {
if (emailCache.has(email)) {
return emailCache.get(email);
}
try {
const result = await dymo.isValidEmail(email);
emailCache.set(email, result.allow);
return result.allow;
} catch (error) {
// Cache failures for shorter time
emailCache.set(email, false);
setTimeout(() => emailCache.delete(email), 60000); // 1 minute
return false;
}
});
// Clear cache periodically
setInterval(() => emailCache.clear(), 300000); // 5 minutes
Benefits:
- ✅ Reduced API calls and costs
- ✅ Faster validation for repeat emails
- ✅ Automatic cache management
Migration from Previous Version
Updating from Manual Validation
// ❌ Manual validation without resilience
import { z } from "zod";
const oldEmailSchema = z.string().transform(async (email) => {
try {
const response = await fetch('/api/validate', {
method: 'POST',
body: JSON.stringify({ email })
});
return response.ok;
} catch (error) {
// ❌ Immediate failure on network issues
throw new Error(`Validation failed: ${error.message}`);
}
});
// ❌ No retries, no fallbacks, poor UX
Updating Configuration
If you were using previous resilience configuration:
// Previous behavior (3 total attempts max)
resilience: { retryAttempts: 2 } // Was: 1 normal + 2 retries = 3 total
// Same behavior now
resilience: { retryAttempts: 2 } // Still: 1 normal + 2 retries = 3 total
The resilience behavior remains the same - only the parameter documentation has been clarified. Your existing code will continue to work without changes.
Support
Common Issues
Getting Help
If you encounter issues with the Zod SDK resilience system:
- Check Console: Look for resilience warning messages
- Verify Configuration: Ensure resilience options are properly set
- Test Network: Check internet connectivity and API access
- Monitor Status: Check API Status Page
- Contact Support: Include logs and configuration details
When reporting issues, please include:
- Your resilience configuration
- Relevant console logs
- Validation schema being used
- Your API key (last 4 characters only)