POST Not working for REST API - Method not found Error

Hello Community,

Hope someone can assist me to POST a JSON to the below URL. It works perfectly with POSTMAN. But when trying with cache/Ensemble i receive Method not found error

Below is the configuration.

 

      set ..Adapter.ContentType="application/json"
      Set tURL=..Adapter.URL
      Set pRequest={"name":"abc1jim23","salary":"123","age":"23"}
      set tSC=..Adapter.PostURL(tURL,.tHTTPResponse,,pRequest)
 

Response is complaining about the Method not found Http error. 

Assistance will be appreciated.

Thanks,

Jimmy Christian.

  • 0
  • 0
  • 137
  • 6
  • 1

Answers

Hi Jimmy,

I don't use Ensemble , but maybe the 4th parameter is not in the right format : see doc(https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=EHTTP_outbound#EHTTP_C7322547) :

The pData argument is an array. The top node of the array is not used. Each subnode is subscripted by the index of the corresponding form variable in the pFormVarNames list. The value at a given subscript should be specified as follows:

  • For a form variable (varname) with a single value, the value at pData(“varname”) should be the form data value to send. There should be no subnodes.

  • For a form variable (varname) with multiple values, the value pData(“varname”) should be the count of the values. Each of the values for this form variable should appear in a subnode, subscripted by its position in the node.

  • To send a request body instead of form variables, leave pFormVarNames empty and pass the body text as the pData argument.

So, can you try to call the PostURL with pRequest.%ToJSON()

In Caché - using %Net.HttpRequest - it works like this :

Set objHttpRequest = ##class(%Net.HttpRequest).%New()
Set objHttpRequest.ContentType = "application/json"
Set objHttpRequest.Server = "dummy.restapiexample.com"
Set pRequest = {"name":"abc1jim23","salary":"123","age":"23"}
Do objHttpRequest.EntityBody.Write(pRequest.%ToJSON())
If objHttpRequest.Send("POST", "/api/v1/create") {
Set objHttpResponse = objHttpRequest.HttpResponse
If $IsObject(objHttpResponse.Data) {
     Set objStream = objHttpResponse.Data
     Set json =""
     While ('objStream.AtEnd) {
          Set json = json _ objStream.ReadLine()
     }
Else {
     Set json = objHttpResponse.Data
}
Set httpStatus = objHttpResponse.StatusCode
Write "Status : ",httpStatus,!
Write "Response : ",json,!
}

 

Thank you Danny for help.

Yes this worked. I did not create a seperate HttpRequest but just used the PostURL method as below.

Set tSC=..Adapter.PostURL(tURL,.tHttpResponse,,pRequest1.%ToJSON()).

The code you provided is very helpful. Especially when i have to include the content type while making the http request.

The Adapter object does not have that ContentType property.

By the way i am also trying to understand when to use the PostURL or .Send or SendFormDataArray method to make a http request?

Do they provide same functionality ? If you have information and can provide me will be much appreciated.

Thank you

Jimmy Christian.

Hi Jimmy,

I think the Send* methods have an extra argument where you can specify the REST type (GET, PUT or POST), and the methods with the Get, Put or Post in the names are just shortcuts that internally call the Send method. (This is true in the %Net.HttpRequest class, so i guess it is the same in the adapter)

The SendFormDataArray and SendFormDataUrl have also an extra argument where you can pass  a %HttpRequest instance. So you could create this instance to pre-populate properties that are not possible to set using the adapter, like the ContentType property.

Set objHttpRequest ##class(%Net.HttpRequest).%New()
Set objHttpRequest.ContentType "application/json"
Set tSC=..Adapter.SendFormDataURL(tURL,.tHttpResponse,"POST",objHttpRequest,,pRequest1.%ToJSON()).
 

I haven't tested this code (don't have Ensemble) but looking at the docs it should work.

Good Morning Danny,

I appreciate your help. After  changing the names i was able to  make the POST calls using SEND. Worked perfectly ! Thank you for your time.

Yes,  looks like .Send has some more configurable parameters in the HttpRequest object we send.

In the same context, would you be able to know how to set a Basic Authoriztion using User and Pass while making the call ?

Seems like i have to make Credentials using ENSEMBLE.

Than set the httprequest.username and httprequest.password using that credential object.

Please let me know if you have any information.

Thank you for time.

Regards,

Jimmy Christian.