Verwendung von Anforderungs- und Antwortübersetzern mit Daten für einen Remotedienst¶
Mit Anforderungs- und Antwortübersetzern können Sie für Remotedienste, die von externen Funktionen verwendet werden, das Format der gesendeten oder empfangenen Daten verändern.
Unter diesem Thema:
Zweck¶
Wenn Snowflake Daten an einen Remotedienst sendet, formatiert Snowflake die Daten nach diesen Regeln. Wenn Snowflake Daten von einem Remotedienst empfängt, erwartet Snowflake, dass die Daten nach denselben Regeln formatiert werden.
Viele Remotedienste erwarten, dass sie Daten in einem anderen Format verarbeiten. Anforderungs- und Antwortübersetzer vereinfachen folgende Operationen:
Konvertierung von Daten aus dem Snowflake-Format in das native Eingabeformat des Remotedienstes (Anforderungsübersetzer).
Konvertierung von Daten aus dem nativen Ausgabeformat des Remotedienstes in das Snowflake-Format (Antwortübersetzer).
SQL-Implementierung¶
Für das Übersetzen von Daten zwischen dem Snowflake-Format und dem nativen Eingabeformat des Remotedienstes können Sie JavaScript-UDFs (benutzerdefinierte Funktionen) verwenden. In den meisten Fällen ist ein Paar von UDFs erforderlich: eine UDF zur Übersetzung der Anforderung und eine UDF zur Übersetzung der Antwort.
Snowflake ruft diese Funktionen als Teil jedes Aufrufs einer externen Funktion auf. Für eine Anforderung an einen Remotedienst ruft Snowflake beispielsweise die Funktion für den Anforderungsübersetzer auf, übergibt diesem die Snowflake-formatierten Daten, übernimmt die zurückgegebenen Daten und sendet diese an den Remotedienst. Nachdem der Remotedienst Daten zurückgegeben hat, ruft Snowflake die Funktion für den Antwortübersetzer auf, um die Daten wieder in das für Snowflake verständliche Format zu konvertieren.
Aus der Sicht des Benutzers ist der Aufruf einer externen Funktion bei Konvertierung durch einen Übersetzer derselbe wie der Aufruf einer externen Funktion ohne Übersetzer. Nachdem Sie Übersetzer als Teil der CREATE EXTERNAL FUNCTION-Anweisung angegeben haben, werden die Übersetzer automatisch aufgerufen.
Eine externe Funktion kann maximal einen Anforderungsübersetzer und einen Antwortübersetzer gleichzeitig haben.
Die UDFs für Anforderungs- und Antwortübersetzer können sichere UDFs sein.
Zuweisen einer Übersetzerfunktion zu einer externen Funktion¶
Um anzugeben, welche benutzerdefinierte Funktion als Übersetzer verwendet werden soll, fügen Sie in die CREATE EXTERNAL FUNCTION
-Anweisung die Klauseln REQUEST_TRANSLATOR
und RESPONSE_TRANSLATOR
ein. Jede nimmt den Namen der Übersetzerfunktion an, die zur Laufzeit verwendet werden soll.
Beispiel:
CREATE EXTERNAL FUNCTION f(...) RETURNS OBJECT ... REQUEST_TRANSLATOR = my_request_translator_udf RESPONSE_TRANSLATOR = my_response_translator_udf ... AS <url_of_proxy_and_resource>;
Im Folgenden ist die Syntax für die Angabe von Übersetzern als Teil einer CREATE EXTERNAL FUNCTION
-Anweisung gezeigt:
CREATE EXTERNAL FUNCTION f(...) RETURNS OBJECT ... [ REQUEST_TRANSLATOR = <request_translator_udf_name> ] [ RESPONSE_TRANSLATOR = <response_translator_udf_name> ] ...Wobei:
request_translator_udf_name
Der Name der Anforderungsübersetzerfunktion.
response_translator_udf_name
Der Name der Antwortübersetzerfunktion.
Die Parameter REQUEST_TRANSLATOR
und RESPONSE_TRANSLATOR
nehmen jeweils einen Parameter vom Typ OBJECT auf.
Sie können auch einen Anforderungs- oder Antwortübersetzer in einem ALTER FUNCTION-Befehl angeben. Folgende Aufgaben können ausgeführt werden:
Hinzufügen eines Übersetzers, wenn die externe Funktion noch keinen hat
Ersetzen eines vorhandenen Übersetzer
Entfernen eines Übersetzers
Verwenden Sie das Schlüsselwort SET
, um einen neuen Übersetzer hinzuzufügen oder einen vorhandenen Übersetzer zu ersetzen.
So können Sie einen Übersetzer hinzufügen oder ersetzen:
ALTER FUNCTION ... SET [REQUEST_TRANSLATOR | RESPONSE_TRANSLATOR] = <udf_name>;Wobei:
udf_name
Der Name einer vorher erstellten JavaScript-UDF.
So können Sie einen Übersetzer entfernen:
ALTER FUNCTION ... UNSET [REQUEST_TRANSLATOR | RESPONSE_TRANSLATOR];
SQL-Anforderungen¶
Der Name der Übersetzerfunktion in der
CREATE EXTERNAL FUNCTION
- oderALTER FUNCTION
-Anweisung muss eine der folgenden Anforderungen erfüllen:Der Name muss qualifiziert sein (z. B. MyDatabase.MySchema.MyJavaScriptUDF).
Der Name muss in derselben Datenbank und demselben Schema definiert sein wie die externe Funktion, in der er verwendet wird.
Wenn der Übersetzer in einer
CREATE EXTERNAL FUNCTION
- oderALTER FUNCTION
-Anweisung angegeben wird, muss die Übersetzer-UDF bereits vorhanden sein. Sie können nicht zuerst den Namen angeben und später die UDF erstellen – auch nicht, wenn Sie die externe Funktion erst aufrufen, wenn Sie die UDF erstellt haben.Eine UDF, die als Übersetzer verwendet wird, darf erst gelöscht werden, wenn sie vorher aus allen externen Funktionen entfernt wurde, in denen sie verwendet wird. (Zum Zeitpunkt des Aufrufs der externen Funktion schlägt Snowflake mit einem Fehler fehl, wenn der Übersetzer nicht vorhanden ist).
Wenn die Übersetzer-UDF mit
ALTER FUNCTION
geändert wird, muss sie dieselben Schnittstellenanforderungen erfüllen. Wenn die Schnittstellenanforderungen nicht erfüllt werden, wird vor Ausführung der externen Funktion eine Ausnahme ausgelöst.
JavaScript-Implementierung¶
Zur Laufzeit wird via SQL ein OBJECT an die Übersetzer-UDF übergeben. Der JavaScript-Code erhält diesen Wert als JavaScript-Objekt.
Implementieren eines Anforderungsübersetzers¶
Eingabeeigenschaften des Anforderungsübersetzers¶
Einer Übersetzer-UDF wird ein JavaScript-Objekt mit dem Namen event
übergeben. Das Objekt enthält die folgenden Eigenschaften:
body
: Das Format desdata
-Feldes entspricht dem des bestehenden Snowflake-Rowset-Batches (d. h. ein Array von Zeilen).Beispiel:
{ "body": { "data": [ [0,"cat"], [1,"dog"] ] } }
Die vorhandenen Daten werden unter dem äußeren Text geschachtelt.
serviceUrl
: Die definierte URL der externen Funktion, die aufgerufen werden soll.contextHeaders
: Ein Objekt, das alle kontextbezogenen Kopfzeilen enthält, wobei die Namen die Feldnamen sind. Das Objekt könnte zum Beispiel den Feldnamen „SF_CONTEXT_CURRENT_DATABASE“ enthalten, und der entsprechende Wert wäre eine Zeichenfolge, die den aktuellen Datenbanknamen enthält.
Eingabeeigenschaften des Anforderungsübersetzers¶
Der Anforderungsübersetzer gibt ein Objekt mit Feldern zurück, die für die Kommunikation mit dem API-Gateway des externen Dienstes verwendet werden. Dieses Objekt hat drei optionale Felder:
body
: Definiert den eigentlichen Text, der an den Dienst übergeben wird. Wenn dies nicht definiert ist, gibt es keinen Text. Derbody
-Wert muss eine Zeichenfolge oder ein JSON-Objekt in dem Format sein, das der Remotedienst erwartet. Wenn der Wert eine Zeichenfolge ist, kann diese Zeichenfolge eine interne Struktur enthalten (z. B. JSON-kompatibel sein). Handelt es sich bei dem Wert um ein JSON-Objekt, wird dieses Objekt in eine Zeichenfolge umgewandelt, sodass es als Teil der HTTP POST-Befehlszeichenfolge eingefügt werden kann.urlSuffix
: Legt das Suffix der Dienst-URL fest, das an das Ende vonserviceUrl
angehängt wird. Dieses Suffix darf auch Abfrageparameter enthalten. Parameternamen und -werte müssen URL-codiert sein. Wenn Sie z. B. einen Parameter mit dem Namena
auf den Wertmy param
setzen möchten, müssen Sie das Leerzeichen URL-codieren, sodass der Parameter?a=my%20param
lauten würde.translatorData
: Wird vom Anforderungsübersetzer an den Antwortübersetzer übergegeben. Dieses Feld kann Kontextinformationen übergeben, wie z. B. den Eingabetext, die Dienst-URL oder das Suffix oder die Kontext-Header.
Alle drei Felder sind optional. In der Praxis geben die meisten Anforderungsübersetzer jedoch zumindest die „body“-Daten zurück.
Implementieren eines Antwortübersetzers¶
Eingabeeigenschaften des Antwortübersetzers¶
Der Eingabeparameter für die Antwortübersetzerfunktion ist ein Objekt. Im folgenden Beispiel wird EVENT
verwendet, das zwei Eigenschaften enthält:
body
: Die Antwort, die aus der Antwort des externen Dienstes decodiert werden muss.translatorData
: Wenn dieses Feld vom Anforderungsübersetzer zurückgegeben wird, übergibt Snowflake es an den Antwortübersetzer.
Ausgabeeigenschaften des Antwortübersetzers¶
Die Antwort des Antwortübersetzers wird als Objekt unter dem body
-Element zurückgegeben. Das Format ist das bestehende Format der externen Funktion (Array von Zeilen). Beispiel:
{ "body": { "data": [ [0, "Life"], [1, "the universe"], [2, "and everything"] ] } }
Anforderungen an die Übersetzerfunktion¶
Jede Übersetzer-UDF muss die folgenden Anforderungen erfüllen:
Muss eine JavaScript-UDF sein.
Muss genau einen Parameter vom Typ OBJECT enthalten, der einen Batch von Zeilen repräsentiert.
Muss genau einen Wert vom Typ OBJECT zurückgeben, der ebenfalls einen Batch von Zeilen repräsentiert.
Die UDF muss skalar sein, d. h. sie gibt für jede übergebene Zeile (OBJECT) genau eine Zeile zurück.
Bemerkung
Obwohl der Übersetzer skalar ist, kann der an den Übersetzer übergebene OBJECT-Wert mehrere in den JSON-Code von OBJECT eingebettete Zeilen enthalten (und tut dies normalerweise auch).
Anzahl und Reihenfolge der von der Antwortübersetzer-UDF zurückgegebenen Zeilen (innerhalb des OBJECT-Werts) müssen mit Anzahl und Reihenfolge der an die Anforderungsübersetzer-UDF übergebenen Zeilen (innerhalb der OBJECT-Werts) übereinstimmen.
Beispiel für einen Anforderungsübersetzer und einen Antwortübersetzer¶
Das folgende Beispiel zeigt, wie ein Anforderungsübersetzer und ein Antwortübersetzer verwendet werden, um Daten in das Format zu konvertieren, das von einem externen Dienst zur Ausführung von Stimmungsanalysen benötigt wird, wie z. B. Amazon Comprehend BatchDetectSentiment. Der Anforderungsübersetzer formt die HTTP-Anfrage so, dass sie mit dem Format übereinstimmt, das der Backend-Dienst erwartet.
Um die Übersetzer verwenden zu können, benötigen Sie ein API-Gateway. In diesem Beispiel wird ein API-Gateway verwendet, das bereits so konfiguriert ist, dass es mit dem Stimmungsanalyse-Dienst kommunizieren kann. Weitere Informationen zur Integration mit einem Amazon Web Services (AWS)-Service als Backend finden Sie unter API-Integrationsanforderung mit API-Gateway-Konsole einrichten in der AWS-Dokumentation.
Es empfiehlt sich, erst die API-Integration erfolgreich einzurichten, bevor Sie Übersetzerprogramme hinzufügen.
Setup¶
Richten Sie eine Datenbank für die Demodaten ein.
Wählen Sie eine Rolle, die über die Berechtigung zum Erstellen externer Funktionen verfügt:
USE ROLE ACCOUNTADMIN;
Geben Sie an, welches Warehouse, welche Datenbank und welches Schema verwendet werden sollen:
USE WAREHOUSE w;
USE DATABASE a;
USE SCHEMA b;
Erstellen Sie eine Tabelle, die Ihre Testsätze enthält:
CREATE TABLE demo(vc varchar);
INSERT INTO demo VALUES('Today is a good day'),('I am feeling mopey');
Anforderungstext vor der Übersetzung¶
Diese externe Funktion hat weder einen Anforderungsübersetzer noch einen Antwortübersetzer:
CREATE OR REPLACE EXTERNAL FUNCTION ComprehendSentiment(thought varchar)
RETURNS VARIANT
API_INTEGRATION = aws_comprehend_gateway
AS 'https://<MY_GATEWAY>.execute-api.us-east-1.amazonaws.com/test/comprehend_proxy';
Rufen Sie die externe Funktion mit Ihren Testdaten aus der Demo-Tabelle auf:
SELECT ComprehendSentiment(vc), vc FROM demo;
Der generierte Anforderungstext verwendet das Snowflake-Datenformat für externe Funktionen:
{"body":{"data:" [[0, "Today is a good day"],[1,"I am feeling mopey"]]}}
Der externe Stimmungsanalyse-Dienst erwartet jedoch ein anderes Format, das die Sprache und ein Array von Zeichenfolgen angibt:
{"body": { Language: "en", TextList: [ "Today is a good day", "I am feeling mopey"]}}
Im nächsten Abschnitt wird beschrieben, wie Sie einen Anforderungsübersetzer hinzufügen können, um den Anforderungstext in das gewünschte Format zu ändern.
Anforderungstext konvertieren¶
Mithilfe eines Anforderungsübersetzers können Sie die oben beschriebene Standardeingabe (im Snowflake-Datenformat) in das Format umwandeln, das der externe Dienst benötigt.
Mit folgender SQL wird eine awscomprehendrequest_translator
-Übersetzerfunktion erstellt.
CREATE OR REPLACE FUNCTION AWSComprehendrequest_translator(EVENT OBJECT)
RETURNS OBJECT
LANGUAGE JAVASCRIPT AS
'
var textlist = []
for(i = 0; i < EVENT.body.data.length; i++) {
let row = EVENT.body.data[i];
// row[0] is the row number and row[1] is the input text.
textlist.push(row[1]); //put text into the textlist
}
// create the request for the service. Also pass the input request as part of the output.
return { "body": { "LanguageCode": "en", "TextList" : textlist }, "translatorData": EVENT.body }
';
Für die Anforderungsübersetzerfunktion wird folgender Code verwendet:
Durchläuft jede Eingabezeilen in einer Schleife. Für jede Zeile wird die Zeichenfolge, die sich in
row[1]
befindet, dem Arraytextlist
hinzugefügt. Der Wert inrow[0]
ist die Zeilennummer, die ignoriert werden kann.Gibt JSON-Text zurück, der den Sprachcode und die Textliste enthält, die mit den Anforderungen des externen Dienstes übereinstimmen.
Gibt Daten über das Feld
translatorData
zurück. Dieses wird vom Antwortübersetzer verwendet. In diesem Beispiel senden Sie die ursprünglichen Eingabedaten. Anhand der Länge der Eingabedaten im Antwortübersetzer können Sie feststellen, wie viele Eingabeanforderungen es gab.
Sie können den Anforderungsübersetzer testen, indem Sie ihn direkt aufrufen.
SELECT AWSComprehendrequest_translator(parse_json('{"body":{"data": [[0, "I am so happy we got a sunny day for my birthday."], [1, "$$$$$."], [2, "Today is my last day in the old house."]]}}'));
Der Anforderungsübersetzer bringt den Text in die Form, die der externe Dienst erwartet.
{"body":{
"LanguageCode": "en",
"TextList": [
"I am so happy we got a sunny day for my birthday.",
"$$$$$.",
"Today is my last day in the old house."
]
},
"translatorData": {
"data": [[0, "I am so happy we got a sunny day for my birthday."],
[1, "$$$$$."],
[2, "Today is my last day in the old house."]]
}
}
Antworttext vor dem Hinzufügen eines Antwortübersetzers¶
Ein Antworttext des externen Dienstes sieht etwa wie folgt aus.
{"body":{
"ErrorList": [ { "ErrorCode": 57, "ErrorMessage": "Language unknown", "Index": 1} ],
"ResultList":[ { "Index": 0, "Sentiment": "POSITIVE",
"SentimentScore": { "Mixed": 25, "Negative": 5, "Neutral": 1, "Positive": 90 }},
{ "Index": 2, "Sentiment": "NEGATIVE",
"SentimentScore": { "Mixed": 25, "Negative": 75, "Neutral": 30, "Positive": 20 }}
]
}
}
Antworttext konvertieren¶
Der Antwortübersetzer verarbeitet die Ergebnisse, die Sie vom externen Dienst zurückerhalten. Die Ergebnisse enthalten eine Kombination aus Fehlern im ErrorList
-Objekt und Ergebnissen im ResultList
-Objekt.
Der Code des Antwortübersetzers kombiniert diese Ergebnisse zu einem vollständigen Set, das mit der Reihenfolge der Zeilen übereinstimmt, die an den externen Dienst übergeben wurden. Der Antwortübersetzer gibt die Ergebnisse im Snowflake-Format zurück.
Mit folgender SQL wird eine awscomprehendresponse_translator
-Übersetzerfunktion erstellt.
CREATE OR REPLACE FUNCTION AWSComprehendresponse_translator(EVENT OBJECT)
RETURNS OBJECT
LANGUAGE JAVASCRIPT AS
'
// Combine the scored results and the errors into a single list.
var responses = new Array(EVENT.translatorData.data.length);
// output format: array of {
// "Sentiment": (POSITIVE, NEUTRAL, MIXED, NEGATIVE, or ERROR),
// "SentimentScore": <score>, "ErrorMessage": ErrorMessage }.
// If error, set ErrorMessage; otherwise, set SentimentScore.
// Insert good results into proper position.
for(i = 0; i < EVENT.body.ResultList.length; i++) {
let row = EVENT.body.ResultList[i];
let result = [row.Index, {"Sentiment": row.Sentiment, "SentimentScore": row.SentimentScore}]
responses[row.Index] = result
}
// Insert errors.
for(i = 0; i < EVENT.body.ErrorList.length; i++) {
let row = EVENT.body.ErrorList[i];
let result = [row.Index, {"Sentiment": "Error", "ErrorMessage": row.ErrorMessage}]
responses[row.Index] = result
}
return { "body": { "data" : responses } };
';
Für die Antwortübersetzerfunktion wird folgender Code verwendet:
Initialisiert ein Array namens
responses
mit der Größe der Eingabe aus der Länge des ArraystranslatorData
. Sie habentranslatorData
vom Anforderungsübersetzer an den Antwortübersetzer gesendet, um die ursprüngliche Liste der Testzeichenfolgen zu übergeben.Durchläuft alle Ergebnisse, die keine Fehler sind, in einer Schleife, und trägt diese in die Ergebnisliste ein.
Durchläuft die Fehlerergebnisse in einer Schleife, und trägt diese in die Ergebnisliste ein. Die Ergebnisliste hat eine Indexposition, die darüber informiert, um welchen Eintrag es sich handelt. Die Reihenfolge der erstellten Ergebnisse muss mit der Eingabereihenfolge übereinstimmen. Die Ergebnisliste enthält auch die Stimmungsinformationen.
Nachdem alle Antworten gesammelt wurden, werden sie in einem JSON-Text in dem von Snowflake erwarteten Format zurückgegeben.
Der folgende direkte Test liefert einen JSON-Textkörper mit dem korrekten Format.
SELECT AWSComprehendresponse_translator(
parse_json('{
"translatorData": {
"data": [[0, "I am so happy we got a sunny day for my birthday."],
[1, "$$$$$."],
[2, "Today is my last day in the old house."]]
}
"body": {
"ErrorList": [ { "ErrorCode": 57, "ErrorMessage": "Language unknown", "Index": 1 } ],
"ResultList": [
{ "Index": 0, "Sentiment": "POSITIVE",
"SentimentScore": { "Mixed": 25, "Negative": 5, "Neutral": 1, "Positive": 90 }
},
{ "Index": 2, "Sentiment": "NEGATIVE",
"SentimentScore": { "Mixed": 25, "Negative": 75, "Neutral": 30, "Positive": 20 }
}
]
},
}'
)
);
Übersetzer der externen Funktion zuweisen¶
Fügen Sie der externen Funktion die Anforderungs- und Antwortübersetzerfunktionen hinzu, indem Sie den Parametern request_translator
und response_translator
die Funktionsnamen als Werte zuweisen. Auf diese Weise werden sie automatisch aufgerufen, wenn die externe Funktion ausgeführt wird.
CREATE OR REPLACE EXTERNAL FUNCTION ComprehendSentiment(thought varchar)
RETURNS VARIANT
API_INTEGRATION = aws_comprehend_gateway
request_translator = db_name.schema_name.AWSComprehendrequest_translator
response_translator = db_name.schema_name.AWSComprehendresponse_translator
AS 'https://<MY_GATEWAY>.execute-api.us-east-1.amazonaws.com/test/comprehend_proxy';
Sie können die Funktion beschreiben, um Informationen über sie zu erhalten.
DESCRIBE FUNCTION ComprehendSentiment(VARCHAR);
Externe Funktion aufrufen¶
Testen Sie die externe Funktion, indem Sie sie mit einem einzelnen Satz aufrufen.
SELECT ComprehendSentiment('Today is a good day');
Sie sehen die Ergebnisse der Stimmungsanalyse.
{"Sentiment": "POSITIVE",
"SentimentScore":{"Mixed":0.002436627633869648,
"Negative":0.0014803812373429537,
"Neutral":0.015923455357551575,
"Positive": 0.9801595211029053}}
Testen Sie die externe Funktion, indem Sie sie mit mehreren Sätzen aufrufen. Verwenden Sie dieselbe Tabelle demo
, die Sie zuvor erstellt haben.
SELECT ComprehendSentiment(vc), vc FROM demo;
Die Ergebnisse der Stimmungsanalyse werden angezeigt.
Beim Aufruf der externen Funktion konvertierte der Anforderungsübersetzer die Daten automatisch in das für den externen Dienst erforderliche Format. Anschließend konvertierte der Antwortübersetzer die Antwort des externen Dienstes automatisch zurück in das von Snowflake benötigte Format.
Tipps zum Testen von Anforderungs- und Antwortübersetzern¶
Testfallwerte sind in der Regel OBJECT-Werte (Collections von Schlüssel-Wert-Paaren). Diese sollten so formatiert werden, dass sie die Anforderungen dieser Regeln erfüllen.
Sie können das Testen des Programms Ihres Anforderungsübersetzers oder Antwortübersetzers damit beginnen, dass Sie eine in eine Zeichenfolge konvertierte Beispieleingabe übergeben. Beispiel:
select my_request_translator_function(parse_json('{"body": {"data": [ [0,"cat",867], [1,"dog",5309] ] } }'));
(Die Eingabe für
PARSE_JSON()
muss eine JSON-formatierte Zeichenfolge sein.)Testen Sie falls erforderlich mit
NULL
-Werten.Fügen Sie mindestens einen SQL
NULL
-Wert in Ihre Testfälle ein.Fügen Sie mindestens einen JSON NULL-Wert in Ihre Testfälle ein.
Das Übersetzen einer Anforderung und das Übersetzen einer Antwort sind oft gegenläufige Prozesse. Konzeptionell:
my_response_translator_udf(my_request_translator_udf(x)) = x
Mithilfe dieser Eigenschaft können Sie testen, ob die Datenformate der Programme für Anforderungsübersetzer und zugehörigem Antwortübersetzer übereinstimmen. Erstellen Sie eine Tabelle mit guten Testwerten, und führen Sie dann einen Befehl ähnlich wie dem folgenden aus:
SELECT test_case_column FROM test_table WHERE my_response_translator_udf(my_request_translator_udf(x)) != x;
Die Abfrage sollte keine Zeilen zurückgeben.
Beachten Sie, dass das Übersetzen einer Anforderung und das Übersetzen einer Antwort nicht immer genau umgekehrt sind. Ein Beispiel dafür, dass sie nicht umgekehrt sein können, finden Sie in der Dokumentation zur Funktion TO_JSON() im Abschnitt „Nutzungshinweise“.