Prérequis
Pour suivre les exemples de cet article, vous aurez besoin de :
- disposer d'une instance du serveur ClickHouse en cours d'exécution
- avoir
curlinstallé. Sur Ubuntu ou Debian, exécutezsudo apt install curlou consultez cette documentation pour les instructions d'installation.
Vue d’ensemble
L’interface HTTP vous permet d’utiliser ClickHouse sur n’importe quelle plateforme, depuis n’importe quel langage de programmation, sous la forme d’une API REST. L’interface HTTP est plus limitée que l’interface native, mais elle offre une meilleure prise en charge des langages.
Par défaut, clickhouse-server écoute sur les ports suivants :
- le port 8123 pour HTTP
- le port 8443 pour HTTPS, si celui-ci est activé
Si vous effectuez une requête GET / sans aucun paramètre, un code de réponse 200 est renvoyé avec la chaîne "Ok." :
$ curl 'http://localhost:8123/'
Ok."Ok." est la valeur par défaut définie dans http_server_default_response et peut être modifiée si nécessaire.
Voir aussi : Mises en garde concernant les codes de réponse HTTP.
Interface utilisateur web
ClickHouse comprend une interface utilisateur web, accessible à l’adresse suivante :
http://localhost:8123/playL’interface web prend en charge l’affichage de la progression pendant l’exécution d’une requête, l’annulation de requête et le streaming des résultats. Elle dispose d’une fonctionnalité cachée pour afficher des graphiques et des graphes de pipelines de requête.
Après l’exécution réussie d’une requête, un bouton de téléchargement apparaît et vous permet de télécharger les résultats de la requête dans différents formats, notamment CSV, TSV, JSON, JSONLines, Parquet, Markdown, ou tout autre format personnalisé pris en charge par ClickHouse. La fonctionnalité de téléchargement utilise le cache de requêtes pour récupérer efficacement les résultats sans réexécuter la requête. Elle télécharge l’ensemble du jeu de résultats, même si l’interface n’a affiché qu’une seule page parmi de nombreuses autres.
L’interface web est conçue pour des professionnels comme vous.

