REST API Request Logging
I am working on my first REST operation to send a API Request to an internal server within our Network. I have finally got past the point of being able to connect using a SSL/TLS Configuration, but I am getting a ERROR <Ens>ErrHTTPStatus: Received non-OK status 403 from remote HTTP server: 'HTTP/1.1 403 Forbidden'.
I have tried using $$$TRACE within my operation to capture the different elements that are being sent to verify the Server, URL, SSL Configuration, and payload. Is there a way that I can see the entire RAW request message that is being sent to see why I might be getting a 403 error in response? What is the best way to go about logging the request message to the trace viewer that has the Header and Data elements?
for example using POSTMAN I can see the following.....
POST xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Host: xxxxxxxxxxxxxxxxxx
Epic-Client-ID: xxxxxxxxxxxxxxxxxxxxxx
Proxy-Connection: keep-alive
Accept: application/json
Content-Type: application/json
Authorization: Basic xxxxxxxxx
Content-Length: 119
{"PatientID":"x","PatientIDType":"xxxxxxx","ContactID":"x","ContactIDType":"xxxx","UserID":"xxxx","UserIDType":"xxxxxxx"}
and it sends a response with the same variables that I am using in the Operation, I just want to verify what is being sent in the RAW request to see if I can track down the 403 error.
I get the following response in postman, which is what I expect because I know I didn't send a correct Identifier.
{"Message":"An error occurred while executing the command: NO-PATIENT-FOUND details: No patient was found with the provided ID and ID type..","ExceptionMessage":"An error occurred while executing the command: NO-PATIENT-FOUND details: No patient was found with the provided ID and ID type..","ExceptionType":"System.Web.HttpException","StackTrace":null}
I would like to see if I can get both the RAW request message and the entire response if it is an error to display in the trace viewer.
Thanks
Comments
Does the user you're using to access the API have proper permissions to use the API and the tables that it accesses?
I am able to call the API without any issues using POSTMAN using the same username/password.
Hi Scott! What application are you using to send the POST call? Is it a web application? IRIS?
IRIS
The issue was with the Custom Header field I needed for connecting to Epic.
Assuming you are using EnsLib.HTTP.OutboundAdapter, you can do this:
1. In your adapter set DEBUG flag to 1 or 2:
/// This is the debug flag setting (0 do nothing, 1 show request, 2 show request/response)Parameter DEBUG As%Integer = 1;
I have tried that but still unable to see the Request or Response being sent...
Class User.REST.Epic.EpicOperation Extends (EnsLib.REST.Operation, Ens.Util.JSON)
{
Parameter DEBUG As %Integer = 2;
Parameter INVOCATION = "Queue";
Method getPatientLocationRequest(pRequest As User.REST.Epic.Msg.GetPatientLocationRequest, Output pResponse As EnsLib.HTTP.GenericMessage) As %Status
{
set tSC = $$$OK
try{
set tHTTPRequest = ##class(%Net.HttpRequest).%New()
do tHTTPRequest.SetHeader("Epic-Client-ID","ed7ca30e-c16a-4053-9233-bff4f5661bb4")
$$$TRACE("HttpRequest: "_tHTTPRequest) <this returns me just a pointer 8@%Net.HttpRequest>
set tRequest = ##class(%DynamicObject).%New()
set tRequest.PatientID = pRequest.PatientID
set tRequest.PatientIDType = pRequest.PatientIDType
set tRequest.ContactID = pRequest.ContactID
set tRequest.ContactIDType = pRequest.ContactIDType
set tRequest.UserID = pRequest.UserID
set tRequest.UserIDType = pRequest.UserIDType
set reqMsg = tHTTPRequest.EntityBody.Write(tRequest)
$$$TRACE("reqMsg: "_reqMsg)
set tSC = tHTTPRequest.EntityBody.Write(tRequest.%ToJSON())
set tURL = ..Adapter.URL
set tSC = ..Adapter.Post(tURL)
set stream = "".....
You need to set
Parameter DEBUG As%Integer = 2;in adapter, not in BO.
You'll get output on the current IO device (that's why you need to run BO in Foreground Mode), when your code gets to this line:
set tSC = ..Adapter.Post(tURL)I enabled DEBUG = 2 on EnsLib.HTTP.OutboundAdapter, but I am still not seeing the entire Request message being sent within the Foreground display that pops up when I execute the Test.
.png)
I was able to $$$LOGINFO(tHTTPRequest.OutputHeaders()) and verified that the header segment is being sent, but it is still throwing a 403 Forbidden error back at me.
Could you try DEBUG=1 please?
I think 1 is to show request and 2 is to show response.
.png)
Does the error mean that I can't do just a POST, I need to use SendFormArray?
.png)
Here is my Test code...
When you use DEBUG=1 the request is not actually sent, just displayed, so you get downstream errors, ignore them.
First you need to check your request with DEBUG=1, verify that everything is okay and after that switch to DEBUG=2.
With DEBUG=2 the request is sent (but not displayed) and you get response back (which would be displayed).
Also you need to pass your tHTTPRequest as pHttpRequestIn (using Send* methods of the adapter) - as currently none of your headers are sent.
Not sure I follow... I do all the SetHeader lines, then call Do tHTTPRequest.EntityBody.Write() is that not writting the headers to tHTTPRequest?
do tHTTPRequest.EntityBody.Write()
do tHTTPRequest.OutputHeaders()
set tURL= "/../../../../" //..Adapter.URL
set jsonRequest = {"........."}
SET tSC = tHTTPRequest.EntityBody.Write(jsonRequest.%ToJSON())
set tHTTPResposne = ##class(%Net.HttpResponse).%New()
do tHTTPRequest.OutputParams()
set tSC = ..Adapter.SendFormDataArray(.tHTTPResposne,"POST",,,tHTTPRequest)It is setting headers, yes. But in your previous sample code you were using ..Adapter.Post method which does not take tHTTPRequest.
💡 This question is considered a Key Question. More details here.