Rest Method is throwing 404 when consumed in client action

Rest Method is throwing 404 when consumed in client action

  

Hi,

I'm developing a mobile application and has many screens. I don't want to use the inbuilt login mechanism, thus, created a REST method to authenticate the users from my service. I'm not sure how to delete the default login and point the HomeScreen to my login screen. Yet, I have deleted the login from common and added the controls in HomeScreen. Although it is bad, but, my login mechanism is working.

I have few REST methods consumed from an external URL. They are functioning fine when tested from the TEST mechanism and few are working fine.

I have created couple of screens and consumed them in these screens at "OnInitialize" of the screens. They are working fine, but, except at the 2nd level of the pages. On other words, WelcomePage can be considered as Level 1 page and has Names. Details Page can be considered as Level 2 page and has input parameter from the WelcomePage.

Everything is fine until the Details page getting the input parameter from WelcomePage. But, when consumed the REST Method in the Details page at OnInitialize action, i get a 404 error message.

There are multiple questions in this post.

1) How to point my LoginScreen as default login?

2) What is the best way to invoke the REST method while navigating from one page to other?

3) How to pass parameters between screens, other than input parameter?

Thanks in advance for reading till this line.

Regards

HI,

1) You have to change the Exception flows. Open the exception flow and on SecurityException and UserId = Null send to your LoginScreen.

2) It really depends on what you want to do, and when you need the information.

3) Why you don't want to use input parameters? Anyway...you can for example save information on the database on one screen and then get it on other.

Hope I could help.


Best regards,

João Nobre

Hi DSK,

Let me try and answer your questions:

1) The easiest way I can think of is to look for all references to the default login screen and replace them with references to your new screen.

2) Right click your screen and select the option shown in the image below:

This will create a new action where you can invoke your REST API.

3) If you don't want to use screen input parameters, you could store the necessary data in a Local Storage Entity.

Hi,


1) How to point my LoginScreen as default login?You can change your screen to point  at Common\OnException

2) What is the best way to invoke the REST method while navigating from one page to other?From below pageyou may find what you you want to do before and after invoke so that you should be able to capture required information before navigation is needed

https://success.outsystems.com/Documentation/10/Extensibility_and_Integration/REST/Consume_REST_APIs/Advanced_Customizations

3) How to pass parameters between screens, other than input parameter?

You can use the local storage tables to store data if need to access on other screens


Hopefully it will help you.

João Nobre wrote:

HI,

1) You have to change the Exception flows. Open the exception flow and on SecurityException and UserId = Null send to your LoginScreen.

[DSK] Yet, we are calling the GetUserId() from the system built. I understand the point of changing the condition to whatever is of my logic. The best thing that is there in my thought is to have a session variable and check for the null value of this variable. As soon the null found, move to LoginScreen. Well, the point is, when to null this value.

2) It really depends on what you want to do, and when you need the information.

[DSK] I need the call to happen when this page is redirected from another page. The calling page has a parameter as ID and the REST call has to be passed with this ID.

3) Why you don't want to use input parameters? Anyway...you can for example save information on the database on one screen and then get it on other.

[DSK] I'm not saying that I don't want to use the input parameters. I'm inquiring, if there is any other means of passing.. things like query parameters withing web application

Hope I could help.


Best regards,

João Nobre

Hi,

Thanks for the reply. Please find my situation within your message.

Regards,


Aurelio Santos wrote:

Hi DSK,

Let me try and answer your questions:

1) The easiest way I can think of is to look for all references to the default login screen and replace them with references to your new screen.

[DSK] There were about 70+ locations, where LOGIN is found within the application. Apart of this finding all and replacing, as mentioned by João, it is a good way to check the exception flow. Yet, I would like to know when to delete the value from a session variable, so that, I can check for the null value within a given session variable, and redirect to login on success. 

2) Right click your screen and select the option shown in the image below:

This will create a new action where you can invoke your REST API.

[DSK] The point is not about creating an action, but, when to invoke it. I have tried all the "OnInitialize/OnReady/OnRender" events of the given page and kept the breakpoints at start of these events. Nothing hit the breakpoint.

3) If you don't want to use screen input parameters, you could store the necessary data in a Local Storage Entity.

[DSK] This seems to be a good idea. But, how to store the value(s)? Create a duplicate structures for each REST Response type and assign them as need?

Aurelio,

Thanks for the quick response, please find within about my situation.

Regards,


Muhammad Iqbal wrote:

Hi,


1) How to point my LoginScreen as default login?You can change your screen to point  at Common\OnException

