233
Views
10
Comments
Solved
REST API Calls/Response not consistent
Question
Application Type
Reactive
Service Studio Version
11.53.0 (Build 60495)

I'm a newbie to outsystems and currently validating some fundamental features so we can decide which low code system we should go for.

I am trying a simple test case of fetching location details based on a Zip code. The API provider is zipcodebase.com, I'm using the free version and well within the limits of the API calls that I can make. 

This is the API call where I replace the {zip} & {country} at runtime from my form. 

https://app.zipcodebase.com/api/v1/search?codes={zip}&country={country}

So if I fire this call from Postman with my API key with various Zip codes within Sweden for example, 100% of the API calls receive a proper response. Sample response below...

So I create a Single REST API method in the Studio, pass the API Key in the Header (as done in Postman), the Zip and the Country as URL parameters (as done in Postman). Test the API Call (in the Studio) with 16252 as Zip Code and SE as the Country for Test Parameters & I get a nice similar response as above. 

Then I publish the project, in the screen type 16252 as the Zip Code (Country as "SE" is hardcoded in the Parameter for now) see below.

I again get a nice response and all the fields are populated correctly...

Next I try with a Zip code of Pizza place in Kalmar, I get a response that's empty and the subsequent error message in the action flow!

I tested the same Zip code immediately with Postman and Postman returns a nice response with all the details (as seen in the 1st screenshot).

In the Service Centre, I see the error below for REST (Consume).

Failed to parse response of the method 'GetSearch' of the 'Zipcodebase' REST API:
Parsing 'results': Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'ssTestREST.CcZipcodebase+RESTResult' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly. To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array. Path 'results', line 1, position 55.

Which tells me that OutSystems was not able to parse the response message since the message format returned for Zip code 39239 was different or EMPTY. 

Question is Zipcodebase API is consistent in returning proper response when working with Postman, what happens when Outsystems REST API calls the same end point but shows empty response for specific random Zip codes so one time it works, the other time it doesnt? 

Any help will be appreciated!

Some more details...


Thanks and regards,

SG

2021-06-02 20-50-04
Márcio Carvalho
Solution

The structure is wrong somehow, I tested in service studio and then I clicked in copy response to body and then I click on finish and now is returning. You need to see a global structure that will work for any case.

But now you know the reason.

EDIT: I think I found the error

I think it's because of the name in JSON, that's why it works one time and doesn't work the second time.

Even the response structure already says that the set of lists will be separated by each code, and the code will be always the name in JSON. But yeah, as @Dorine Boudry  said, you need to parse or manipulate the response after response.


2021-06-02 20-50-04
Márcio Carvalho

Try to copy the response body from the postman and created a structure based on the JSON provided. Then use that structure as the data type for the deserialize. The structure and the output from the API must match! :)

To create the structure based on JSON, go to the DATA tab and go to the folder structures

 and right-click

PS: The structure will not be created if there are null fields from the response body.


Let me know if it helps or if I am just wrong :D

Kind Regards,

Márcio

UserImage.jpg
AFUIS AB

Hi Marcio,


Thanks for the prompt reply! Yes, I do have proper data structure matching with the response. See my update below please.

Thanks and regards,

SG

UserImage.jpg
AFUIS AB

Further update:

I tapped into OnAfterResponse and Logged the ResponseText to OS Log. I see some problems here! for both Good and Bad Zip Code i.e. Responses, Zipcodebase.com does return a proper response with correct information. I copied the JSON to a file and validated both of them, they are good...

Also below, the OS response to the Bad Zip Code request above in DevTools:

So it seems somewhere between when the Correct Response is received from Zipcodebase and sending the response to the App, OS is going in a wrong direction and setting the response Empty as above?

I'm now out of ideas at this point!

2021-06-02 20-50-04
Márcio Carvalho

From OutSystems I am getting data with your inputs


{

  "query": {

    "codes": [

      "39239"

    ],

    "country": "SE"

  },

  "results": {

    "39239": [

      {

        "postal_code": "392 39",

        "country_code": "SE",

        "latitude": "56.66160000",

        "longitude": "16.36160000",

        "city": "Kalmar",

        "state": "Kalmar",

        "city_en": "Kalmar",

        "state_en": "Kalmar",

        "state_code": "H",

        "province": "Kalmar",

        "province_code": "0880"

      },

      {

        "postal_code": "39239",

        "country_code": "SE",

        "latitude": "0.00000000",

        "longitude": "0.00000000",

        "city": "Kalmar",

        "state": "Kalmar",

        "city_en": "Kalmar",

        "state_en": "Kalmar",

        "state_code": null,

        "province": null,

        "province_code": null

      }

    ]

  }


}

Try to debug, if when you get the data from the API if you are assigning somewhere else and the data is getting lost.

UserImage.jpg
AFUIS AB

Hi Marcio,

Yes, my calls work out same when tested via the Studio but the issue arises when I execute it via the Web App.

Attached is the OML devoid of the API Key. Please update with yours and it should be good to run...

Test Zip codes : 

16252 - Good Zip

39239 - Bad Zip

Country is set to "SE"

I'm calling LogAction so the Error log is available in the OS Service Centre. Also check DevTools Network Response for both calls.

TestREST.share.oml
2021-06-02 20-50-04
Márcio Carvalho
Solution

The structure is wrong somehow, I tested in service studio and then I clicked in copy response to body and then I click on finish and now is returning. You need to see a global structure that will work for any case.

But now you know the reason.

EDIT: I think I found the error

I think it's because of the name in JSON, that's why it works one time and doesn't work the second time.

Even the response structure already says that the set of lists will be separated by each code, and the code will be always the name in JSON. But yeah, as @Dorine Boudry  said, you need to parse or manipulate the response after response.


2021-09-06 15-09-53
Dorine Boudry
 
MVP

Very well spotted, @Márcio Carvalho !  This is sneeky little thing that is easily overlooked.

That is indeed the problem, as the api allows to request several zips at the same time, it apparently returns each requested zip as part of its response structure.  

@AFUIS, you'll probably have to do some formatting of the response in OnAfterResponse before parsing it, I guess.

Dorine

UserImage.jpg
AFUIS AB

Yes, I think that may be causing the problem! Not sure how to address this in OnAfterResponse but will tinker with it and see if I can solve it...

Thanks Marcio, a good spot!

2021-09-06 15-09-53
Dorine Boudry
 
MVP

you'll have to replace the postal code tag by some tag you choose, and make sure it matches the structure you want to receive it in.

See attached oml for an example using regex_replace.  it works ... kind of, but the regex isn't winning any beauty contests, I'm not sure how to write perfect capturing groups to also capture the " right after the tag.

Dorine

QDR_ZipCodeAPI.oml
UserImage.jpg
AFUIS AB

Im struggling with RegEx too :D! Will check with someone tomorrow on how to match 

"results": {"39239": [{"postal_code"

and replace with 

"results": {"ZIPLIST": [{"postal_code"

Will post if I get a solution...

Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.