Hi Mike,
o Am I fooling myself that creating a server side .xq file is going to perform better than building a completed query on the client and sending that via REST without "variables"?
Indeed it’s always recommendable to bind variables to a static expression instead of concatenating query strings (no matter if you are using our client bindings or REST). In terms of performance, there shouldn’t be any difference in BaseX, but your APIs will definitely be more robust and less prone to errors in the long term. Moreover, there’s no chance of query injection if you pass on dynamic user values.
o Is there a way to perform the equivalent "prepare/execute" method from the client without creating a .xq file on the server?
The usual way to go would be to pass on variables via the POST method and the <variable> elements. I see you have already found this alternative in our documentation.
o Can anyone suggest how I can get the server side .xq file to work?
First I thought “yeah, should be trivial”, then I noticed that I also stumbled upon the "no context found" error message. This is what I did:
URL: http://localhost:8984/rest/db?run=test.xq&driver=abc&contributor=def
XQUERY: declare namespace zss = 'your-zss-namespace-uri'; declare variable $driver external; declare variable $contributor external; delete node /zss:driver[@name=$driver]/zss:part[@contributor=$contributor]
To get this work, I had to include the database in the query:
URL: http://localhost:8984/rest?run=test.xq&driver=abc&contributor=def
XQUERY (in the server webapp directory): declare namespace zss = 'your-zss-namespace-uri'; declare variable $driver external; declare variable $contributor external; delete node db:open($db) /zss:driver[@name=$driver]/zss:part[@contributor=$contributor]
The database could obviously be passed on as query parameter as well.
I’ll send you another mail once I have found out why it’s not possible anymore to access the currently opened database inside your query.
However, I’d like to add another question to your three:
o Are there better ways to do this?
Yes: use RESTXQ :) It may take some more time to understand how it’s working, but it will allow you to specify much nicer APIs than REST.
Here is how your previous example would look like with RESTXQ:
URL (use the DELETE Method to delete data...): http://localhost:8984/db/abc/def
XQUERY (in the server webapp directory):
declare namespace zss = 'your-zss-namespace-uri'; declare %updating %rest:path("{$database}/{$driver}/{$contributor}") %rest:method("DELETE") function local:delete( $database as xs:string, $driver as xs:string, $contributor as xs:string ) { delete node db:open($database) /zss:driver[@name=$driver] /zss:part[@contributor=$contributor] }; ()
Hope this helps Christian