Dans les scripts de vérification d’état, utilisez la requête GET /ping. Ce handler renvoie toujours "Ok." (avec un saut de ligne à la fin). Disponible à partir de la version 18.12.13. Voir aussi /replicas_status pour vérifier le retard de la réplique.
$ curl 'http://localhost:8123/ping'
Ok.
$ curl 'http://localhost:8123/replicas_status'
Ok.Exécuter des requêtes via HTTP/HTTPS
Pour exécuter des requêtes via HTTP/HTTPS, trois options s’offrent à vous :
- envoyer la requête en tant que paramètre d’URL 'query'
- utiliser la méthode POST.
- envoyer le début de la requête dans le paramètre 'query', et le reste via POST
En cas de succès, vous recevez le code de réponse 200 ainsi que le résultat dans le corps de la réponse. Si une erreur se produit, vous recevez le code de réponse 500 et un texte décrivant l’erreur dans le corps de la réponse.
Les requêtes utilisant GET sont en mode 'readonly'. Cela signifie que, pour les requêtes qui modifient des données, vous ne pouvez utiliser que la méthode POST. Vous pouvez envoyer la requête elle-même soit dans le corps de la requête POST, soit dans le paramètre d’URL. Examinons quelques exemples.
Dans l’exemple ci-dessous, curl est utilisé pour envoyer la requête SELECT 1. Notez l’utilisation de l’encodage URL pour l’espace : %20.
curl 'http://localhost:8123/?query=SELECT%201'1Dans cet exemple, wget est utilisé avec les paramètres -nv (non-verbose) et -O- pour afficher le résultat dans le terminal.
Dans ce cas, il n’est pas nécessaire d’utiliser l’encodage URL pour l’espace :
wget -nv -O- 'http://localhost:8123/?query=SELECT 1'1Dans cet exemple, nous redirigeons une requête HTTP brute vers netcat :
echo -ne 'GET /?query=SELECT%201 HTTP/1.0\r\n\r\n' | nc localhost 8123HTTP/1.0 200 OK
X-ClickHouse-Summary: {"read_rows":"1","read_bytes":"1","written_rows":"0","written_bytes":"0","total_rows_to_read":"1","result_rows":"0","result_bytes":"0","elapsed_ns":"4505959","memory_usage":"1111711"}
Date: Tue, 11 Nov 2025 18:16:01 GMT
Connection: Close
Content-Type: text/tab-separated-values; charset=UTF-8
Access-Control-Expose-Headers: X-ClickHouse-Query-Id,X-ClickHouse-Summary,X-ClickHouse-Server-Display-Name,X-ClickHouse-Format,X-ClickHouse-Timezone,X-ClickHouse-Exception-Code,X-ClickHouse-Exception-Tag
X-ClickHouse-Server-Display-Name: MacBook-Pro.local
X-ClickHouse-Query-Id: ec0d8ec6-efc4-4e1d-a14f-b748e01f5294
X-ClickHouse-Format: TabSeparated
X-ClickHouse-Timezone: Europe/London
X-ClickHouse-Exception-Tag: dngjzjnxkvlwkeua
1Comme vous pouvez le constater, la commande curl est assez peu pratique, car les espaces doivent être encodés dans l’URL.
Bien que wget encode tout de lui-même, nous ne recommandons pas de l’utiliser, car il ne fonctionne pas bien avec HTTP 1.1 lors de l’utilisation de keep-alive et de Transfer-Encoding: chunked.
$ echo 'SELECT 1' | curl 'http://localhost:8123/' --data-binary @-
1
$ echo 'SELECT 1' | curl 'http://localhost:8123/?query=' --data-binary @-
1
$ echo '1' | curl 'http://localhost:8123/?query=SELECT' --data-binary @-
1Si une partie de la requête est envoyée via le paramètre et l’autre dans le corps de la requête POST, un saut de ligne est inséré entre ces deux blocs de données. Par exemple, ceci ne fonctionnera pas :
$ echo 'ECT 1' | curl 'http://localhost:8123/?query=SEL' --data-binary @-
Code: 59, e.displayText() = DB::Exception: Syntax error: failed at position 0: SEL
ECT 1
, expected One of: SHOW TABLES, SHOW DATABASES, SELECT, INSERT, CREATE, ATTACH, RENAME, DROP, DETACH, USE, SET, OPTIMIZE., e.what() = DB::ExceptionPar défaut, les données sont renvoyées au format TabSeparated.
La clause FORMAT est utilisée dans la requête pour spécifier un autre format. Par exemple :
wget -nv -O- 'http://localhost:8123/?query=SELECT 1, 2, 3 FORMAT JSON'{
"meta":
[
{
"name": "1",
"type": "UInt8"
},
{
"name": "2",
"type": "UInt8"
},
{
"name": "3",
"type": "UInt8"
}
],
"data":
[
{
"1": 1,
"2": 2,
"3": 3
}
],
"rows": 1,
"statistics":
{
"elapsed": 0.000515,
"rows_read": 1,
"bytes_read": 1
}
}Vous pouvez utiliser le paramètre d’URL default_format pour spécifier un format par défaut autre que TabSeparated. L’en-tête X-ClickHouse-Format sélectionne explicitement le format de la réponse : il s’agit d’un alias du paramètre output_format, il surcharge donc également une clause FORMAT dans la requête. Il ne modifie jamais la façon dont le corps de la requête d’un INSERT est analysé — utilisez input_format ou format à cette fin.
$ echo 'SELECT 1 FORMAT Pretty' | curl 'http://localhost:8123/?' --data-binary @-
┏━━━┓
┃ 1 ┃
┡━━━┩
│ 1 │
└───┘Vous pouvez utiliser la méthode POST avec des requêtes paramétrées. Les paramètres sont indiqués entre accolades, avec le nom et le type du paramètre, comme {name:Type}. Les valeurs des paramètres sont transmises via param_name :
$ curl -X POST -F 'query=select {p1:UInt8} + {p2:UInt8}' -F "param_p1=3" -F "param_p2=4" 'http://localhost:8123/'
7Accéder aux tables via des chemins d’URL et construire des requêtes
Disponible dans ClickHouse 26.8 et versions ultérieures.
L’interface HTTP peut interpréter un chemin d’URL comme une base de données, une table, un format de sortie et une méthode de compression. Les paramètres d’URL peuvent ensuite déterminer le résultat, de sorte que les requêtes de lecture simples ne nécessitent pas de SQL. Ces fonctionnalités sont désactivées par défaut et doivent être activées explicitement.
Activer le routage par chemin
L’interprétation des chemins est contrôlée à deux niveaux :
- Activez le paramètre de configuration
http_allow_path_requestsau niveau du serveur, qui permet à l’interface HTTP d’acheminer les requêtes basées sur des chemins vers le gestionnaire de requêtes :
<clickhouse>
<http_allow_path_requests>1</http_allow_path_requests>
</clickhouse>- Activez les paramètres requis par utilisateur :
| Paramètre | Effet |
|---|---|
http_allow_table_as_file |
Interprète le dernier composant du chemin comme table, table.format ou table.format.compression. |
http_allow_database_as_path |
Interprète un composant initial du chemin /database/ comme la base de données courante. |
http_allow_filters_as_path |
Interprète les composants du chemin /name=value/ au format Hive comme des filtres WHERE. |
http_allow_filters_as_unrecognized_url_parameters |
Interprète les paramètres d’URL non reconnus comme des filtres WHERE. |
Accéder aux tables sous forme de fichiers
Lorsque http_allow_table_as_file est activé, une requête vers /table.format.compression est traitée comme SELECT * FROM table. Activez http_allow_database_as_path pour utiliser /database/table.format.compression.
# SELECT * FROM my_db.hits, formatted as CSV
curl 'http://localhost:8123/my_db/hits.csv'
# The same result, compressed with gzip
curl 'http://localhost:8123/my_db/hits.csv.gz' | gzip -dLes extensions de format et de compression sont reconnues sans distinction de casse. Ainsi, hits.csv et hits.CSV sont équivalents.
Un paramètre d’URL format ou output_format explicite surcharge le format indiqué dans le chemin. Ce n’est pas le cas de default_format : il indique uniquement le format à utiliser lorsqu’aucun autre élément n’en sélectionne un, car l’extension du chemin est plus spécifique. Un paramètre compression explicite doit correspondre à la compression indiquée dans le chemin ; des valeurs incompatibles entraînent une exception.
Construire une requête
Les paramètres suivants encapsulent la requête de base dans une table dérivée. Ils peuvent être combinés entre eux et avec une requête existante. Vous pouvez les fournir comme paramètres d’URL HTTP, dans une clause SETTINGS de la requête ou via un profil utilisateur.
| Paramètre | Effet |
|---|---|
select |
SELECT <expression_list> FROM (…) |
filter |
Ajoute WHERE <expression>. Plusieurs paramètres d’URL filter sont combinés avec AND. |
order |
Ajoute ORDER BY <expression_list>. |
sort |
Ajoute ORDER BY à partir d’une liste d’identifiants ou de positions de colonnes séparées par des virgules, chacun pouvant être précédé du préfixe facultatif + (croissant) ou - (décroissant), par exemple sort=a,-b. Ne peut pas être combiné avec order. |
limit et offset |
Ajoutent LIMIT <n> OFFSET <m>. Les deux acceptent des valeurs négatives pour sélectionner la fin et des valeurs fractionnaires représentant une proportion des lignes. |
page |
Définit offset = limit * (page - 1). Nécessite limit et ne peut pas être combiné avec offset. |
# Filter my_db.hits, sort by a descending, and return the first 10 rows
curl 'http://localhost:8123/my_db/hits?filter=a%3E0&sort=-a&limit=10'
# Return the second page of 100 rows
curl 'http://localhost:8123/my_db/hits?limit=100&page=2'Modifier une requête existante
Les paramètres de construction ne se limitent pas aux requêtes par chemin : ils modifient également une requête que vous écrivez vous-même. La requête devient une table dérivée ; les paramètres s'appliquent donc à son résultat au lieu d'y être fusionnés. Par exemple, ?query=SELECT a, b FROM hits&filter=a > 0&sort=-b&limit=10 est exécutée comme suit :
SELECT * FROM (SELECT a, b FROM hits) WHERE a > 0 ORDER BY b DESC LIMIT 10Cela est utile pour paginer, trier ou affiner le résultat d’une requête définie ailleurs — dans une requête enregistrée d’un dashboard, un predefined_query_handler ou un client qui permet uniquement d’ajouter des paramètres d’URL :
# Page through the result of an arbitrary query without editing the query text
curl 'http://localhost:8123/?query=SELECT+a,+b+FROM+hits+GROUP+BY+a,+b&limit=100&page=3'
# Keep only some of the resulting columns and rows
curl -G 'http://localhost:8123/' --data-urlencode 'query=SELECT * FROM hits' --data-urlencode 'select=a, b' --data-urlencode 'filter=b != 0'
# The last 5 rows of an aggregate (a negative `limit` selects from the tail)
curl 'http://localhost:8123/?query=SELECT+a,+count()+FROM+hits+GROUP+BY+a+ORDER+BY+a&limit=-5'Comme les paramètres enveloppent la requête au lieu de la réécrire, ils sont compatibles avec une clause FORMAT et un ORDER BY au sein de la requête, et ne modifient jamais les lignes écrites par un INSERT : un paramètre de construction placé sur une instruction INSERT ... SELECT façonne le résultat propre à cette instruction (vide), et non celui de son SELECT source. Pour façonner la source, placez le paramètre dans la clause SETTINGS du SELECT :
-- Inserts all 10 rows: `limit` applies to the INSERT statement, not to its SELECT
INSERT INTO t SETTINGS limit = 2 SELECT number FROM numbers(10);
-- Inserts 2 rows: `limit` applies to the SELECT itself
INSERT INTO t SELECT number FROM numbers(10) SETTINGS limit = 2;Surcharge des formats et de la compression
| Paramètre | Effet |
|---|---|
output_format |
Remplace le format de sortie. Il prévaut sur la clause FORMAT de la requête, l’extension du chemin, format et default_format. Il peut également être défini à l’aide de l’en-tête X-ClickHouse-Format. |
input_format |
Remplace le format d’entrée pour INSERT. Il prévaut sur la clause FORMAT de la requête et sur format. |
format |
Remplace le format dans les deux sens, sauf si un paramètre spécifique à une direction est fourni. |
default_format |
Définit le format de sortie lorsque la requête ne comporte aucune clause FORMAT, aucune extension de chemin ni aucune autre surcharge de format. |
compression |
Compresse le corps de la réponse, par exemple avec compression=gz. Ce paramètre est indépendant de l’en-tête HTTP Content-Encoding et du paramètre natif ClickHouse compress. |
Les paramètres de format fonctionnent également avec d’autres protocoles, notamment le client natif et clickhouse-local. input_format et output_format correspondent aux options --input-format et --output-format. Dans clickhouse-local, l’option --format correspond au paramètre bidirectionnel format, tandis que dans clickhouse-client, elle conserve sa signification historique limitée à la sortie et correspond à output_format.
compression est spécifique à la mise en forme des réponses HTTP et est traité avant l’exécution de la requête. Indiquez-le à l’aide d’un paramètre d’URL HTTP, d’une extension de chemin ou d’un profil utilisateur. Il est rejeté dans une clause SETTINGS de la requête.
Les réponses HTTP binaires et compressées incluent un en-tête Content-Disposition: attachment; filename=…. Le nom de fichier est dérivé du chemin d’URL ou prend la forme result.<format>.<compression> lorsque le chemin n’en fournit pas.
Utiliser une table de chemin dans une requête
Lorsque le chemin identifie une table et que vous fournissez également un paramètre query, cette table est accessible via implicit_table_at_top_level. Un SELECT sans clause FROM lit la table identifiée par le chemin :
# Read columns a and b from my_db.hits without a FROM clause
curl 'http://localhost:8123/my_db/hits.CSV?query=SELECT+a,+b'Si la requête contient déjà une clause FROM, le composant de chemin sert uniquement à fournir le nom du fichier téléchargé.
Requêtes INSERT via HTTP/HTTPS
La méthode POST est nécessaire pour transmettre des données dans les requêtes INSERT. Dans ce cas, vous pouvez écrire le début de la requête dans le paramètre d’URL et utiliser POST pour transmettre les données à insérer. Les données à insérer peuvent être, par exemple, un dump MySQL séparé par des tabulations. Ainsi, la requête INSERT remplace LOAD DATA LOCAL INFILE de MySQL.
Exemples
Pour créer une table :
$ echo 'CREATE TABLE t (a UInt8) ENGINE = Memory' | curl 'http://localhost:8123/' --data-binary @-Pour utiliser la requête INSERT habituelle pour insérer des données :
$ echo 'INSERT INTO t VALUES (1),(2),(3)' | curl 'http://localhost:8123/' --data-binary @-Pour envoyer les données séparément de la requête :
$ echo '(4),(5),(6)' | curl 'http://localhost:8123/?query=INSERT%20INTO%20t%20VALUES' --data-binary @-Tout format de données peut être spécifié. Par exemple, il est possible de spécifier le format 'Values', c’est-à-dire le même format que celui utilisé lors de l’écriture de INSERT INTO t VALUES :
$ echo '(7),(8),(9)' | curl 'http://localhost:8123/?query=INSERT%20INTO%20t%20FORMAT%20Values' --data-binary @-Pour insérer des données à partir d’un dump séparé par des tabulations, spécifiez le format correspondant :
$ echo -ne '10\n11\n12\n' | curl 'http://localhost:8123/?query=INSERT%20INTO%20t%20FORMAT%20TabSeparated' --data-binary @-Pour lire le contenu de la table :
$ curl 'http://localhost:8123/?query=SELECT%20a%20FROM%20t'
7
8
9
10
11
12
1
2
3
4
5
6Pour supprimer la table :
$ echo 'DROP TABLE t' | curl 'http://localhost:8123/' --data-binary @-Pour les requêtes réussies qui ne renvoient pas de tableau de données, le corps de la réponse est vide.
Compression
La compression peut être utilisée pour réduire le trafic réseau lors de la transmission d'un grand volume de données, ou pour créer des dumps déjà compressés.
Vous pouvez utiliser le format de compression interne de ClickHouse lors de la transmission de données. Les données compressées ont un format non standard, et vous avez besoin du programme clickhouse-compressor pour les manipuler. Il est installé par défaut avec le paquet clickhouse-client.
Pour améliorer l'efficacité de l'insertion de données, désactivez la vérification de la somme de contrôle côté serveur à l'aide du paramètre http_native_compression_disable_checksumming_on_decompress.
Si vous spécifiez compress=1 dans l'URL, le serveur compressera les données qu'il vous envoie. Si vous spécifiez decompress=1 dans l'URL, le serveur décompressera les données que vous envoyez dans la méthode POST.
Vous pouvez également choisir d'utiliser la compression HTTP. ClickHouse prend en charge les méthodes de compression suivantes :
gzipbrdeflatexzzstdlz4bz2snappy
Pour envoyer une requête POST compressée, ajoutez l'en-tête de requête Content-Encoding: compression_method.
Pour que ClickHouse compresse la réponse, ajoutez l'en-tête Accept-Encoding: compression_method à la requête.
Vous pouvez configurer le niveau de compression des données à l'aide du paramètre http_zlib_compression_level pour toutes les méthodes de compression.
Exemples
Pour envoyer des données compressées au serveur :
echo "SELECT 1" | gzip -c | \
curl -sS --data-binary @- -H 'Content-Encoding: gzip' 'http://localhost:8123/'Pour recevoir l’archive de données compressée depuis le serveur :
curl -vsS "http://localhost:8123/?enable_http_compression=1" \
-H 'Accept-Encoding: gzip' --output result.gz -d 'SELECT number FROM system.numbers LIMIT 3'
zcat result.gz
0
1
2Pour recevoir des données compressées du serveur, utilisez gunzip afin d’obtenir des données décompressées :
curl -sS "http://localhost:8123/?enable_http_compression=1" \
-H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 3' | gunzip -
0
1
2Base de données par défaut
Vous pouvez utiliser le paramètre d’URL database ou l’en-tête X-ClickHouse-Database pour indiquer la base de données par défaut.
echo 'SELECT number FROM numbers LIMIT 10' | curl 'http://localhost:8123/?database=system' --data-binary @-
0
1
2
3
4
5
6
7
8
9Par défaut, la base de données enregistrée dans les paramètres du serveur est utilisée comme base de données par défaut. Par défaut, il s’agit de la base de données nommée default. Vous pouvez également toujours préciser la base de données en la faisant précéder d’un point avant le nom de la table.
Authentification
Le nom d’utilisateur et le mot de passe peuvent être indiqués de l’une des trois manières suivantes :
- En utilisant l’authentification HTTP Basic.
Par exemple :
echo 'SELECT 1' | curl 'http://user:password@localhost:8123/' -d @-- Dans les paramètres d’URL
useretpassword
Par exemple :
echo 'SELECT 1' | curl 'http://localhost:8123/?user=user&password=password' -d @-- Utilisation des en-têtes 'X-ClickHouse-User' et 'X-ClickHouse-Key'
Par exemple :
echo 'SELECT 1' | curl -H 'X-ClickHouse-User: user' -H 'X-ClickHouse-Key: password' 'http://localhost:8123/' -d @-Si le nom d’utilisateur n’est pas spécifié, le nom default est utilisé. Si le mot de passe n’est pas spécifié, un mot de passe vide est utilisé.
Vous pouvez également utiliser les paramètres d’URL pour définir des réglages pour le traitement d’une seule requête ou de profils complets de réglages.
Par exemple :
http://localhost:8123/?profile=web&max_rows_to_read=1000000000&query=SELECT+1$ echo 'SELECT number FROM system.numbers LIMIT 10' | curl 'http://localhost:8123/?' --data-binary @-
0
1
2
3
4
5
6
7
8
9Pour en savoir plus, consultez :
Utilisation des sessions ClickHouse avec le protocole HTTP
Vous pouvez également utiliser les sessions ClickHouse avec le protocole HTTP. Pour ce faire, vous devez ajouter le paramètre GET session_id à la requête. Vous pouvez utiliser n’importe quelle chaîne comme identifiant de session.
Par défaut, la session prend fin après 60 secondes d’inactivité. Pour modifier ce délai d’expiration (en secondes), modifiez le paramètre default_session_timeout dans la configuration du serveur, ou ajoutez le paramètre GET session_timeout à la requête.
Pour vérifier l’état de la session, utilisez le paramètre session_check=1. Une seule requête à la fois peut être exécutée dans une même session.
Vous pouvez recevoir des informations sur la progression d’une requête dans les en-têtes de réponse X-ClickHouse-Progress. Pour ce faire, activez send_progress_in_http_headers.
Vous trouverez ci-dessous un exemple de séquence d’en-têtes :
X-ClickHouse-Progress: {"read_rows":"261636","read_bytes":"2093088","total_rows_to_read":"1000000","elapsed_ns":"14050417","memory_usage":"22205975"}
X-ClickHouse-Progress: {"read_rows":"654090","read_bytes":"5232720","total_rows_to_read":"1000000","elapsed_ns":"27948667","memory_usage":"83400279"}
X-ClickHouse-Progress: {"read_rows":"1000000","read_bytes":"8000000","total_rows_to_read":"1000000","elapsed_ns":"38002417","memory_usage":"80715679"}Les champs d’en-tête possibles sont :
| Champ d’en-tête | Description |
|---|---|
read_rows |
Nombre de lignes lues. |
read_bytes |
Volume de données lues en octets. |
total_rows_to_read |
Nombre total de lignes à lire. |
written_rows |
Nombre de lignes écrites. |
written_bytes |
Volume de données écrites en octets. |
elapsed_ns |
Durée d’exécution de la requête en nanosecondes. |
memory_usage |
Mémoire utilisée par la requête, en octets. (Disponible à partir de la version 25.11) |
Les requêtes en cours d’exécution ne s’arrêtent pas automatiquement si la connexion HTTP est perdue. L’analyse syntaxique et le formatage des données sont effectués côté serveur, et le recours au réseau peut s’avérer peu efficace.
Les paramètres facultatifs suivants existent :
| Parameters | Description |
|---|---|
query_id (optional) |
Peut être transmis comme identifiant de requête (n’importe quelle chaîne). replace_running_query |
quota_key (optional) |
Peut être transmis comme clé de quota (n’importe quelle chaîne). "Quotas" |
L’interface HTTP permet de transmettre des données externes (tables temporaires externes) pour l’exécution de requêtes. Pour plus d’informations, consultez "External data for query processing".
Mise en tampon des réponses
La mise en tampon des réponses peut être activée côté serveur. Les paramètres d’URL suivants sont disponibles à cet effet :
buffer_sizewait_end_of_query
Les paramètres suivants peuvent être utilisés :
buffer_size détermine le nombre d’octets du résultat à mettre en tampon dans la mémoire du serveur. Si le corps d’un résultat dépasse ce seuil, le tampon est écrit dans le canal HTTP et les données restantes sont envoyées directement à ce canal.
Pour garantir que l’intégralité de la réponse soit mise en tampon, définissez wait_end_of_query=1. Dans ce cas, les données qui ne sont pas stockées en mémoire seront mises en tampon dans un fichier temporaire sur le serveur.
Par exemple :
curl -sS 'http://localhost:8123/?max_result_bytes=4000000&buffer_size=3000000&wait_end_of_query=1' -d 'SELECT toUInt8(number) FROM system.numbers LIMIT 9000000 FORMAT RowBinary'Définir un rôle avec des paramètres de requête
Cette fonctionnalité a été ajoutée dans ClickHouse 24.4.
Dans certains cas, il peut être nécessaire de définir d’abord le rôle accordé avant d’exécuter l’instruction proprement dite.
Cependant, il n’est pas possible d’envoyer SET ROLE et l’instruction en une seule fois, car les requêtes multi-instructions ne sont pas autorisées :
curl -sS "http://localhost:8123" --data-binary "SET ROLE my_role;SELECT * FROM my_table;"La commande ci-dessus provoque une erreur :
Code: 62. DB::Exception: Syntax error (Multi-statements are not allowed)Pour contourner cette limitation, utilisez plutôt le paramètre de requête role :
curl -sS "http://localhost:8123?role=my_role" --data-binary "SELECT * FROM my_table;"Cela revient à exécuter SET ROLE my_role avant l’instruction.
De plus, il est possible de spécifier plusieurs paramètres de requête role :
curl -sS "http://localhost:8123?role=my_role&role=my_other_role" --data-binary "SELECT * FROM my_table;"Dans ce cas, ?role=my_role&role=my_other_role fonctionne comme si SET ROLE my_role, my_other_role était exécuté avant l’instruction.
Mises en garde concernant les codes de réponse HTTP
En raison des limites du protocole HTTP, un code de réponse HTTP 200 ne garantit pas qu'une requête a abouti.
Voici un exemple :
curl -v -Ss "http://localhost:8123/?max_block_size=1&query=select+sleepEachRow(0.001),throwIf(number=2)from+numbers(5)"
* Trying 127.0.0.1:8123...
...
< HTTP/1.1 200 OK
...
Code: 395. DB::Exception: Value passed to 'throwIf' function is non-zero: while executing 'FUNCTION throwIf(equals(number, 2) :: 1) -> throwIf(equals(number, 2))La raison de ce comportement tient à la nature du protocole HTTP. L’en-tête HTTP est envoyé en premier avec un code HTTP 200, suivi du corps HTTP, puis l’erreur est injectée dans le corps sous forme de texte brut.
Ce comportement est indépendant du format utilisé, qu’il s’agisse de Native, TSV ou JSON ; le message d’erreur se trouvera toujours au milieu du flux de réponse.
Vous pouvez atténuer ce problème en activant wait_end_of_query=1 (mise en tampon des réponses). Dans ce cas, l’envoi de l’en-tête HTTP est différé jusqu’à ce que la requête soit entièrement traitée. Cependant, cela ne résout pas complètement le problème, car le résultat doit toujours tenir dans http_response_buffer_size, et d’autres paramètres comme send_progress_in_http_headers peuvent empêcher ce délai d’être appliqué à l’en-tête.
Dans ClickHouse, ces exceptions ont un format cohérent, comme ci-dessous, quel que soit le format utilisé (par ex. Native, TSV, JSON, etc.) lorsque http_write_exception_in_output_format=0 (par défaut). Cela facilite l’analyse et l’extraction des messages d’erreur côté client.
\r\n
__exception__\r\n
<TAG>\r\n
<error message>\r\n
<message_length> <TAG>\r\n
__exception__\r\nOù <TAG> est un tag aléatoire de 16 octets, identique à celui envoyé dans l’en-tête de réponse X-ClickHouse-Exception-Tag.
Le <error message> correspond au message d’exception proprement dit (sa longueur exacte figure dans <message_length>). L’ensemble du bloc d’exception décrit ci-dessus peut atteindre 16 Kio.
Voici un exemple au format JSON
$ curl -v -Ss "http://localhost:8123/?max_block_size=1&query=select+sleepEachRow(0.001),throwIf(number=2)from+numbers(5)+FORMAT+JSON"
...
{
"meta":
[
{
"name": "sleepEachRow(0.001)",
"type": "UInt8"
},
{
"name": "throwIf(equals(number, 2))",
"type": "UInt8"
}
],
"data":
[
{
"sleepEachRow(0.001)": 0,
"throwIf(equals(number, 2))": 0
},
{
"sleepEachRow(0.001)": 0,
"throwIf(equals(number, 2))": 0
}
__exception__
dmrdfnujjqvszhav
Code: 395. DB::Exception: Value passed to 'throwIf' function is non-zero: while executing 'FUNCTION throwIf(equals(__table1.number, 2_UInt8) :: 1) -> throwIf(equals(__table1.number, 2_UInt8)) UInt8 : 0'. (FUNCTION_THROW_IF_VALUE_IS_NON_ZERO) (version 25.11.1.1)
262 dmrdfnujjqvszhav
__exception__Voici un exemple similaire, mais au format CSV
$ curl -v -Ss "http://localhost:8123/?max_block_size=1&query=select+sleepEachRow(0.001),throwIf(number=2)from+numbers(5)+FORMAT+CSV"
...
<
0,0
0,0
__exception__
rumfyutuqkncbgau
Code: 395. DB::Exception: Value passed to 'throwIf' function is non-zero: while executing 'FUNCTION throwIf(equals(__table1.number, 2_UInt8) :: 1) -> throwIf(equals(__table1.number, 2_UInt8)) UInt8 : 0'. (FUNCTION_THROW_IF_VALUE_IS_NON_ZERO) (version 25.11.1.1)
262 rumfyutuqkncbgau
__exception__Requêtes avec paramètres
Vous pouvez créer une requête avec des paramètres et leur attribuer des valeurs à partir des paramètres de la requête HTTP correspondante. Pour en savoir plus, consultez Requêtes avec paramètres pour l’interface CLI.
Exemple
$ curl -sS "<address>?param_id=2¶m_phrase=test" -d "SELECT * FROM table WHERE int_column = {id:UInt8} and string_column = {phrase:String}"Tabulations dans les paramètres d’URL
Les paramètres de requête sont analysés à partir du format "escaped". Cela présente certains avantages, comme la possibilité d’analyser sans ambiguïté les valeurs NULL sous la forme \N. Cela signifie que le caractère de tabulation doit être encodé sous la forme \t (ou \ suivi d’une tabulation). Par exemple, ce qui suit contient une véritable tabulation entre abc et 123, et la chaîne d’entrée est divisée en deux valeurs :
curl -sS "http://localhost:8123" -d "SELECT splitByChar('\t', 'abc 123')"['abc','123']Cependant, si vous essayez d’encoder un caractère de tabulation réel avec %09 dans un paramètre d’URL, il ne sera pas correctement interprété :
curl -sS "http://localhost:8123?param_arg1=abc%09123" -d "SELECT splitByChar('\t', {arg1:String})"
Code: 457. DB::Exception: Value abc 123 cannot be parsed as String for query parameter 'arg1' because it isn't parsed completely: only 3 of 7 bytes was parsed: abc. (BAD_QUERY_PARAMETER) (version 23.4.1.869 (official build))Si vous utilisez des paramètres d’URL, vous devrez encoder \t sous la forme %5C%09. Par exemple :
curl -sS "http://localhost:8123?param_arg1=abc%5C%09123" -d "SELECT splitByChar('\t', {arg1:String})"['abc','123']Interface HTTP prédéfinie
ClickHouse prend en charge certaines requêtes via l’interface HTTP. Par exemple, vous pouvez écrire des données dans une table comme suit :
$ echo '(4),(5),(6)' | curl 'http://localhost:8123/?query=INSERT%20INTO%20t%20VALUES' --data-binary @-ClickHouse prend également en charge une Interface HTTP prédéfinie, ce qui peut faciliter l’intégration avec des outils tiers comme Prometheus exporter. Prenons un exemple.
Tout d’abord, ajoutez cette section à votre fichier de configuration du serveur.
http_handlers est configuré pour contenir plusieurs rule. ClickHouse fera correspondre les requêtes HTTP reçues au type prédéfini dans rule, et la première règle qui correspond exécutera le gestionnaire. Ensuite, ClickHouse exécutera la requête prédéfinie correspondante si la correspondance aboutit.
<http_handlers>
<rule>
<url>/predefined_query</url>
<methods>POST,GET</methods>
<handler>
<type>predefined_query_handler</type>
<query>SELECT * FROM system.metrics LIMIT 5 FORMAT Template SETTINGS format_template_resultset = 'prometheus_template_output_format_resultset', format_template_row = 'prometheus_template_output_format_row', format_template_rows_between_delimiter = '\n'</query>
</handler>
</rule>
<rule>...</rule>
<rule>...</rule>
</http_handlers>Vous pouvez maintenant interroger directement l’URL pour des données au format Prometheus :
$ curl -v 'http://localhost:8123/predefined_query'
* Trying ::1...
* Connected to localhost (::1) port 8123 (#0)
> GET /predefined_query HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Tue, 28 Apr 2020 08:52:56 GMT
< Connection: Keep-Alive
< Content-Type: text/plain; charset=UTF-8
< X-ClickHouse-Server-Display-Name: i-mloy5trc
< Transfer-Encoding: chunked
< X-ClickHouse-Query-Id: 96fe0052-01e6-43ce-b12a-6b7370de6e8a
< X-ClickHouse-Format: Template
< X-ClickHouse-Timezone: Asia/Shanghai
< Keep-Alive: timeout=10
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334","memory_usage":"8451671"}
<
# HELP "Query" "Number of executing queries"
# TYPE "Query" counter
"Query" 1
# HELP "Merge" "Number of executing background merges"
# TYPE "Merge" counter
"Merge" 0
# HELP "PartMutation" "Number of mutations (ALTER DELETE/UPDATE)"
# TYPE "PartMutation" counter
"PartMutation" 0
# HELP "ReplicatedFetch" "Number of data parts being fetched from replica"
# TYPE "ReplicatedFetch" counter
"ReplicatedFetch" 0
# HELP "ReplicatedSend" "Number of data parts being sent to replicas"
# TYPE "ReplicatedSend" counter
"ReplicatedSend" 0
* Connection #0 to host localhost left intact
* Connection #0 to host localhost left intactLes options de configuration de http_handlers sont les suivantes.
rule permet de configurer les paramètres suivants :
methodheadersurlfull_urlhandler
Chacun de ces paramètres est décrit ci-dessous :
-
methodsert à faire correspondre la partie méthode de la requête HTTP.methodest entièrement conforme à la définition de [method] (https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) dans le protocole HTTP. Il s'agit d'une configuration facultative. S'il n'est pas défini dans le fichier de configuration, aucune correspondance n'est effectuée sur la partie méthode de la requête HTTP. -
urlsert à faire correspondre la partie URL (chemin et chaîne de requête) de la requête HTTP. Siurlest préfixé parregex:, il attend des expressions régulières RE2. Il s'agit d'une configuration facultative. S'il n'est pas défini dans le fichier de configuration, aucune correspondance n'est effectuée sur la partie URL de la requête HTTP. -
full_urlest identique àurl, mais inclut l'URL complète, c.-à-d.schema://host:port/path?query_string. Remarque : ClickHouse ne prend pas en charge les « hôtes virtuels », donchostest une adresse IP (et non la valeur de l'en-têteHost). -
empty_query_string- garantit l'absence de chaîne de requête (?query_string) dans la requête -
headersservent à faire correspondre la partie en-têtes de la requête HTTP. Ils sont compatibles avec les expressions régulières RE2. Il s'agit d'une configuration facultative. S'ils ne sont pas définis dans le fichier de configuration, aucune correspondance n'est effectuée sur la partie en-têtes de la requête HTTP. -
handlercontient la partie principale du traitement.Il peut avoir le
typesuivant :Et les paramètres suivants :
query— à utiliser avec le typepredefined_query_handler, exécute la query lorsque le gestionnaire est appelé.query_param_name— à utiliser avec le typedynamic_query_handler, extrait et exécute la valeur correspondant àquery_param_namedans les paramètres de requête HTTP.status— à utiliser avec le typestatic, code d'état de la réponse.content_type— à utiliser avec n'importe quel type, content-type de la réponse.http_response_headers— à utiliser avec n'importe quel type, map des en-têtes de la réponse. Peut également être utilisé pour définir le type de contenu.response_content— à utiliser avec le typestatic, contenu de la réponse envoyé au client ; lors de l'utilisation du préfixe 'file://' ou 'config://', le contenu est lu depuis le fichier ou la configuration, puis envoyé au client.user- utilisateur avec lequel exécuter la query (l'utilisateur par défaut estdefault). Remarque, vous n'avez pas besoin de spécifier de password pour cet utilisateur.
Les méthodes de configuration pour les différents type sont décrites ci-dessous.
predefined_query_handler
predefined_query_handler prend en charge la définition des valeurs Settings et query_params. Vous pouvez configurer query pour le type predefined_query_handler.
La valeur query est une requête prédéfinie de predefined_query_handler, exécutée par ClickHouse lorsqu’une requête HTTP correspond, puis le résultat de la requête est renvoyé. Cette configuration est obligatoire.
L’exemple suivant définit les valeurs des paramètres max_threads et max_final_threads, puis interroge la table système pour vérifier si ces paramètres ont bien été définis.
Par exemple :
<http_handlers>
<rule>
<url><![CDATA[regex:/query_param_with_url/(?P<name_1>[^/]+)]]></url>
<methods>GET</methods>
<headers>
<XXX>TEST_HEADER_VALUE</XXX>
<PARAMS_XXX><![CDATA[regex:(?P<name_2>[^/]+)]]></PARAMS_XXX>
</headers>
<handler>
<type>predefined_query_handler</type>
<query>
SELECT name, value FROM system.settings
WHERE name IN ({name_1:String}, {name_2:String})
</query>
</handler>
</rule>
<defaults/>
</http_handlers>curl -H 'XXX:TEST_HEADER_VALUE' -H 'PARAMS_XXX:max_final_threads' 'http://localhost:8123/query_param_with_url/max_threads?max_threads=1&max_final_threads=2'
max_final_threads 2
max_threads 1Paramètre virtuel _request_body
En plus des paramètres d’URL, des en-têtes et des paramètres de requête, predefined_query_handler prend en charge un paramètre virtuel spécial, _request_body.
Il contient le corps brut de la requête HTTP sous forme de chaîne de caractères.
Cela vous permet de créer des API REST flexibles, capables d’accepter des formats de données arbitraires et de les traiter dans vos requêtes.
Par exemple, vous pouvez utiliser _request_body pour implémenter un point de terminaison REST qui accepte des données JSON dans une requête POST et les insère dans une table :
<http_handlers>
<rule>
<methods>POST</methods>
<url>/api/events</url>
<handler>
<type>predefined_query_handler</type>
<query>
INSERT INTO events (id, data)
SELECT {id:UInt32}, {_request_body:String}
</query>
</handler>
</rule>
<defaults/>
</http_handlers>Vous pouvez ensuite envoyer des données à ce point de terminaison :
curl -X POST 'http://localhost:8123/api/events?id=123' \
-H 'Content-Type: application/json' \
-d '{"user": "john", "action": "login", "timestamp": "2024-01-01T10:00:00Z"}'dynamic_query_handler
Dans dynamic_query_handler, la requête est écrite comme paramètre de la requête HTTP. La différence est que, dans predefined_query_handler, la requête est écrite dans le fichier de configuration. query_param_name peut être configuré dans dynamic_query_handler.
ClickHouse extrait et exécute la valeur associée à query_param_name dans l’URL de la requête HTTP. La valeur par défaut de query_param_name est /query . Cette configuration est facultative. Si rien n’est défini dans le fichier de configuration, le paramètre n’est pas transmis.
Pour tester cette fonctionnalité, l’exemple suivant définit les valeurs de max_threads et max_final_threads, puis vérifie par une requête si les paramètres ont bien été définis.
Exemple :
<http_handlers>
<rule>
<headers>
<XXX>TEST_HEADER_VALUE_DYNAMIC</XXX> </headers>
<handler>
<type>dynamic_query_handler</type>
<query_param_name>query_param</query_param_name>
</handler>
</rule>
<defaults/>
</http_handlers>curl -H 'XXX:TEST_HEADER_VALUE_DYNAMIC' 'http://localhost:8123/own?max_threads=1&max_final_threads=2¶m_name_1=max_threads¶m_name_2=max_final_threads&query_param=SELECT%20name,value%20FROM%20system.settings%20where%20name%20=%20%7Bname_1:String%7D%20OR%20name%20=%20%7Bname_2:String%7D'
max_threads 1
max_final_threads 2static
static peut renvoyer content_type, status et response_content. response_content peut renvoyer le contenu indiqué.
Par exemple, pour renvoyer le message "Bonjour !" :
<http_handlers>
<rule>
<methods>GET</methods>
<headers><XXX>xxx</XXX></headers>
<url>/hi</url>
<handler>
<type>static</type>
<status>402</status>
<content_type>text/html; charset=UTF-8</content_type>
<http_response_headers>
<Content-Language>en</Content-Language>
<X-My-Custom-Header>43</X-My-Custom-Header>
</http_response_headers>
<response_content>Say Hi!</response_content>
</handler>
</rule>
<defaults/>
</http_handlers>http_response_headers peut être utilisé pour définir le type de contenu à la place de content_type.
<http_handlers>
<rule>
<methods>GET</methods>
<headers><XXX>xxx</XXX></headers>
<url>/hi</url>
<handler>
<type>static</type>
<status>402</status>
#begin-highlight
<http_response_headers>
<Content-Type>text/html; charset=UTF-8</Content-Type>
<Content-Language>en</Content-Language>
<X-My-Custom-Header>43</X-My-Custom-Header>
</http_response_headers>
#end-highlight
<response_content>Say Hi!</response_content>
</handler>
</rule>
<defaults/>
</http_handlers>curl -vv -H 'XXX:xxx' 'http://localhost:8123/hi'
* Trying ::1...
* Connected to localhost (::1) port 8123 (#0)
> GET /hi HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.47.0
> Accept: */*
> XXX:xxx
>
< HTTP/1.1 402 Payment Required
< Date: Wed, 29 Apr 2020 03:51:26 GMT
< Connection: Keep-Alive
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Keep-Alive: timeout=10
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334","memory_usage":"8451671"}
<
* Connection #0 to host localhost left intact
Say Hi!%Retrouvez le contenu de la configuration envoyée au client.
<get_config_static_handler><![CDATA[<html ng-app="SMI2"><head><base href="http://ui.tabix.io/"></head><body><div ui-view="" class="content-ui"></div><script src="http://loader.tabix.io/master.js"></script></body></html>]]></get_config_static_handler>
<http_handlers>
<rule>
<methods>GET</methods>
<headers><XXX>xxx</XXX></headers>
<url>/get_config_static_handler</url>
<handler>
<type>static</type>
<response_content>config://get_config_static_handler</response_content>
</handler>
</rule>
</http_handlers>$ curl -v -H 'XXX:xxx' 'http://localhost:8123/get_config_static_handler'
* Trying ::1...
* Connected to localhost (::1) port 8123 (#0)
> GET /get_config_static_handler HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.47.0
> Accept: */*
> XXX:xxx
>
< HTTP/1.1 200 OK
< Date: Wed, 29 Apr 2020 04:01:24 GMT
< Connection: Keep-Alive
< Content-Type: text/plain; charset=UTF-8
< Transfer-Encoding: chunked
< Keep-Alive: timeout=10
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334","memory_usage":"8451671"}
<
* Connection #0 to host localhost left intact
<html ng-app="SMI2"><head><base href="http://ui.tabix.io/"></head><body><div ui-view="" class="content-ui"></div><script src="http://loader.tabix.io/master.js"></script></body></html>%Pour trouver le contenu du fichier transmis au client :
<http_handlers>
<rule>
<methods>GET</methods>
<headers><XXX>xxx</XXX></headers>
<url>/get_absolute_path_static_handler</url>
<handler>
<type>static</type>
<content_type>text/html; charset=UTF-8</content_type>
<http_response_headers>
<ETag>737060cd8c284d8af7ad3082f209582d</ETag>
</http_response_headers>
<response_content>file:///absolute_path_file.html</response_content>
</handler>
</rule>
<rule>
<methods>GET</methods>
<headers><XXX>xxx</XXX></headers>
<url>/get_relative_path_static_handler</url>
<handler>
<type>static</type>
<content_type>text/html; charset=UTF-8</content_type>
<http_response_headers>
<ETag>737060cd8c284d8af7ad3082f209582d</ETag>
</http_response_headers>
<response_content>file://./relative_path_file.html</response_content>
</handler>
</rule>
</http_handlers>$ user_files_path='/var/lib/clickhouse/user_files'
$ sudo echo "<html><body>Relative Path File</body></html>" > $user_files_path/relative_path_file.html
$ sudo echo "<html><body>Absolute Path File</body></html>" > $user_files_path/absolute_path_file.html
$ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_absolute_path_static_handler'
* Trying ::1...
* Connected to localhost (::1) port 8123 (#0)
> GET /get_absolute_path_static_handler HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.47.0
> Accept: */*
> XXX:xxx
>
< HTTP/1.1 200 OK
< Date: Wed, 29 Apr 2020 04:18:16 GMT
< Connection: Keep-Alive
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Keep-Alive: timeout=10
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334","memory_usage":"8451671"}
<
<html><body>Absolute Path File</body></html>
* Connection #0 to host localhost left intact
$ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_relative_path_static_handler'
* Trying ::1...
* Connected to localhost (::1) port 8123 (#0)
> GET /get_relative_path_static_handler HTTP/1.1
> Host: localhost:8123
> User-Agent: curl/7.47.0
> Accept: */*
> XXX:xxx
>
< HTTP/1.1 200 OK
< Date: Wed, 29 Apr 2020 04:18:31 GMT
< Connection: Keep-Alive
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Keep-Alive: timeout=10
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334","memory_usage":"8451671"}
<
<html><body>Relative Path File</body></html>
* Connection #0 to host localhost left intactredirect
redirect effectue une redirection 302 vers location
Par exemple, voici comment ajouter automatiquement set user à play dans ClickHouse play :
<clickhouse>
<http_handlers>
<rule>
<methods>GET</methods>
<url>/play</url>
<handler>
<type>redirect</type>
<location>/play?user=play</location>
</handler>
</rule>
</http_handlers>
</clickhouse>En-têtes de réponse HTTP
ClickHouse vous permet de configurer des en-têtes de réponse HTTP personnalisés, applicables à tout type de gestionnaire configurable. Ces en-têtes peuvent être définis à l’aide du paramètre http_response_headers, qui accepte des paires clé-valeur représentant les noms des en-têtes et leurs valeurs. Cette fonctionnalité est particulièrement utile pour mettre en place des en-têtes de sécurité personnalisés, des politiques CORS ou toute autre exigence relative aux en-têtes HTTP sur votre interface HTTP ClickHouse.
Par exemple, vous pouvez configurer des en-têtes pour :
- Points de terminaison de requête standard
- Web UI
- Vérification d’état.
Il est également possible de spécifier common_http_response_headers. Ceux-ci seront appliqués à tous les gestionnaires HTTP définis dans la configuration.
Les en-têtes seront inclus dans la réponse HTTP de chaque gestionnaire configuré.
Dans l’exemple ci-dessous, chaque réponse du serveur contiendra deux en-têtes personnalisés : X-My-Common-Header et X-My-Custom-Header.
<clickhouse>
<http_handlers>
<common_http_response_headers>
<X-My-Common-Header>Common header</X-My-Common-Header>
</common_http_response_headers>
<rule>
<methods>GET</methods>
<url>/ping</url>
<handler>
<type>ping</type>
<http_response_headers>
<X-My-Custom-Header>Custom indeed</X-My-Custom-Header>
</http_response_headers>
</handler>
</rule>
</http_handlers>
</clickhouse>Réponse JSON/XML valide en cas d’exception lors du streaming HTTP
Lorsqu’une requête est exécutée via HTTP, une exception peut se produire alors qu’une partie des données a déjà été envoyée. En général, l’exception est envoyée au client en texte brut.
Même si un format de données spécifique a été utilisé pour la sortie, celle-ci peut devenir invalide au regard du format spécifié.
Pour éviter cela, vous pouvez utiliser le paramètre http_write_exception_in_output_format (désactivé par défaut), qui indique à ClickHouse d’écrire l’exception dans le format spécifié (actuellement pris en charge pour les formats XML et JSON*).
Exemples :
$ curl 'http://localhost:8123/?query=SELECT+number,+throwIf(number>3)+from+system.numbers+format+JSON+settings+max_block_size=1&http_write_exception_in_output_format=1'
{
"meta":
[
{
"name": "number",
"type": "UInt64"
},
{
"name": "throwIf(greater(number, 2))",
"type": "UInt8"
}
],
"data":
[
{
"number": "0",
"throwIf(greater(number, 2))": 0
},
{
"number": "1",
"throwIf(greater(number, 2))": 0
},
{
"number": "2",
"throwIf(greater(number, 2))": 0
}
],
"rows": 3,
"exception": "Code: 395. DB::Exception: Value passed to 'throwIf' function is non-zero: while executing 'FUNCTION throwIf(greater(number, 2) :: 2) -> throwIf(greater(number, 2)) UInt8 : 1'. (FUNCTION_THROW_IF_VALUE_IS_NON_ZERO) (version 23.8.1.1)"
}$ curl 'http://localhost:8123/?query=SELECT+number,+throwIf(number>2)+from+system.numbers+format+XML+settings+max_block_size=1&http_write_exception_in_output_format=1'
<?xml version='1.0' encoding='UTF-8' ?>
<result>
<meta>
<columns>
<column>
<name>number</name>
<type>UInt64</type>
</column>
<column>
<name>throwIf(greater(number, 2))</name>
<type>UInt8</type>
</column>
</columns>
</meta>
<data>
<row>
<number>0</number>
<field>0</field>
</row>
<row>
<number>1</number>
<field>0</field>
</row>
<row>
<number>2</number>
<field>0</field>
</row>
</data>
<rows>3</rows>
<exception>Code: 395. DB::Exception: Value passed to 'throwIf' function is non-zero: while executing 'FUNCTION throwIf(greater(number, 2) :: 2) -> throwIf(greater(number, 2)) UInt8 : 1'. (FUNCTION_THROW_IF_VALUE_IS_NON_ZERO) (version 23.8.1.1)</exception>
</result>