Skip to content
netweft

Why the SEO data provider sits behind a port

Engineering 2 min read

netweft's SEO data provider is an interface with two implementations: DataForSEO for real data, and a mock serving deterministic fixtures with no credentials. Nothing above the port knows which answered, so the product runs offline, every test is deterministic, and credit accounting is identical on both paths.

There is exactly one module in netweft that knows DataForSEO exists. Everything else — the routes, the worker, the credit accounting, the dashboard — talks to an interface with a handful of methods on it.

That is not architectural decoration. It buys four specific things.

The product runs with no vendor account

The mock implementation serves deterministic fixtures and needs no credentials. bun run dev produces a working netweft: projects, keyword research, rank checks, audits, the dashboard, the assistant. Nobody needs a DataForSEO key to run the thing, review a change, or reproduce a bug.

A product that requires a paid third-party account to start is a product with a contributor ceiling, and more immediately, one where every developer’s afternoon costs money.

Every test is deterministic

Fixtures do not rate limit, do not return a different SERP on Tuesday, and do not go down. A test suite that talks to a real SERP provider is a test suite that fails for reasons unrelated to the change under test, and the usual response — retries, tolerances, skipped assertions — erodes the suite until it stops catching anything.

The credit path is the same on both sides

This is the subtle one, and the reason the port sits where it does rather than one layer lower. Reservation and settlement happen above the port. A mock call reserves credits at the rate card price and settles against a fixture’s reported cost exactly as a real call reserves and settles against the vendor’s.

So the accounting is exercised on every run in development, not only in production against real money. The path that decides whether a workspace is refused is the path everybody runs all day.

Switching providers is a module, not a migration

netweft is not planning to leave DataForSEO. But a provider that changes its pricing, its coverage or its terms is a thing that happens to products, and the version of that event where one module is rewritten is survivable in a way that the version where the vendor’s response shape is spread through forty route handlers is not.

The same reasoning applies one shelf down: the cache and the rate limiter fail open. Without them every lookup misses and every request is allowed, which is the intended degraded behaviour rather than a failure mode. A dependency that can be absent is a dependency that cannot take the product down.

Every claim in these guides is something the product does.

Start a trial and check the ones that matter against a domain you already know.

There is no free tier. Three plans from $50 a month, each opening with a free trial.