DEV Community

Shawn P
Shawn P

Posted on

Building a Zero-Dependency Validation API on Cloudflare Workers

The idea

I wanted a small side project that could actually run itself once shipped — no cron jobs to babysit, no upstream API to go down at 3am and take my uptime with it. That constraint led somewhere specific: an API that validates common business data formats — phone numbers, IBAN, VAT/tax IDs, BIC/SWIFT codes, credit card numbers, postal codes — using nothing but offline checksum and format rules.

No third-party lookups. No API keys to rotate for an upstream provider. No rate limits inherited from someone else's infrastructure. If it's slow or wrong, it's my bug, not a dependency's outage.

The stack

  • Hono on Cloudflare Workers — TypeScript, no cold starts, runs on the free tier comfortably up to 100k requests/day
  • libphonenumber-js, ibantools, jsvat, card-validator — all well-maintained, all pure computation, zero network calls
  • Vitest for tests, run against real fixtures (not made-up test data — every "valid" example in my test suite is a real IBAN/VAT/card number pulled from each library's own published examples, verified against the actual library output before I trusted it)

The whole thing is about 300 lines of TypeScript across the router and six validator modules. Small enough to actually reason about, which mattered more to me than feature breadth.

app.post("/v1/iban/validate", async (c) => {
  const body = await c.req.json<{ iban?: string }>().catch(() => null);
  if (!body?.iban) {
    return c.json({ error: "missing required field: iban" }, 400);
  }
  return c.json(validateIban(body.iban));
});
Enter fullscreen mode Exit fullscreen mode

The part that actually surprised me

I expected the code to be the hard part. It wasn't. Deploying and listing it on RapidAPI was.

Two things stood out:

CORS mattered even though I "shouldn't" need it. Real production traffic through RapidAPI's gateway is server-to-server — CORS is a browser-enforced concept, so I assumed it was irrelevant. But RapidAPI's own in-dashboard request tester runs as a real browser fetch, and without an OPTIONS handler my backend was completely unreachable from their testing console — failing with a generic "blocked by origin server" error that told me nothing useful. Turned out to be a five-line fix with hono/cors, but it cost me an hour of assuming the bug was in my endpoint config instead.

The provider docs describe an older UI. RapidAPI's own documentation references a "Base URL" field that doesn't exist anymore in their current Studio — it's now a custom environment variable buried under Requests → Environments → Gateway. Their proxy auth secret (X-RapidAPI-Proxy-Secret) is generated by them, not something you configure — you copy their value into your backend, not the other way around, which is the opposite of how most API-key setups work. None of this is documented anywhere I could find; I only figured it out by testing requests and reading actual error responses.

Monetization, briefly

Listed with four tiers — free (500 req/mo), then $10/$30/$75 monthly tiers scaling request quota. RapidAPI takes a 25% cut and only pays out via PayPal, monthly, with roughly a two-month lag on when revenue actually lands in your account. Worth knowing going in — this is not a same-week payout model.

Try it

Free tier, no credit card to start: Business Data Validator on RapidAPI

Genuinely curious what other validators would be useful here — thinking about adding tax-ID formats beyond EU VAT next. Feedback welcome.

Top comments (0)