HTTP Status while consuming REST

HTTP Status while consuming REST

  

How do I get the HTTP Response Status Code while consuming a REST service?

Hi Vinay,

Add a OnAfterResponse to the REST service (REST API properties, On After Response, New OnAfterResponse). The OnAfterResponse has a parameter Response, which is of type HTTPResponse, which has an attribute StatusCode.

Kilian Hekhuis wrote:

Hi Vinay,

Add a OnAfterResponse to the REST service (REST API properties, On After Response, New OnAfterResponse). The OnAfterResponse has a parameter Response, which is of type HTTPResponse, which has an attribute StatusCode.

Thanks Kilian for the reply.

I can find the Status property in the On After Response callback, but I cannot find a way to pass that property outside the callback. The callback doesn't have any local variables in scope that I can modify to expose the Response information outside it. 

What I need is for my REST method to return back the HTTP status as an Output.


Solution

Hi Vinay,

Note that if the response is an error response (e.g. 400), the Platform will trigger an exception, so you can't pass the code in a meaningful way. Also, it's not your REST method, you call someone else's REST method. What you seem to want is for the result of the REST method you call to be passed to the caller of the REST method.

If that is indeed what you want, you can either introduce a session variable that you set to the status code (I'm not entirely sure that works, the OnAfterResponse may run in a different session), or manipulate the output JSON (assuming the method returns JSON) to include the status code (the full JSON payload is in the ResponseText attribute). Also, set the status code of the CustomizeResponse to 200 to prevent the exception handler kicking in.

Solution

Kilian Hekhuis wrote:

Hi Vinay,

Note that if the response is an error response (e.g. 400), the Platform will trigger an exception, so you can't pass the code in a meaningful way. Also, it's not your REST method, you call someone else's REST method. What you seem to want is for the result of the REST method you call to be passed to the caller of the REST method.

If that is indeed what you want, you can either introduce a session variable that you set to the status code (I'm not entirely sure that works, the OnAfterResponse may run in a different session), or manipulate the output JSON (assuming the method returns JSON) to include the status code (the full JSON payload is in the ResponseText attribute). Also, set the status code of the CustomizeResponse to 200 to prevent the exception handler kicking in.

Thanks Kilian for the lucid answer. Helps me very much.

Seems like Outsystems doesn't sit well with exposing the internals of the REST service, I need to rethink my application logic and try to use the default Error Handling, instead of doing it manually. 


Well, OutSystems wants to hide the gritty details from the average user, while allowing manipulating stuff in the OnBeforeRequest and OnAfterResponse handlers. That works pretty well in most cases, imho.

Btw, if you're satisfied with my answer above, please mark it as resolved (and also Like my post(s) :)).

Hello guys,


I'm actually working on consuming RESTful APIs from OutSystems. Let me walk you through the example I put up...

Imagine you have an API to manipulate users. For the sake of simplicity, I'll just go with GET /users/{UserId}



Practitioners of RESTful state that you should return a 404 if the user is not found. That's easily achievable in OutSystems...



How about the consumer? That's where the architecture part comes into play. If you follow the 4 Layer Architecture practices, you'll notice that you should wrap the external services in actions, and provide that to the upper layers to consume. What I did while consuming this GET /users/{UserId} was just that. In the OnAfterResponse of my consumer, I check the status code and I raise an exception based on the status code.

But this method has no context on what's being done right? But I have a wrapper to this method, so I handle the exception there...



Let me know what you think.


Seems a good way to approach this. I'm not sure though what kind of exception is thrown when you do not handle the response but just let the Platform handle it. Is it a generic exception without any indication of the status code (sorry, too lazy to check)?

Yes, just a generic exception, with the bare minimum details. The fact that EVERY REST service needs the implementation Pedro describes to properly handle the HTTP status code errors that REST services use is a sign that the system needs improvement.

J.Ja

Justin James wrote:

What improvements would you like to see there Justin?

Yes, just a generic exception, with the bare minimum details. The fact that EVERY REST service needs the implementation Pedro describes to properly handle the HTTP status code errors that REST services use is a sign that the system needs improvement.

J.Ja



Pedro Cardoso wrote:

Justin James wrote:

What improvements would you like to see there Justin?

Yes, just a generic exception, with the bare minimum details. The fact that EVERY REST service needs the implementation Pedro describes to properly handle the HTTP status code errors that REST services use is a sign that the system needs improvement.

J.Ja




Pedro -

We need:

1. A way of accessing the response body from an exception handler.

2. Exceptions for each different HTTP status code.

This all because of two fundamental REST concepts:

* HTTP status code actually indicate application state, not infrastructure state; for example, GET /users/789 cn throw a 404 indicating that there is no record with the ID of 789... and 403 or 403 might mean "you do not have access to write to that record". This means that HTTP status codes need to be handled VERY granularly, and the typical behavior of just throwing the exception on the screen via FeedbackMessage isn't good enough.

* Many times a non-200 reponse code will be given indicaing an error, but the error details are in the respnse body, typically in JSON representing an error. The current system just gives a Session.Exception message like "File not found" or whatever that doesn't help me actually fix the issue.


J.Ja

^This. +1

Hey Justin, thanks for the reply!

Showing a feedback message was a simple example of making the exception flow to the user. If this would be a machine-to-machine integration, you probably want to deal with those in a different manner. 

The big statement here is that you can handle the exceptions in the OnBeforeRequest and wrap your logic to provide meaningful output to the upper layers. Besides the need to deal with status codes, one should always do this, so that changes in the producer don't affect others, than the direct consumer, of course, up to a certain degree.

In terms of what you refer as needed, at least for status codes, it could actually be good! I'll discuss it here with some guys.


Justin James wrote:

Pedro Cardoso wrote:

Justin James wrote:

What improvements would you like to see there Justin?

Yes, just a generic exception, with the bare minimum details. The fact that EVERY REST service needs the implementation Pedro describes to properly handle the HTTP status code errors that REST services use is a sign that the system needs improvement.

J.Ja




Pedro -

We need:

1. A way of accessing the response body from an exception handler.

2. Exceptions for each different HTTP status code.

This all because of two fundamental REST concepts:

* HTTP status code actually indicate application state, not infrastructure state; for example, GET /users/789 cn throw a 404 indicating that there is no record with the ID of 789... and 403 or 403 might mean "you do not have access to write to that record". This means that HTTP status codes need to be handled VERY granularly, and the typical behavior of just throwing the exception on the screen via FeedbackMessage isn't good enough.

* Many times a non-200 reponse code will be given indicaing an error, but the error details are in the respnse body, typically in JSON representing an error. The current system just gives a Session.Exception message like "File not found" or whatever that doesn't help me actually fix the issue.


J.Ja



Pedro -


The problem as I see it is that you almost *always* need to do all of that work, even if you are using Feedback Message, because the Session.Exception message is useless in REST calls. :(


J.Ja

That is fair enough Justin. I can see that happening also. If we're consuming an API that is well behaved, in terms of status code, the consumer code to handle those will always be the same. And we as OutSystems developers hate the monkey code ;)

If the APIs are not that well behaved, then we could tweak a default implementation of the thing...

Disclaimer: These are just some random thoughts, not a promise of any kind!