Server-Side Guide
Node.js, Express, backend applications, and API development
Express Middleware
Use typed errors for clean middleware and request handling.
import { Either, Left, Right } from 'kotlinify-ts/monads';
// Validate and process request with Either
function validateRequest(req) {
return req.body ? Right(req.body) : Left({ code: 400, message: 'No body' });
}
validateRequest(req)
.flatMap(body => authenticate(body))
.flatMap(user => authorize(user, action))
.flatMap(user => processRequest(user))
.fold(
error => res.status(error.code).json({ error: error.message }),
data => res.json(data)
);
// Auth token validation
const token = req.headers.authorization;
(token ? Right(token) : Left('No token'))
.flatMap(t => verifyToken(t))
.flatMap(user => checkPermissions(user, action))
.fold(
error => res.status(401).json({ error }),
user => next()
);Database Operations
Chain database queries with error recovery and transaction support.
import { tryCatch, also } from 'kotlinify-ts';
tryCatch(() => db.findUser(id))
.flatMap(user => tryCatch(() => db.findOrders(user.id)))
.map(orders => calculateTotal(orders))
.onSuccess(total => db.updateTotal(id, total))
.fold(
error => rollback(error),
total => commit(total)
);
also(db.transaction(), tx => {
tryCatch(() => tx.insert(user))
.flatMap(() => tryCatch(() => tx.insert(profile)))
.fold(
error => tx.rollback(),
() => tx.commit()
);
});API Request Handling
Build robust API endpoints with validation and error handling.
import { tryCatch } from 'kotlinify-ts';
app.post("/api/users", (req, res) => {
tryCatch(() => validateInput(req.body))
.flatMap(data => tryCatch(() => sanitize(data)))
.flatMap(data => tryCatch(() => checkDuplicates(data)))
.flatMap(data => tryCatch(() => hashPassword(data)))
.flatMap(data => tryCatch(() => saveToDatabase(data)))
.flatMap(user => tryCatch(() => sendWelcomeEmail(user)))
.map(user => formatUserResponse(user))
.fold(
error => res.status(400).json({ error }),
user => res.status(201).json(user)
);
});
tryCatch(() => getRequestData(req))
.flatMap(data => tryCatch(() => validateSchema(data)))
.flatMap(valid => tryCatch(() => processData(valid)))
.map(result => transformResult(result))
.fold(
error => res.status(400).json({ error }),
data => res.json(data)
);Background Jobs
Run background tasks with coroutines and structured concurrency.
import { launch, coroutineScope } from 'kotlinify-ts/coroutines';
const queue = createJobQueue();
queue.subscribe(job =>
launch(() => {
processJob(job);
})
.catch(error => {
logger.error("Job failed:", error);
queue.retry(job);
})
);
await coroutineScope((scope) => {
const jobs = [
scope.launch(() => sendEmails(batch)),
scope.launch(() => processImages(batch)),
scope.launch(() => generateReports(batch))
];
return Promise.all(jobs.map(j => j.join()))
.then(results => logResults(results))
.catch(error => notifyAdmin(error));
});Stream Processing
Process large datasets efficiently with sequences and flows.
import { asSequence } from 'kotlinify-ts/sequences';
asSequence(db.streamUsers())
.filter(user => user.isActive)
.map(user => enrichUserData(user))
.chunked(100)
.forEach(batch => processBatch(batch));
asSequence(getLogFiles())
.flatMap(file => readLines(file))
.filter(line => line.includes("ERROR"))
.map(line => parseError(line))
.groupBy(error => error.type)
.forEach(([type, errors]) => report(type, errors));Caching Strategies
Implement caching with scope functions and error recovery.
import { also, let } from 'kotlinify-ts';
import { fromNullable, Some } from 'kotlinify-ts';
const key = getCacheKey(req);
const cached = let(key, k => cache.get(k));
fromNullable(cached)
.orElse(() => {
const data = fetchData();
also(data, d => cache.set(key, d));
return Some(data);
})
.getOrThrow();
tryCatch(() => cache.get(key))
.recover(() => {
const data = fetchFromDb(key);
also(data, d => cache.set(key, d, ttl));
return data;
})
.fold(
error => res.status(500).json({ error }),
data => res.json(data)
);Rate Limiting
Implement rate limiting with windowed operations and flows.
import { windowed } from 'kotlinify-ts/collections';
import { fromNullable } from 'kotlinify-ts/monads';
const log = getRequestLog(userId);
const windows = windowed(log, 100, 1);
const recentWindows = windows.map(window => window.filter(isRecent));
const exceeded = recentWindows.find(window => window.length > limit);
fromNullable(exceeded)
.fold(
() => next(),
() => res.status(429).json({ error: "Rate limit exceeded" })
);
requestFlow
.throttle(100)
.filter(req => !isRateLimited(req))
.collect(req => processRequest(req));Parallel Processing
Process multiple operations in parallel with automatic error handling.
import { coroutineScope } from 'kotlinify-ts/coroutines';
await coroutineScope((scope) => {
const deferreds = getUserIds().map(id =>
scope.async(() => fetchUserData(id))
);
return Promise.all(deferreds.map(d => d.await()))
.then(users => users.filter(Boolean))
.then(users => saveToCache(users))
.catch(error => logger.error("Batch failed:", error));
});
await coroutineScope((scope) => {
const tasks = [
scope.launch(() => updateSearchIndex()),
scope.launch(() => regenerateSitemap()),
scope.launch(() => clearCache()),
scope.launch(() => notifySubscribers())
];
return Promise.all(tasks.map(t => t.join()))
.then(() => logger.info("Deployment tasks completed"))
.catch(error => rollbackDeployment(error));
});