zipcompressionexist-dbrestxq

Returning a zip file from an eXist-db RestXQ call


I am working on creating a zip file of several XML documents from eXist-db. This method creates the zip file, but does not return it. I tried storing in exist, but the zip file is not the proper format. How do I get the call to return the zip file?

eXist-db version 6.1.0-SNAPSHOT. The latest pull of the JWT branch.

(:~

@param $jwt The JWT authorization token for RBAC
@param $host Tells the webserver which virtual host to use
@param $trim If true, then the empty properties in the JSON output are removed
@param $required A list of property names that are to remain during a trim even if they are empty
@return
@custom:openapi-tag Public
 :)
declare
    %rest:GET
    %rest:path("/v2/public/project/{$mapID}")
    %rest:header-param("JWT", "{$jwt}")
    %rest:header-param("Host", "{$host}")
    %rest:query-param("version", "{$version}", "latest")
    %rest:produces("application/octet-stream")
    %output:media-type("application/zip")
    %output:method("binary")
function v2pub:project-by-id(
            $jwt as xs:string*,
            $host as xs:string*,
            $mapID as xs:string*,
            $version as xs:string*
)
{
    let $login := login:authenticate($jwt)
    let $total-host := magutil:host($host)
    let $mapping := magutil:get-mapping-version($mapID, $version)
    let $mapping-entry := <entry name="" type="xml" method="store">{fn:serialize($mapping, map {"method": "xml" })}</entry>
    let $zip := compression:zip($mapping-entry, fn:false())
    return $zip
};

UPDATE:

I tried adding the following to the return

    return
<rest:response>
  <http:response status="200" message="Success">
    <http:header name="Content-Disposition" value="attachment; filename=test.zip"/>
  </http:response>
</rest:response>,
    $zip

But it is now telling me that $zip is not set.

UPDATE 2:

I was missing as item()+. The zip file is still not working though.

xquery version "3.1";

module namespace v2pub = "http://easymetahub.com/modules/ns/public/v2";

declare namespace rest="http://exquery.org/ns/restxq";
declare namespace http = "http://expath.org/ns/http-client";
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";

(:~

@param $jwt The JWT authorization token for RBAC
@param $host Tells the webserver which virtual host to use
@param $trim If true, then the empty properties in the JSON output are removed
@param $required A list of property names that are to remain during a trim even if they are empty
@return
@custom:openapi-tag Public
 :)
declare
    %rest:GET
    %rest:path("/v2/public/project/{$mapID}")
    %rest:header-param("JWT", "{$jwt}")
    %rest:header-param("Host", "{$host}")
    %rest:query-param("version", "{$version}", "latest")
    %rest:produces("application/octet-stream")
    %output:media-type("application/zip")
    %output:method("binary")
function v2pub:project-by-id(
            $jwt as xs:string*,
            $host as xs:string*,
            $mapID as xs:string*,
            $version as xs:string*
)
as item()+
{
    let $login := login:authenticate($jwt)
    let $total-host := magutil:host($host)
    let $mapping := magutil:get-mapping-version($mapID, $version)
    let $mapping-entry := <entry name="" type="xml" method="store">{fn:serialize($mapping, map {"method": "xml" })}</entry>
    let $zip := compression:zip($mapping-entry, fn:false())
    return
     (
<rest:response>
  <http:response status="200" message="Success">
    <http:header name="Content-Disposition" value="attachment; filename=test.zip"/>
  </http:response>
</rest:response>,
    $zip)
};

Solution

  • I found the fix. I was missing as item()+

    xquery version "3.1";
    
    module namespace v2pub = "http://easymetahub.com/modules/ns/public/v2";
    
    declare namespace rest="http://exquery.org/ns/restxq";
    declare namespace http = "http://expath.org/ns/http-client";
    declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
    
    (:~
    
    @param $jwt The JWT authorization token for RBAC
    @param $host Tells the webserver which virtual host to use
    @param $trim If true, then the empty properties in the JSON output are removed
    @param $required A list of property names that are to remain during a trim even if they are empty
    @return
    @custom:openapi-tag Public
     :)
    declare
        %rest:GET
        %rest:path("/v2/public/project/{$mapID}")
        %rest:header-param("JWT", "{$jwt}")
        %rest:header-param("Host", "{$host}")
        %rest:query-param("version", "{$version}", "latest")
        %rest:produces("application/octet-stream")
        %output:media-type("application/zip")
        %output:method("binary")
    function v2pub:project-by-id(
                $jwt as xs:string*,
                $host as xs:string*,
                $mapID as xs:string*,
                $version as xs:string*
    )
    as item()+
    {
        let $login := login:authenticate($jwt)
        let $total-host := magutil:host($host)
        let $mapping := magutil:get-mapping-version($mapID, $version)
        let $mapping-entry := <entry name="test.xml" type="xml" method="store">{fn:serialize($mapping, map {"method": "xml" })}</entry>
        let $zip := compression:zip($mapping-entry, fn:false())
        return
         (
    <rest:response>
      <http:response status="200" message="Success">
        <http:header name="Content-Disposition" value="attachment; filename=test.zip"/>
      </http:response>
    </rest:response>,
        $zip)
    };