2

I'm extending the REST API in MarkLogic and managing my development and deployment using gradle. By default, my endpoint looks like this (note v1):

http://localhost:8005/v1/resources/my_endpoint

If I change my endpoint implementation, how do I expose the new version as v2 and keep the original (v1) for backward compatibility so that I have

http://localhost:8005/v2/resources/my_endpoint

using gradle? I don't see any way to annotate version in my gradle config files. I've been searching MarkLogic's gradle wiki and haven't found an answer there.

Mads Hansen
  • 63,927
  • 12
  • 112
  • 147

2 Answers2

1

The REST API unfortunately doesn't allow for what you want - see https://docs.marklogic.com/REST/PUT/v1/config/resources/[name] . You can specify a version as optional metadata on your extension, but that will not change the URL - it's still going to be "/v1/resources/my_endpoint".

You however can achieve this if you customize the default XML rewriter that MarkLogic uses for a REST API app server - see https://docs.marklogic.com/guide/app-dev/XMLrewriter .

rjrudin
  • 2,108
  • 9
  • 7
  • Thanks for your help @rjrudin. So as a strategy, I could have a rewriter rewrite an incoming url `/api/v2/my_endpoint` to `/v1/resources/v2_my_endpoint` and achieve what I'm looking to do? – Abhai Raj Llewellyn Jan 20 '23 at 19:47
  • Right - you can achieve pretty much anything via the declarative XML rewriter. I usually use the existing rewriter rules for examples when I'm customizing it. – rjrudin Jan 24 '23 at 14:32
1

I was able to meet requirement using a declarative rewriter as @rjrudin suggested.

I started by copying <MarkLogic install dir>\Modules\MarkLogic\rest-api\rewriter.xml to api-rewriter.xml, modifying the new file, and updating my rest api server Url Rewriter value (via Admin console).

Then I added the following declarations:

<match-path matches="^/api">
    <match-method any-of="GET">
        <match-path matches="/(v\d+\.\d+)/([\w|\-]+)/(\d+)">
            <set-query-param name="name">$1_$2</set-query-param>
            <set-query-param name="rs:id">$3</set-query-param>
            <dispatch>/MarkLogic/rest-api/endpoints/resource-service-query.xqy</dispatch>
        </match-path>
        <match-path matches="/(v\d+\.\d+)/(\w+)">
            <set-query-param name="name">$1_$2</set-query-param>
            <dispatch>/MarkLogic/rest-api/endpoints/resource-service-query.xqy</dispatch>
        </match-path>
    </match-method>
</match-path>

I create resource implementations using ml-gradle with names that look like this: v2.0_ping.sjs. So now I can use urls like this:

http://{{host}}:{{port}}/api/v2.0/ping

that resolve to

/MarkLogic/rest-api/endpoints/resource-service-query.xqy?name=v2.0_ping
  • Note that you can load that rewriter by storing it under src/main/ml-modules and configuring your app server - via a file under src/main/ml-config/servers - to reference it. That avoids the manual step of adjusting the rewriter URL via the Admin UI. – rjrudin Jan 23 '23 at 12:36
  • 1
    Thanks @rjrudin! That was my next question :-) – Abhai Raj Llewellyn Jan 23 '23 at 13:55