> ## Documentation Index
> Fetch the complete documentation index at: https://villagesql.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# vsql_http extension for MySQL

> The vsql_http extension makes GET, POST, PUT, PATCH, and DELETE requests from inside a MySQL query, returning each response as JSON.

`vsql_http` makes HTTP requests from inside a query. A trigger can call a
webhook, a `SELECT` can enrich rows from an API, and a scheduled event can push
a summary somewhere, with no application layer in between. It is built on
libcurl and returns every response as JSON.

| | |
| - | - |
| **Maintainer** | VillageSQL |
| **Source and full documentation** | [villagesql/vsql-http](https://github.com/villagesql/vsql-http) |
| **License** | GPL-2.0 |

## Install

`vsql_http.veb` is already in the server's `lib/veb/` directory if you installed
VillageSQL with the install script, the Docker image, or a release tarball.
Install it into the server with one statement:

```sql theme={null}
INSTALL EXTENSION vsql_http;
```

Confirm it is there:

```sql theme={null}
SELECT EXTENSION_NAME
FROM INFORMATION_SCHEMA.EXTENSIONS
WHERE EXTENSION_NAME = 'vsql_http';
```

```
+----------------+
| EXTENSION_NAME |
+----------------+
| vsql_http      |
+----------------+
```

To build it yourself, follow the build instructions in the
[repository](https://github.com/villagesql/vsql-http).

## What it adds

Every request function returns one JSON object with four fields: `status`,
`content_type`, `headers`, and `content`. A request that cannot complete, such as
a refused connection or a timeout, returns `NULL` and raises a warning carrying
curl's error message:

```
Warning 3200 VDF error in function 'http_get': Couldn't connect to server
```

| Function | Returns | What it does |
| - | - | - |
| `http_get(url)` | text | A GET request, with the response as JSON |
| `http_post(url, content_type, body)` | text | A POST request with a body |
| `http_put(url, content_type, body)` | text | A PUT request with a body |
| `http_patch(url, content_type, body)` | text | A PATCH request with a body |
| `http_delete(url)` | text | A DELETE request |
| `http_request(method, url, headers, body, content_type, options)` | text | Any method, with your own headers and options as JSON |
| `url_encode(s)` | text | Percent-encodes a string for use in a URL |
| `url_decode(s)` | text | Reverses `url_encode` |

`http_request`'s `method` argument matches GET, HEAD, POST, PUT, DELETE, CONNECT,
OPTIONS, TRACE and PATCH case-insensitively and sends them in uppercase; any
other method is sent exactly as given.

## Example

Fetch a URL and read two fields out of the response:

```sql theme={null}
SET @r = CONVERT(http_get('https://villagesql.com/robots.txt') USING utf8mb4);

SELECT JSON_EXTRACT(@r, '$.status') AS status,
       JSON_UNQUOTE(JSON_EXTRACT(@r, '$.content_type')) AS content_type;
```

```
+--------+---------------------------+
| status | content_type              |
+--------+---------------------------+
| 200    | text/plain; charset=utf-8 |
+--------+---------------------------+
```

Build a query string safely:

```sql theme={null}
SELECT url_encode('hello world & more') AS encoded;
```

```
+----------------------------+
| encoded                    |
+----------------------------+
| hello%20world%20%26%20more |
+----------------------------+
```

> [!NOTE]
>
> On VillageSQL 0.0.6 and earlier the response carries the binary character set.
> A JSON function or a `JSON` column rejects it, so the example above without
> its `CONVERT` fails there with
> `ERROR 3144 (22032): Cannot create a JSON value from a string with CHARACTER
>     SET 'binary'.` Inside `JSON_OBJECT()` or `JSON_ARRAY()` it is accepted but
> base64-encoded instead. Keep the `CONVERT(... USING utf8mb4)` on those
> versions; it is unnecessary on 0.0.7 and later, and harmless there.

> [!WARNING]
>
> A request blocks the statement that made it, for up to 30 seconds by default.
> Only `http_request` can shorten that, through its options argument, as in
> `'{"timeout": 5}'`. One call per row turns a table scan into a series of
> network round trips, so keep these calls off large result sets.

## See also

* [Making HTTP requests from MySQL](https://villagesql.com/docs/guides/http-requests-in-mysql.md) — timeouts, error handling, and reading the response
* [Sending webhooks from MySQL](https://villagesql.com/docs/guides/http-webhooks.md) — firing a request from a trigger
* [Enriching rows from a REST API](https://villagesql.com/docs/guides/rest-api-enrichment.md) — joining a query to an external service
* [Install extensions](https://villagesql.com/docs/mysql-8.4/0.0.6/install.md) — how `INSTALL EXTENSION` works and where the server looks for a bundle
* [Available extensions](https://villagesql.com/docs/mysql-8.4/0.0.6/extensions.md) — the full catalog
* [villagesql/vsql-http](https://github.com/villagesql/vsql-http) — source, build instructions, and the known limitations


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.