[DSK] True. But, how to validate for the given user as authenticated for each screen? I was wondering of keeping a session variable and check for the null value to authenticate. But the problem is two fold. One, when to validate this variable? In other words, at which event of every screen to check for the valid value? OnInitialize is not functioning for specific pages and i found that it is not consistence. On a second note, I'm not sure about how and when the session variables become null or will be reset to null. 


2) What is the best way to invoke the REST method while navigating from one page to other?From below pageyou may find what you you want to do before and after invoke so that you should be able to capture required information before navigation is needed

https://success.outsystems.com/Documentation/10/Extensibility_and_Integration/REST/Consume_REST_APIs/Advanced_Customizations

[DSK] I have read this information, but, the point is about the inconsistency of OnInitialize event.

3) How to pass parameters between screens, other than input parameter?

You can use the local storage tables to store data if need to access on other screens

[DSK] Yes, that's a good idea


Hopefully it will help you.

Muhammad,

Thanks for the reply. Please find my comments within to know my situation.

Regards,


DSK Chakravarthy wrote:

Aurelio Santos wrote:

Hi DSK,

Let me try and answer your questions:

1) The easiest way I can think of is to look for all references to the default login screen and replace them with references to your new screen.

[DSK] There were about 70+ locations, where LOGIN is found within the application. Apart of this finding all and replacing, as mentioned by João, it is a good way to check the exception flow. Yet, I would like to know when to delete the value from a session variable, so that, I can check for the null value within a given session variable, and redirect to login on success. 

2) Right click your screen and select the option shown in the image below:

This will create a new action where you can invoke your REST API.

[DSK] The point is not about creating an action, but, when to invoke it. I have tried all the "OnInitialize/OnReady/OnRender" events of the given page and kept the breakpoints at start of these events. Nothing hit the breakpoint.

3) If you don't want to use screen input parameters, you could store the necessary data in a Local Storage Entity.

[DSK] This seems to be a good idea. But, how to store the value(s)? Create a duplicate structures for each REST Response type and assign them as need?

Aurelio,

Thanks for the quick response, please find within about my situation.

Regards,


Hi,

Answers below:

1) Did you use the "Find Usages" option to find all references to the screen? I find it a bit odd that you have so many references to the login screen.

2) Using the option I mentioned is the recommended way to invoke a REST API that retrieves the data you need for your screen. Keep in mind that it's not just a simple client action, it's a special action that will be automatically invoked when the screen is loaded.

3) Without knowing the details of your requirements, it's hard for me to make recommendations. Do you need to store the response of a REST call and use it in a different screen? You could have a local entity that will always have just one record with the data you need.


Aurelio Santos wrote:

DSK Chakravarthy wrote:

Aurelio Santos wrote:

Hi DSK,

Let me try and answer your questions:

1) The easiest way I can think of is to look for all references to the default login screen and replace them with references to your new screen.

[DSK] There were about 70+ locations, where LOGIN is found within the application. Apart of this finding all and replacing, as mentioned by João, it is a good way to check the exception flow. Yet, I would like to know when to delete the value from a session variable, so that, I can check for the null value within a given session variable, and redirect to login on success. 

2) Right click your screen and select the option shown in the image below:

This will create a new action where you can invoke your REST API.

[DSK] The point is not about creating an action, but, when to invoke it. I have tried all the "OnInitialize/OnReady/OnRender" events of the given page and kept the breakpoints at start of these events. Nothing hit the breakpoint.

3) If you don't want to use screen input parameters, you could store the necessary data in a Local Storage Entity.

[DSK] This seems to be a good idea. But, how to store the value(s)? Create a duplicate structures for each REST Response type and assign them as need?

Aurelio,

Thanks for the quick response, please find within about my situation.

Regards,


Hi,

Answers below:

1) Did you use the "Find Usages" option to find all references to the screen? I find it a bit odd that you have so many references to the login screen.

2) Using the option I mentioned is the recommended way to invoke a REST API that retrieves the data you need for your screen. Keep in mind that it's not just a simple client action, it's a special action that will be automatically invoked when the screen is loaded.

3) Without knowing the details of your requirements, it's hard for me to make recommendations. Do you need to store the response of a REST call and use it in a different screen? You could have a local entity that will always have just one record with the data you need.


Hi Aurelio,

Thanks for your response. We can ignore the point 1 for now, as 2 is the critical issue. Please find below are the same kind of sequences from different screens

But, the Screen2 is throwing 404 at the REST call, GetActor. For the record, the method working fine, when tested. And both are OnInit of the respective screens.

What do you think would have happened here..

