Question
Mike Yackanich · Jan 13, 2021

How to set HTTP Response Status Code in httpResponse object

Hi all,

I have a passthru REST setup using EnsLib.HTTP.GenericService and EnsLib.HTTP.GenericOperation. Works well.

I am adding some logic to the Operation and for some scenarios I want to return an HTTP 40x response status code.

I create an httpResponse object within the Business Operation, but I can't figure out how to set the http response status code that is returned to my Posstman client that initiated the request. I set StatusCode=400, and StatusLine and ReasonPhrase properties - but when the ultimate requestor (Postman) receives the response back it is a 200 status code. I am quitting the OnMessage method with status of $$$OK - which I suspect is being interpreted as HTTP response status code of 200. But I thought the httpResponse.StatusCode property setting of 400 would override that (?)

So how do I control the status code of the response? Can that be done within the httpResponse object within the Business Operation? Or do I need to subclass the related Business Service?

Product version: IRIS 2020.4
00
1 0 6 174
Log in or sign up to continue

Replies

This is how we handled that in Cache 2018 for a REST connection.

s %response.Status = $$$HTTP401UNAUTHORIZED

Thanks for the feedback Don. I ended up calling WRC and was informed that a Business Service alone does not allow control of the HTTP response status code other than either 200 or 500. A CSP layer is apparently needed in order to expose %request.Status.

Hi Mike,

I have been having the same problem and could only ever return a 200 or 500 status code from my REST Business Service, so I was very disheartened to see your post that WRC said you have to CSP layer to get round this.

However, not one to give up easily, I believe I have found a solution:

I am using the EnsLib.REST.GenericServices business service class which uses the EnsLib.HTTP.InboundAdapter  adaptor class.

It appears that the EnsLib.HTTP.InboundAdapter class uses the second and remaining pieces, separated by " ", of the StatusLine header value for the returned status code.

Therefore, in my Business Process code, that returns  EnsLib.HTTP.GenericMessage back to the Business Service, I used the following lines, in the appropriate places of my code:

Set tHttpResponse = ##class(%Net.HttpResponse).%New()

Set tHttpResponse.StatusLine = "HTTP/1.1 404 Not Known"

Set response = ##class(EnsLib.HTTP.GenericMessage).%New(tResponseStream,,tHttpResponse)

Do response.HTTPHeaders.SetAt("HTTP/1.1 400 Bad Request","STATUSLINE")

Do response.HTTPHeaders.SetAt(tHttpResponse.StatusLine,"STATUSLINE")

Hope this helps.

Hi Neil,

My code was pretty much identical to what you shared above, except for the following:

Do response.HTTPHeaders.SetAt("HTTP/1.1 400 Bad Request","STATUSLINE")

I added that, but it didn't change anything.

The only other difference is that I am doing all of this in the Business Operation in that I only have and Business Service and Business Operation (no Business Process). Not sure if that would make a difference, but I'm going to put in a Business Operation and apply these changes and see if that works.

Thanks again for the investigation and idea - I'll let you know if inserting a Business Process and the related code works for me.

Hi Neil,

I'm attempting to introduce a Business Process to see if I can modify the HTTP response code there, but I wanted to ask what class you were using for the Business Process. Did you use EnsLib.MsgRouter.RoutingEngine?

Hi Mike,

I am using my own custom Business Process which creates the HTTP Response.

I am also using a Business Services, rather than a Business Operation, like you, but I'm sure the principle will be much the same.

My Business Services uses the passthrough 'EnsLib.REST.GenericServices' business service class, which passes the HTTP Request to my custom process.

The Business Process then processes the request and creates the appropriate HTTP Response which is passed back to Business Service.