Skip to main content

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples in this guide work on VillageSQL. Install Now →
Some data doesn’t live in your database — exchange rates, shipping status, geolocation lookups, third-party product details. The standard approach is to fetch it in application code and either cache it in a table or stitch it together with query results at the application layer. VillageSQL’s vsql_http extension lets you pull that data directly from a query or store it in a column with a single UPDATE.

Setup

Pattern 1: Store Enrichment in a Column

The most common use: backfill a column with data fetched from an external API. Run an UPDATE that calls the API per row, store the result, then query the stored column. This example fetches a shipping status for each order:
Run this in a loop from your application until no rows with shipping_status IS NULL remain. Process in batches to stay within API rate limits. After backfilling, queries hit the stored column — no API call per query:

Pattern 2: Live Lookup in a Query

For data that changes too fast to cache — exchange rates, real-time pricing — you can call the API inline in the SELECT. Every row in the result triggers a request, so keep the result set small.
Fetch the shared value once into a variable, then use the variable in the query — don’t call http_get() inside the SELECT expression unless each row genuinely needs a different API call.

Pattern 3: Conditional Enrichment

Only fetch for rows that actually need it using WHERE to filter before calling the API:
Note url_encode() wrapping the address — always encode user data before embedding it in a URL.

Handling API Errors

All vsql_http functions return NULL on connection failure. Check the status code before using the content:
For bulk UPDATE loops, rows that get a NULL or non-200 response keep their column value NULL, so you can re-run the UPDATE to retry failed rows.

Performance Considerations

Each HTTP call is synchronous and blocks the query. A batch of 50 rows each hitting a 200ms API takes 10 seconds minimum. Set max_execution_time accordingly:
Prefer storing results over querying live — once a value is in a column, subsequent queries don’t touch the network.

Troubleshooting

Next Steps

See also