%Net.HttpRequest and {}.%FromJSON
Hi !
I am new to the language and I am trying to read some json data from a government site (it is public data).
The address is: https://apisidra.ibge.gov.br/values/t/1736/n1/all/v/all/p/all/d/v44%202…
Here is some data sample:
[{"NC":"Nível Territorial (Código)","NN":"Nível Territorial","MC":"Unidade de Medida (Código)","MN":"Unidade de Medida","V":"Valor","D1C":"Brasil (Código)","D1N":"Brasil","D2C":"Variável (Código)","D2N":"Variável","D3C":"Mês (Código)","D3N":"Mês"},{"NC":"1","NN":"Brasil","MC":"30","MN":"Número-índice","V":"0.0000000055765","D1C":"1","D1N":"Brasil","D2C":"2289","D2N":"INPC - Número-índice (base: dezembro de 1993 = 100)","D3C":"197903","D3N":"março 1979"},{"NC":"1","NN":"Brasil","MC":"30","MN":"Número-índice","V":"0.0000000057689","D1C":"1","D1N":"Brasil","D2C":"2289","D2N":"INPC - Número-índice (base: dezembro de 1993 = 100)","D3C":"197904","D3N":"abril 1979"},{"NC":"1","NN":"Brasil","MC":"30","MN":"Número-índice","V":"0.0000000058704","D1C":"1","D1N":"Brasil","D2C":"2289","D2N":"INPC - Número-índice (base: dezembro de 1993 = 100)","D3C":"197905","D3N":"maio 1979"},{"NC":"1","NN":"Brasil","MC":"30","MN":"Número-índice","V":"0.0000000060465","D1C":"1","D1N":"Brasil","D2C":"2289","D2N":"INPC - Número-índice (base: dezembro de 1993 = 100)","D3C":"197906","D3N":"junho 1979"},I am trying to make a class to read some of this data:
/// Contém os dados do INPC para calculos financeiros
Class User.TabelaINPC Extends (%Persistent, %JSON.Adaptor)
{Property Mes As %Integer [ Required ];Index MesIndex On Mes [ Unique ];Property Descricao As %String [ Required ];Property Valor As %Double [ Required ];ClassMethod leINPC() As %Status
{
Set result = ##class(%Net.HttpRequest).%New()
Set result.Server = "api.sidra.ibge.gov.br"
set result.SSLConfiguration = "padrao"
set result.Https = 1
set result.SSLCheckServerIdentity = 0
set result.FollowRedirect = $$$YES
TRY {
set status = result.Get("/values/t/1736/n1/all/v/all/p/all/d/v44%202,v68%202,v2289%2013,v2290%202,v2291%202,v2292%202?formato=json")
set response = result.HttpResponse.Data
set dados = {}.%FromJSON(response) -----> THE ERROR IS HERE
}
CATCH erro {
write "ERRO:"
write erro.Name_", "_erro.Location_", error code "_erro.Code,!
do $system.OBJ.DisplayError()
RETURN erro.AsStatus()
}
Quit $$$OK
}
I am getting the error code 5035, Parsing error code 3.
What I am doing wrong?
Thanks in advance !
Comments
I'd recommend looking at what (other than valid JSON) is in result.HttpResponse.Data. Also worth looking at result.HttpResponse.StatusCode - is it 400 or 404?
It looks like there might be an issue with the service you're trying to use - at https://apisidra.ibge.gov.br/ , pasting in "/t/1612/n2/all/v/all/p/last/c81/2702/f/u" as "Parâmetros/valores da API:" then clicking "Consultar" I get an alert saying "A solicitação de conexão com pools sofreu timeout".
I also see this from ObjectScript with Server set to apisidra.ibge.gov.br instead of api.sidra.ibge.gov.br
Hi Timothy !
Thank´s for the help.
Yesterday the service was unstable, but today is working fine When I type de url in the browser I get the data, but in my code (I did as you told me to) HttpResponse.StatusCode returns 404.
I don´t know why...
Right - at this point I'd say set Server to apisidra.ibge.gov.br instead of api.sidra.ibge.gov.br and see if that fixes it.
Hi,
No, it din´t fix it. It didn´t find the server apisidra.ibge.gov.br. The correct one is api.sidra.ibge.gov.br.
Does it make any difference if the connection is sync or async?
Do I have to change the code because of it?
Thanks !
Problem solved !
/// Contém os dados do INPC para calculos financeirosClass User.TabelaINPC Extends (%Persistent, %JSON.Adaptor){Property Mes As %Integer [ Required ];Index MesIndex On Mes [ Unique ];Property Descricao As %String [ Required ];Property Valor As %Double [ Required ];ClassMethod leINPC() As %Status{Set result = ##class(%Net.HttpRequest).%New()Set result.Server = "api.sidra.ibge.gov.br"set result.SSLConfiguration = "padrao"set result.Https = 0 --- HTTPS MUST Be ZERO, although there is a redirect to https in the browserset result.SSLCheckServerIdentity = 0set result.FollowRedirect = $$$YESset result.ContentType = "application/json"TRY {set status = result.Get("/values/t/1736/n1/all/v/all/p/all/d/v44%202,v68%202,v2289%2013,v2290%202,v2291%202,v2292%202?formato=json")set response = result.HttpResponse.Datawrite "HTTP_CODE:"_result.HttpResponse.StatusCode,!set dados = {}.%FromJSON(response)set formatter = ##class(%JSON.Formatter).%New()do formatter.Format(dados)set iterator = dados.%GetIterator()while iterator.%GetNext(.key, .value) { write "element:"_key_"=/"_value_"/ ",!}}CATCH erro {write "ERRO:",!write erro.Name_", "_erro.Location_", error code "_erro.Code,!do $system.OBJ.DisplayError()RETURN erro.AsStatus()}Quit $$$OK}Thank you for the help Timothy !
Your result.HttpResponse.Data can be either a string or a stream object. If it's a stream object you'll have to handle it a little bit differently using result.HttpResponse.Data.Read():
set response=result.HttpResponse.Data.Read()
while 'result.HttpResponse.Data.AtEnd{
set response = response_result.HttpResponse.Data.Read()
}No, as long as response is json this should work - %FromJSON accepts strings, streams and even file paths as input:
set response = result.HttpResponse.Data
set dados = {}.%FromJSON(response) I think I am doing something wrong before
set response = result.HttpResponse.Data
set dados = {}.%FromJSON(response)
I am getting error 404 although the access by the browser is ok.
Thanks !
Try to set UserAgent in IRIS to your browser.
Just to add more information.
This is a C# Code that works fine :
HttpClient client = new HttpClient();
string baseApiAddress = "http://www.sidra.ibge.gov.br";
client.BaseAddress = new Uri(baseApiAddress);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("/api/values/t/1612/n2/all/v/all/p/last/c81/2702/f/u").Result;
It is a asynchronous connection.
I get 404 opening this url in the browser
https://www.sidra.ibge.gov.br/api/values/t/1612/n2/all/v/all/p/last/c81…
Because the correct address is : http://api.sidra.ibge.gov.br/values/t/1736/n1/all/v/all/p/all/d/v44%202…
That C# code is not working anymore. They presented it just as a sample.
Anyway, as I posted here, the problem is solved. Thank you for your attention !
Daniel,
One thing I always recommend is to get familiar with the API using a standalone tool before attempting to code the programmatic interface. I like Postman as it has pretty good UI to work with. If you are at the command line you can use curl.
Postman can also give you the code for different programming environments. Unfortunately not Objectscript, but it is fairly easy to translate from the examples you can see.
Thank you !