I have a database trigger function like this:
CREATE OR REPLACE FUNCTION public.webhook()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
BEGIN
PERFORM status FROM
http_post('https://example.com/receiver', jsonb_set(jsonb_build_object('action',TG_OP,'table',TG_TABLE_NAME),'{value}',
to_jsonb(NEW.*)));
RETURN NULL;
END;
$function$
;
But I get now new field "value" inside my json. What is wrong with my function?
What I’m trying to achieve is to get
{
"table": "issues",
"action": "UPDATE",
"value": ####
}
in my request body, with #### containing the changed record.
It works with
PERFORM status FROM
http_post('https://example.com/receiver', to_jsonb(NEW.*));
but I want to have the action and table too.
3
Answers
The problem is less inside
json_set
, as I assumed in the question, it is more in the conjunction withhttp_post()
frompgsql-http
. If I cast thejsonb
object to text and change thathttp_post()
call to this:it works. Thank You all for helping. Zegarek, you pointed me in the right direction by You debug mechanism, which showed, taht my problem was not where I thought.
You can get the required structure with something like this:
jsonb_build_object constructs the entire JSON object in one go.
What you’re showing works ok if you’re trying to nest the new record under the
value
key:demo at db<>fiddle
If you’re trying to get a JSON version of that record, with
table
andaction
added into it, flip the arguments: don’t add the record to a JSON with the pair of keys but instead usejsonb_set()
orjsonb_insert()
twice to add them to the record.Or, concatenate
||
these together (that’s a dedicated operator for mergingjsonb
‘s, not to be confused withtext
concatenation):demo at db<>fiddle
You should be able to
to_jsonb(NEW)
without unpackingNEW.*
.