For the point 3, the Common Menu layout has if condition to determine whether the user is logged in or not. And the current condition is with reference to GetUserId(), now that i'm implementing my own method for authenticating, need to maintain a status for this If condition to switch between Login and Logout. I'm not sure as how can i send the value to Menu.. I have tried creating a local variable / input variable / etc, to pass the value from the button click of WelcomeScreen, but in vain

Hi DSK,

As expected, a 404 means you point to a non-existing resource. Please check Service Center to see what URL gives the 404, and see if it's the expected URL.

Kilian Hekhuis wrote:

Hi DSK,

As expected, a 404 means you point to a non-existing resource. Please check Service Center to see what URL gives the 404, and see if it's the expected URL.

If that is so, then the method it self should not be working fine when TEST run!!! but, it is not the case the REST method is successfully returning data 

Hi DSK,

I'm sorry, but you're not correct. Testing the REST and consuming it when running the application are not the same thing (just like testing an Aggregate or SQL is not by definition producing the same results as running them in the application).

So again, please check Service Center to see what the call and reply actually are, if you are at all interested in solving this.

Kilian Hekhuis wrote:

Hi DSK,

I'm sorry, but you're not correct. Testing the REST and consuming it when running the application are not the same thing (just like testing an Aggregate or SQL is not by definition producing the same results as running them in the application).

So again, please check Service Center to see what the call and reply actually are, if you are at all interested in solving this.

Thanks for following with me. The problem is not with the service .. it is working fine

Hi DSK,

Good to hear that. What was the cause?

Solution

Friends.

I have found the root cause with the help of João Martins 

The root cause is that the API call is submitted with a space within the URL as HTMLEncoded and the API is not recognising the HTMLEncoded SPACE, as it is submitted with "+" within URL

Thanks for everyone who helped me in this journey.. 


Solution

Hi Everyone, 

So I'm making a call to an external REST API. (Google Vision Library). I followed the steps described here - Consume REST API to setup the REST method. When I run it on the device, it throws a "404 Not Found". How do I go about debugging this? 


Service Center Error did not make shed more light(to me), posted below :

404 Not Found
Environment InformationeSpaceVer: 38 (Id=146, PubId=153, CompiledWith=10.0.702.0)
RequestUrl: https://bharath-kamath.outsystemscloud.com/OCRPOC/moduleservices/log?clientTimeInMillis=1510084848558 (Method: POST)
AppDomain: /LM/W3SVC/22/ROOT/OCRPOC-120-131545583265005477
FilePath: C:\OutSystems\Sandboxes\XUZTKU019\Platform Server\running\OCRPOC\
ClientIp: 199.246.228.251
Locale: en-US
DateFormat: yyyy-MM-dd
PID: 59916 ('w3wp', Started='10/3/2017 8:18:03 PM', Priv=356Mb, Virt=18077Mb)
TID: 275
Thread Name:
.NET: 4.0.30319.42000
Client-Side Log
Stack:PostImages
 Error
    at Object.a [as getException] (https://bharath-kamath.outsystemscloud.com/OCRPOC/scripts/OutSystems.js?TgkYxm38WdiNZwCb45Sl2w:1:23727)
    at XMLHttpRequest.y.onload (https://bharath-kamath.outsystemscloud.com/OCRPOC/scripts/OutSystems.js?TgkYxm38WdiNZwCb45Sl2w:3:4406)

Hi Barath,

You should check the Integration logging, and likely set the logging level of your REST API consume to max. If you do not know how to, I can post that as well (but perhaps you know, and it would take some time to explain).

Hi Kilian,


https://success.outsystems.com/Support/Enterprise_Customers/Troubleshooting/Change_OutSystems_Platform_logging_levels_(OSTrace)

Do you mean something like the above? I've not yet got around to trying this out, will give it a shot later in the day. 


 

I tried a couple other POST calls and they work fine. Only the google vision APIs are failing. The error message is " The requested URL /v1/images%3Aannotate?key=DDSzaSyCmx3cBsg7sjlw was not found on this site."

Could it be because of the X-Frame-Options? Can this even be disabled?

HTTP/1.1 404 Not Found X-XSS-Protection: 1; mode=block X-Frame-Options: SAMEORIGIN X-Content-Type-Options: nosniff Alt-Svc: quic=":443"; ma=2592000; v="41,39,38,37,35" Content-Length: 1625 Content-Type: text/html; charset=UTF-8 Date: Mon, 13 Nov 2017 14:35:59 GMT Server: ESF

I am now making this call directly via the JS widget. But would love to troubleshoot the actual issue, any inputs on how to proceed here?