Well this was a voyage of discovery!

In an attempt to avoid a "rest of the owl" situation I'll show my working out and try and keep it brief.

The problem was I'd read the tool tip for CreateBusinessService and thought the first part was a description but, in fact, it requires an actual Business Service name.

For this I needed to extend Ens.BusinessService with my own.

Class RESTful.RESTfulBusService Extends Ens.BusinessService
{
Property TargetName As %String(MAXLEN = 200);
Parameter SETTINGS = "TargetName:Basic:selector?multiSelect=0&context={Ens.ContextSearch/ProductionItems?targets=1&productionName=@productionId}";
Method OnProcessInput(pInput As %Library.RegisteredObject, pOutput As %Library.RegisteredObject) As %Status
{ Set SC =..SendRequestSync($piece(..TargetName,",") ,pInput, pOutput, 0, "") Quit $$$OK
}
}

Creating that in the Management Portal -> Ensemble -> Configure -> Production as a new Business Service called "RESTfulURLService".

Also (for completeness) I needed to extend request and response for my messages.

Class RESTful.REST2BPRequest Extends Ens.Request
{
Property UUID As %String(MAXLEN = 20);
Property PatNum As %String(MAXLEN = 20);
Property CareType As %String(MAXLEN = 100);
}
Class RESTful.REST2BPResponse Extends Ens.Response
{
Property ResponseURL As %String(MAXLEN = 2500);
}

The final Dispatch Class code then looks like this:

Class RESTful.Dispatch Extends %CSP.REST
{ XData UrlMap
{
<Routes>
<Route Url="/QueryString" Method="GET" Call="ProcessQueryString" />
</Routes>
}
ClassMethod ProcessQueryString(pRequest As RESTful.REST2BPRequest, pResponse As RESTful.REST2BPResponse) As %Status
{
Set tSC = $$$OK if 'tSC QUIT tSC
Set pRequest = ##class(RESTful.REST2BPRequest).%New()
Set pRequest.UUID = $Get(%request.Data("UUID",1))
Set pRequest.PatNum = $Get(%request.Data("PATID",1))
 
Set pRequest.CareType = $Get(%request.Data("CareType",1)) Set tSC = ##class(Ens.Director).CreateBusinessService("RESTfulURLService",.tService)
If $$$ISERR(tSC)
{
     write $System.Status.GetErrorText(tSC), !
     quit tSC
}
Set targetName = "BPReturnURL" //The name of the Business Process I want to call
Set timeout = 30
Set description = "Call to get URL" If ($IsObject(tService))
{
Set tSC = tService.SendRequestSync(targetName, pRequest, .pResponse, timeout, description)
Else {
WRITE "No Object"
}
Set %response.Redirect = pResponse.ResponseURL Quit $$$OK
}
}

The Business Process BPReturnURL accepts my extended Request class and responds with the extended Response class.

This is my first post Eduard so I'm not sure what the etiquette is. Should I mark your post as correct as it lead me to realise where the problem was or this one as it contains the working code?

Either way thanks for pointing me in the right direction.

Many thanks for the fast response Eduard.

I should point out I don't have a lot of InterSystems coding experience but I do have a fair amount of general programming experience.

"Check that tSC is not an error"

I'm not sure I fully understand what you're saying by that, however that might not be an issue because:

If ($IsObject(tService))
{
Set tSC = tService.SendRequestSync(targetName, message, .response1, timeout, description)
} Else {
WRITE "No object"
}

Returns "No object" which looks like a smoking gun to me.

So given I've been working from examples that use tService but don't show how to create the object do I need to programatically create it as an object and if so how?

Yeah like I said I don't have a lot of InterSystems coding experience but the guy who does is off!