Context
I have a server which has a bunch of routes which may take a json body as an input and may answer with a json response as an output, and I want to quickly test these routes and various combinations of them.
The commands I am using manually look like :
curl -H "Content-Type:application/json" -d @- http://$HOST:$PORT/route1 | jq
I want to be able to compose these routes, piping them. Currently, I use a small script ./jqr which looks like :
case $1 in route1) jq 'filter_input_route1' | curl -H "Content-Type:application/json" -d @- http://$HOST:$PORT/route1 | jq ;;# ...
And can be used like this :
./jqr route1 < share_example_a.json | jq 'some_manual_processing'
Which is better but far from perfect.
Problem
Ideally, I would like to extract the curl invocation in a jq function rather than in a shell program, so as to be able to do
jq 'route1|some_manual_processing'< share_example_a.json
It may not look like much, but in addition to save alternating calls of jq and ./jqr, piping and copying is a lot more powerful in jq than in bash. Say I have routes add
and disable
with no output and a route list
with no input, I could do things like :
echo '{"name":"toto","enabled":true}' | jq 'route_add,route_list|.[]|select(.name=="toto")'
jq 'route_list|.[]|select(.name=="toto")|route_disable'
Where def filter_input_route_disable : {"id":.id}
What I tried and looked up
Again, because piping and copying is much more convenient in jq than in bash, making a wrapper script around jq to augment its capabilities seems highly impractical and time consuming.
jq 's manual, while otherwise very thorough, is very indigent when it comes to custom functions and modules. I did manage to find some other sources to learn how to write them, but during my testings in jq-1.6
, I didn't manage to shell out from a jq custom function.
It seems to be a popular feature request more than a decade old, approved by stedolanhttps://github.com/jqlang/jq/issues/147which still wasn't implemented somewhat recentlyhttps://github.com/jqlang/jq/issues/1101. I assume there are privilege issues involved : https://github.com/jqlang/jq/pull/1005. Additionally, there might be issues with order of operations and (a)synchronicity, maybe jq language makes assumptions not compatible with what I want to do, and maybe it would not work well with awaiting results from a network request, I really have no clue.
One possible solution might be to write a jq function in C rather than in jq, like some built-in functions are, but I have no idea where to start.
Am I going the right way about my issue or am I having an XY problem ?
Subsequent questions
Assuming a crude combination of curl and jq is the right way, is there anything I am missing ? Like a jq version or fork capable of shelling out ?
Assuming I didn't miss anything, is it worth attempting to write jq custom functions in C ? Like would it take more than a handful easy lines per route, and less than an hour of constant overhead, learning and setting things up ?