I'm looking at this example from: https://docs.marklogic.com/10.0/rest:matching-request
Specifically, this code:
xquery version "1.0-ml";
import module namespace rest="http://marklogic.com/appservices/rest"
at "/MarkLogic/appservices/utils/rest.xqy";
declare option xdmp:mapping "false";
let $options :=
<options xmlns="http://marklogic.com/appservices/rest">
<request uri="^/shakespeare/(.+)/(.+)" endpoint="/redirect.xqy">
<uri-param name="__ml_redirect__">/$1/$2</uri-param>
</request>
<request uri="^/shakespeare/(.+)" endpoint="/redirect.xqy">
<uri-param name="__ml_redirect__">/$1</uri-param>
</request>
<request uri="^/(.+)/act(\d+)" endpoint="/endpoint.xqy">
<uri-param name="play">$1.xml</uri-param>
<uri-param name="act" as="integer">$2</uri-param>
<param name="scene" as="integer" values="1|2|3" default="1"/>
</request>
<request uri="^/(.+)$" endpoint="/endpoint.xqy">
<uri-param name="play">$1.xml</uri-param>
</request>
<request uri="^/(.+)$" endpoint="/delete.xqy">
<http method="DELETE"/>
<param name="reason" required="true"/>
</request>
<request uri="^(.+)$" endpoint="/options.xqy" user-params="allow">
<uri-param name="__ml_options__">$1</uri-param>
<http method="OPTIONS"/>
</request>
</options>
let $uri := "/shakespeare/hamlet"
let $accept := xdmp:get-request-header("Accept")
let $params := map:map()
return rest:matching-request($options, ("uri","method"))
Now, I would have thought that the match would be:
<request uri="^/shakespeare/(.+)" endpoint="/redirect.xqy">
<uri-param name="__ml_redirect__">/$1</uri-param>
</request>
But, instead, the match is:
<request uri="^/(.+)$" endpoint="/endpoint.xqy">
<uri-param name="play">$1.xml</uri-param>
</request>
The reason that I'm asking is that I would like to come up with a rule for this expression, which is actually good regex: ^(\/openapi\/.+.yml)$
However, for 1) that regex is invalid according to MarkLogic, but ^(/openapi/.+.yml)$
is valid, and 2) if /shakespeare/hamlet
doesn't match ^/shakespeare/(.+)/(.+)
, then I don't understand what the regex is supposed to be that would match it.
I believe the issue is that when you are executing the code to test in Query Console, it is using the URI of your Query Console request: /qconsole/endpoints/evaler.xqy
.
The code example is a little confusing, because it has let $uri:= "/shakespeare/hamlet"
, but that $uri
is not used. I believe the intent was to show you what the request URI would be, and then demonstrate how the rest:matching-request()
function would behave.
You can verify that the URI is indeed /qconsole/endpoints/evaler.xqy
by executing this:
import module namespace rest="http://marklogic.com/appservices/rest"
at "/MarkLogic/appservices/utils/rest.xqy";
let $options :=
<options xmlns="http://marklogic.com/appservices/rest">
<request uri="/qconsole/endpoints/evaler.xqy" endpoint="/redirect.xqy">
<uri-param name="__ml_redirect__">/QUERY-CONSOLE-TEST</uri-param>
</request>
</options>
return rest:matching-request($options, "uri")
Also, if you configure an invalid regex, the error message for the matches()
will reveal what the actual URL is:
import module namespace rest="http://marklogic.com/appservices/rest"
at "/MarkLogic/appservices/utils/rest.xqy";
let $options :=
<options xmlns="http://marklogic.com/appservices/rest">
<request uri="\/" endpoint="/redirect.xqy">
<uri-param name="__ml_redirect__">INVALID-REGEX-TEST</uri-param>
</request>
</options>
return rest:matching-request($options, "uri")
returns:
[1.0-ml] XDMP-REGEX: (err:FORX0002) fn:matches("/qconsole/endpoints/evaler.xqy", attribute{fn:QName("","uri")}{"/"}) -- Invalid regular expression
You can look under the covers and see how the rest module calls rest-impl.xqy methods and perform tests using the implementation functions:
declare namespace rest="http://marklogic.com/appservices/rest";
import module namespace rest-impl="http://marklogic.com/appservices/rest-impl"
at "/MarkLogic/appservices/utils/rest-impl.xqy";
let $options :=
<options xmlns="http://marklogic.com/appservices/rest">
<request uri="^(/openapi/.+.yml)$" endpoint="/redirect.xqy"/>
</options>
let $reqenv := rest-impl:request-environment()
let $_ := map:put($reqenv, "uri", "/openapi/foo.yml")
return
rest-impl:matching-request-wrapper($options/rest:request, $reqenv, "uri")
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.