Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
Windows Tipps & SecurityWindows-Update beschädigt wichtige Datenrettungsfunktion(22.09.2026 um 09:04 Uhr)
Sichere ProgrammierungBuilding an Accessible Ecommerce Product Page with WCAG 2.2(22.09.2026 um 03:39 Uhr)
Sichere ProgrammierungGet Your Website Protected in 10 Minutes with SafeLine WAF(22.09.2026 um 08:42 Uhr)
Sichere ProgrammierungIntroduction to SPRINGBOOT(22.09.2026 um 08:42 Uhr)
Windows Tipps & SecurityWindows-Update beschädigt wichtige Datenrettungsfunktion(22.09.2026 um 09:04 Uhr)
Sichere ProgrammierungBuilding an Accessible Ecommerce Product Page with WCAG 2.2(22.09.2026 um 03:39 Uhr)
Sichere ProgrammierungGet Your Website Protected in 10 Minutes with SafeLine WAF(22.09.2026 um 08:42 Uhr)
Sichere ProgrammierungIntroduction to SPRINGBOOT(22.09.2026 um 08:42 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Building Modern Backends with Kaapi: Request validation Part 2

Kaapi: A flexible, extensible backend framework for modern APIs with messaging, documentation, and type safety built right in. This series is written for backend developers who love TypeScript and can appreciate Hapi’s design p…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

Kaapi: A flexible, extensible backend framework for modern APIs with messaging, documentation, and type safety built right in.


This series is written for backend developers who love TypeScript and can appreciate Hapi’s design philosophy.










Validation… again?



Maybe you followed along with the previous article on request validation using Joi, ArkType, Valibot, or Zod.



You’ve got a shiny Kaapi app, routes are clean, validation is solid. Everything felt neat and reassuring.



You probably started with something like this:




import { z } from 'zod';

app
.base()
.zod({
params: z.object({
name: z.string().min(3).max(10)
})
})
.route({
method: 'GET',
path: '/hello/{name}',
handler: function (request, h) {
return `Hello ${request.params.name}!`;
}
});






And honestly?

That works perfectly fine.



Until the day your app stops being small.



At some point, routes start multiplying. You stop defining them inline. They live in their own files, grouped by feature. And suddenly, that nice little chain you had doesn’t quite fit anymore.



So the question becomes:




How do you keep validation close to your routes… when routes are no longer close to your app?




That’s what we’re solving here.







The new setup (you’ve probably done this already)



You want two things:




  • routes defined independently

  • a single place where they’re registered with app.route(...)



And you still want:




  • validation

  • type safety

  • freedom to choose your favorite validator



Let’s walk through it, one validator at a time.







Joi: the familiar path



If you’re using Joi, nothing changes. That’s intentional.



Install it:




  • joi



Then define a route the same way you would with Hapi:




import { Kaapi, KaapiServerRoute } from '@kaapi/kaapi';
import Joi from 'joi';

const app = new Kaapi({ /* ... */ });

const route: KaapiServerRoute<{ Params: { name: string } }> = {
method: 'GET',
path: '/hello/{name}',
options: {
validate: {
params: Joi.object({
name: Joi.string().min(3).max(10).required()
}),
},
},
handler: function (request, h) {
return `Hello ${request.params.name}!`;
}
};






No magic. No surprises.

If you’ve used Hapi before, this should feel like coming home.







Zod: validation that talks to TypeScript



Now let’s say you want strong type inference, without juggling generics.



Install:




  • zod

  • @kaapi/validator-zod



First, extend Kaapi:




import { Kaapi } from '@kaapi/kaapi';
import { validatorZod } from '@kaapi/validator-zod';

const app = new Kaapi({ /* ... */ });

const start = async () => {
await app.extend(validatorZod);
};

start();






Now define your route:




import { withSchema } from '@kaapi/validator-zod';
import { z } from 'zod';

const route = withSchema({
params: z.object({
name: z.string().min(3).max(10)
})
}).route({
method: 'GET',
path: '/hello/{name}',
handler: function (request, h) {
return `Hello ${request.params.name}!`;
}
});






No generics.

Your types come straight from the schema.



You write validation once and TypeScript follows along.







Valibot: same idea, different flavor



Valibot plays in the same league as Zod, with a slightly different syntax.



Install:




  • valibot

  • @kaapi/validator-valibot



Extend Kaapi:




import { Kaapi } from '@kaapi/kaapi';
import { validatorValibot } from '@kaapi/validator-valibot';

const app = new Kaapi({ /* ... */ });

const start = async () => {
await app.extend(validatorValibot);
};

start();






Then define the route:




import { withSchema } from '@kaapi/validator-valibot';
import * as v from 'valibot';

const route = withSchema({
params: v.object({
name: v.pipe(v.string(), v.minLength(3), v.maxLength(10))
})
}).route({
method: 'GET',
path: '/hello/{name}',
handler: function (request, h) {
return `Hello ${request.params.name}!`;
}
});












ArkType: schemas you can read



Install:




  • arktype

  • @kaapi/validator-arktype



Extend Kaapi:




import { Kaapi } from '@kaapi/kaapi';
import { validatorArk } from '@kaapi/validator-arktype';

const app = new Kaapi({ /* ... */ });

const start = async () => {
await app.extend(validatorArk);
};

start();






Now the route:




import { withSchema } from '@kaapi/validator-arktype';
import { type } from 'arktype';

const route = withSchema({
params: type({
name: '3 <= string <= 10'
})
}).route({
method: 'GET',
path: '/hello/{name}',
handler: function (request, h) {
return `Hello ${request.params.name}!`;
}
});












What actually matters here



Regardless of the validator:




  • Routes are defined independently

  • Each route picks the validator it wants

  • Registration stays dead simple:




app.route(route);






Joi works out of the box.

Zod, Valibot, and ArkType plug in via withSchema.



Same app. Same API. Different tools.







So… which validator should you use?



Quick recap:





  • Minimal code? → Joi or ArkType


  • Strong type inference without generics? → Zod or Valibot


  • Human-readable schemas? → ArkType


  • Great auto-docs? → Zod, Valibot, or Joi



Kaapi doesn’t force a choice.



It gives you the whole toolbox. Pick the screwdriver you like using.







Source code



Want the full example?



👉 github.com/shygyver/kaapi-monorepo-playground

The example lives under validation-app.

Check the README for run instructions.



More Kaapi articles are coming.

This one was just about keeping validation where it belongs.





📦 Get started now




npm install @kaapi/kaapi






🔗 Learn more: https://github.com/demingongo/kaapi/wiki

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Building Modern Backends with Kaapi: Request validation Part 2

Thematisch verwandte Begriffe: Building, Modern, Backends, with · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-55210 | Joplin is an open source note-taking and to-do application that organise…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick