Question
· Jun 1, 2016

Passing a parameter with slashes to the REST call

I need to pass a parameter string that contains slashes to a REST call.

I tried URL encoding, or making URL map to accept query parameter instead of path parameter but apparently we only allow for path parameters.

I can come with several workarounds, but these involve some transformation at client and then on server, but I'd prefer a direct support.

Q1: is there any Cache specific trick to pass slashes in path parameters

Q2: are we going to support query parameters in REST?

something like this would help: 

<Route Url="/test?var=:var" Method="GET" Call="Test" Cors="true"/>

 Dan Kutac

Discussion (18)0
Log in or sign up to continue

I have never actually tried to pass slashes as parameters, but I would guess that it should work if you encode them. I am aware that some systems drop these requests, because it is easy to inject malicious code this way.

Are you receiving a 404 and use Apache? If so, you may have to enable  the AllowEncodedSlashes directive:

http://httpd.apache.org/docs/current/mod/core.html#allowencodedslashes

Q2: It is against core REST architecture principles, so I hope not.

That is not entirely true. Filters and action descriptions are commonly exposed as URL parameters as they serve to either specify an action or limit the working set. But you are still operating on the same resource identity.

What you can observe is that REST is just a best practice leveraging HTML. You will find any possible implementation of REST interfaces out there, some are true to the original spirit, some are not.

Anyway, you can fight endless wars about REST  interfaces, but one thing is for sure: URL parameters are commonly used for REST interfaces.

To answer the original question: I don't see a need to add URL parameters to the URL map. They would only add value if we added them as method arguments, but I think that would be very confusing as path variables are passed as arguments at the moment.

You can use the %request.Data property to retrieve the URL parameters.

Hi Eduard,

I am running in the same issue as Dan and trying out your solution in assumption that there is no other better way of handling this. Overriding OnPreDispatch doesn't seem to work for me. My URL seems decoded by then.

E.g. my API URL is

http://localhost:52773/mapi/admin/v1/patients/{patientReference} where patientReference contains a slash so client call would be something like

http://localhost:52773/mapi/admin/v1/patients/ipm%2F3245678

In my OnPreDisptach pUrl is  already decoded

v1/patients/ipm/3245678 

hence your solution doesn't seem to work. Am I missing something? Is there any  other way of handling this?

Thanks,

Utsavi

What the issue you faced?

Class User.Rest Extends %CSP.REST
{

XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{
<Routes>
<Route Url="/:resource/(.*)" Method="GET" Call="GetResource" Cors="true"/>
<Route Url="/ping" Method="GET" Call="Ping" Cors="true"/>
</Routes>
}

ClassMethod Ping() As %String
{
  Write {"pong": true}.%ToJSON()
  Return $$$OK
}

ClassMethod GetResource(pResource As %String, pId As %String) As %Status
{
  Write {"resource": (pResource), "id": (pId)}.%ToJSON()
  Return $$$OK
}

}

With this REST class, I can do queries like this http://localhost:52773/rest/patient/test/123/456, with no issues it returns {"resource":"patient","id":"test/123/456"}

Thanks Dmitry:) that actually works for me too if i change my route from /patients/{patientRef} to /patients/(.*) in the dispatch class. 

My only problem now is that my api specification says the route is /patients/{patientRef} and because we are using the iris api/mgmnt api to auto generate rest classes based on Swagger specification, my dispatch class is auto generated based on .spec class. My .disp class also gets overwritten everytime my .spec class is recompiled.  Any ideas on how to get around this?

Many thanks, 

Utsavi

Thanks Dmitry:) that actually works for me too if i change my route from /patients/{patientRef} to /patients/(.*) in the dispatch class. 

My only problem now is that my api specification says the route is /patients/{patientRef} and because we are using the iris api/mgmnt api to auto generate rest classes based on Swagger specification, my dispatch class is auto generated based on .spec class. My .disp class also gets overwritten everytime my .spec class is recompiled.  Any ideas on how to get around this?

Many thanks, 

Utsavi