Help on URLConnection

Hi,
i’m trying to update a program i’ve made some years ago due to an upgrade in the API on the other side.
I was able to update most of my code succesfully but i don’t know how to implement this change :

The example code for what i'm tryng to do is as follow : 
> curl -X PUT "https://api-v2.fattureincloud.it/c/12345/entities/clients/12345" \
>  -H "Accept: application/json" \
>  -H "Authorization: Bearer MYAPIKEY" \
>  -H "Content-Type: application/json" \
>  -d '{"data":{"code":"AE86","name":"Avv. Maria Rossi","type":"person","first_name":"Maria","last_name":"Rossi","contact_person":"","vat_number":"IT12345640962","tax_code":"BLTGNI5ABCDA794E","address_street":"Via Roma, 1","address_postal_code":"20900","address_city":"Milano","address_province":"MI","address_extra":"","country":"Italia","email":"maria.rossi@example.com","certified_email":"maria.rossi@pec.example.com","phone":"1234567890","fax":"","notes":"","default_payment_terms":1,"default_payment_terms_type":"standard","bank_name":"Indesa","bank_iban":"IT40P123456781000000123456","bank_swift_code":"AK86PCT","shipping_address":"Corso Magellano 4","e_invoice":true,"ei_code":"111111","default_vat":{"id":54321,"value":45,"description":"","is_disabled":false}}}' 

My working code for other API call is :

Var Connection As New URLConnection
Var Contenuto As String
Var json As New JSONItem
Var d As New Dictionary
Dim URL As String

Connection.RequestHeader(“Authorization”) = “Bearer MYAPIKEY”
Connection.SetRequestContent(json.ToString, “application/json”)
URL = “https://api-v2.fattureincloud.it/c/325415/entities/clients/” + SCEGLICLI.ElencoAnagrafica.Cell(SCEGLICLI.ElencoAnagrafica.ListIndex,0)
Contenuto = Connection.SendSync (“GET”, URL, 30)
Connection.Disconnect
d = ParseJSON (Contenuto)

The problem in this case is that i don’t know how to pass the -d data part to URLConnection. Also is enough to replace the GET command with PUT command ?

Thanks
Mattia

The CURL -d parameter is the data or body of the request.
GET and PUT are the HTTP methods.

With the CURL statement you’ve provided, the HTTP method is PUT, so that would be your first parameter in the call to URLConnection.Send.

Most CURL requests can be translated into URLConnection without the need for additional plugins. To get you started, here’s how the CURL command you’ve shared might translate:

// Build a URLConnection object with the headers we need
var oConnection as new URLConnection
oConnection.RequestHeader("Accept") = "application/json"
oConnection.RequestHeader("Authorization") = "Bearer MYAPIKEY"

// kDataString is your JSON data stored in a constant so we don't
// have to go through and escape everything to store it in-line.
// The second parameter here sets the "Content-type:" header
oConnection.SetRequestContent(kDataString, "application/json")

// I really *really* recommend not using SendSync,
// but for the purposes of a short example here we are
var sResponse as String = oConnection.SendSync("PUT", "https://api-v2.fattureincloud.it/c/12345/entities/clients/12345")

try
  var jsResponse as new JSONItem(sResponse)
  
catch ex as JSONException
  // Response was not JSON
  // Handle that somehow
  
end try

Communicating with remote REST APIs is one of my specialties, so if you’re in need of professional guidance please don’t hesitate to reach out privately!

3 Likes

Hey thanks for the answer!

I got two questions

First i got all the data i’ve to insert in the json in textfields (for example the name, vat_number etc) so how can i generate a working json as the one in the example ?
Second : Why i shoudn’t use SendSync ? What should i use ?

Thanks again
Mattia

Here’s a bare-bones sample for how to generate the *structure* of the item above. It doesn’t have every key, but I did illustrate how to make sub-objects like the default_vat object:

// The "data" key is an object
var jsData as new JSONItem
jsData.Value("first_name") = txtFirstName.Text
jsData.Value("last_name") = txtLastName.Text

// Default Vat is an object
var jsDefaultVat as new JSONItem
jsDefaultVat.Value("id") = txtVatID.Text.ToInteger

// Put the object into a key on the data object
jsData.Value("default_vat") = jsDefaultVat

// The data object needs to go on a key on a main outer body object
var jsBody as new JSONItem
jsBody.Value("data") = jsData

// Get the JSONItem as a String into the request body
oConnection.SetRequestContent(jsBody.ToString, "application/json")

Regarding SendSync, it locks up your whole program until it gets a response. It’s handy for a quick and dirty implementation or example, but the event-driven URLConnection features provide a better end user experience.

Thank you for the very helpfull answer Tim. I was able using your examples to almost complete my code.
I have now another problem still related to this situation.
To find out the latest invoice number i have to call a query. The answer of this call is something like this :

{
"data": {
"numerations": {
"2018": {
"AB123": 2
},
"2019": {
"123": null
},
"2020": {
"ABC": 2
},
"2021": {
"rec123": 2
}},
"dn_numerations": {
"2017": {
"": 1000
},
"2018": {
"": 112
},
"2019": {
"": 526
},
"2020": {
"": 11
},
"2021": {
"": 110
}},

I’ve to access the value inside “numerations” that is called as the current year. Inside that there is the last invoice number that i’ve to use.
I tried but i always and up with a Mismatch type exception and don’t know why.
Here is my code

Dim currentYear As New date
dim dictInner as Dictionary = d.Lookup("data", nil)
dim dictinner2 As Dictionary = dictInner.Lookup("numerations",nil)
MessageBox dictinner2.Value(Str(currentYear.year))

I got the error on the messagebox line
How can i get the value i need and put it in a string variable ?

Thanks again
Mattia

Please don’t use Dictionaries to manipulate JSON. It causes all kinds of headaches and is the core of your problem here. Use the class JSONItem, it’s purpose built for handling JSON.

Here’s how to access the data you’re looking for object using JSONItem:

// Make the document a JSONItem
var jsBody as new JSONItem(sAPIResponse)

// Get the data object
var jsData as JSONItem = jsBody.Child("data")

if jsData = nil then
  // No data object
  // Handle this somehow
  return
  
end

// Get numerations
var jsNumerations as JSONItem = jsData.Child("numerations")

if jsNumerations = nil then
  // No numerations object
  // Handle this somehow
  return
  
end

// Find this year
var sYearKey as String = DateTime.Now.Year.ToString
var jsThisYear as JSONItem = jsNumerations.Lookup(sYearKey, nil)

if jsThisYear = nil then
  // This year was not found
  // Handle this somehow
  return
  
end

// We have found this year's numeration!
break

1 Like

Agree one-hundred-percent and then some.