jueves, 26 de febrero de 2026

Acceder a servicios REST FULL API desde Visual Foxpro 9.0

 Hola a tod@s, espero poder regresar más seguido por este blog; hoy les traigo otro reto.

El requerimiento es como sigue, existen servicios de internet que se pueden consumir desde su app de Visual FoxPro, estos son del tipo REST FULL API, que aceptan métodos de llamada del tipo: GET, POST, PUT

El Get es para recuperar información (es decir devolverá tipicamente un JSON con los datos solicitados).

El POST se usa para actualizar información que nosotros le enviamos.

Para usar el GET existen varias librerias, yo utilizo la del amigo Victor Espina, y la idea es recuperar información de una tabla basado en un rango de fechas, el rango esta en 2 variables digamos ldFec1 la fecha inicial y ldFec2 la fecha final.

Se construye la cadena a enviar de la siguiente manera

SET DATE TO ANSI

lcFec1 = DTOC(ldFec1)

lcFec1 = STRTRAN(lcFec1,'.','-')

lcFec2 = DTOC(ldFec2)

lcFec2 = STRTRAN(lcFec2,'.','-')

SET DATE TO YMD 

lcURL = "https://script.google.com/macros/s/AKfycbxeKrqo2sk-xjPaUX7LXtjMJ/exec?fromDate="

lcRango=lcFec1+"&toDate="+lcFec2

SET PROCEDURE TO qdfoxjson additive
JSONStart()
cJSON = GETURL(lcURL+lcRango)
oDatos = json.Parse(cJSON)

y listo, si el estado devuelve 200 hubo exito, en caso contrario algo salió mal
IF oDatos.meta.status#200
=MESSAGEBOX('La busqueda tuvo problemas',64)
oDatos = .Null.
RETURN 0
ENDIF

Luego podemos iterar el objeto

lnProcesados = 0
FOR J = 1 TO lnRegistros
   mMess="Procesando registros: "+TRANSFORM(J,'99,999')+"/"+Alltrim(TRANSFORM(lnRegistros,'99,999'))
   Wait mMess Window At Srows()/2,(Scols()/2 - (Len(mMess)/2)) NOWAIT

m.Detalles = oDatos.Result.Item(J).Conceptos.Count
m.Cliente = ALLTRIM(oDatos.Result.Item(J).Codigo)
...
...
...
endfor 

Y eso es todo en cuanto a recuperar información, ahora para enviar información y actualizar datos en la web, se usa el POST (hay que mencionar que ambos necesitan un EndPoint). Lo primero es construir la cadena JSON a enviar con información de los clientes, el endPoint requiere la siguiente estructura:

El body del request debe contener esta información por el momento:

Ejemplo:
{
    "meta": {
        "endpoint": "v1/reemplazar-actualizar-todos-los-clientes"
    },
    "payload": {
        "clientes": [
            {
                "codigo": "SVexamp",
                "nombreOrRazonSocial": "Example S.A de C.V",
                "email": "example@example.example",
                "zona": "CENTRO",
                "vendedorId": 5,
                "activo": 1,
                "limiteCartera": 1000,
                "saldoDebe": 0
            },
        ]
    }
}

Nuestro código se verá así

CLEAR
TEXT TO C1 NOSHOW 
{"meta": {"endpoint": "v1/reemplazar-actualizar-todos-los-clientes"}, "payload": {"clientes": [
ENDTEXT
CLOSE DATABASES ALL
USE Clientes ORDER Codigo
lcCuerpo = ''
llPrimero = .T.
GO TOP
SCAN FOR RECNO()<10
IF llPrimero
lcCuerpo = lcCuerpo + [{"codigo": "] + ALLTRIM(Clientes.Clie_Cod) + [",] + ;
["nombreOrRazonSocial": "] + ALLTRIM(Clientes.Clie_nom) + [",] + ;
["email": "] + ALLTRIM(Clientes.Clie_Email) + [",] + ;
["zona": "] + ALLTRIM(Clientes.Zona) + [",] + ;
["vendedorId":] + ALLTRIM(STR(Clientes.Clie_Vend)) + [,] + ;
["activo": 1,] + ;
["limiteCartera":] + ALLTRIM(STR(Clientes.clie_limca)) +[,] + ;
["saldoDebe":]+ALLTRIM(TRANSFORM(Clientes.Clie_Saldo,'999999.99')) + "}"
llPrimero = .F.
ELSE
lcCuerpo = lcCuerpo + [,{"codigo": "] + ALLTRIM(Clientes.Clie_Cod) + [",] + ;
["nombreOrRazonSocial": "] + ALLTRIM(Clientes.Clie_nom) + [",] + ;
["email": "] + ALLTRIM(Clientes.Clie_Email) + [",] + ;
["zona": "] + ALLTRIM(Clientes.Zona) + [",] + ;
["vendedorId":] + ALLTRIM(STR(Clientes.Clie_Vend)) + [,] + ;
["activo": 1,] + ;
["limiteCartera":] + ALLTRIM(STR(Clientes.clie_limca)) +[,] + ;
["saldoDebe":]+ALLTRIM(TRANSFORM(Clientes.Clie_Saldo,'999999.99')) + "}"
ENDIF
ENDSCAN
TEXT TO C2 NOSHOW 
]}}
ENDTEXT
cJson = C1 + lcCuerpo + C2
****

* Luego creamos el objeto para utilizar

LOCAL xmlHttp, result, lcUrl, lcJsonData

* 1. Instantiate the ServerXMLHTTP object
* Use version 6.0 for best compatibility, fall back to 3.0 if needed
TRY
    xmlHttp = CREATEOBJECT("Msxml2.ServerXMLHTTP.6.0")
CATCH
    xmlHttp = CREATEOBJECT("MSXML2.XMLHTTP.3.0")
ENDTRY

* 2. Define the target URL
lcUrl = "http://your-api-endpoint.com"
lcURL = "https://script.google.com/macros/s/AKfycbxjWfYQuGA3vh4oWsQTlLifmwFzWyxXe/exec"

* 3. Prepare the data to send (e.g., a JSON string)
* You would construct this string based on your API's requirements
lcJsonData = cJson  && '{ "key1": "value1", "key2": 123 }'

* 4. Open the connection and specify the method (POST)
* The third parameter (null or .F.) means the request is synchronous
xmlHttp.open("POST", lcUrl, .F.)

* 5. Set request headers (e.g., Content-Type for JSON data)
xmlHttp.setRequestHeader("Content-Type", "application/json")

* You might also need to set other headers like API keys or authorization tokens:
* xmlHttp.setRequestHeader("Authorization", "Bearer your_token_here")

* 6. Send the request with the data in the body
xmlHttp.send(lcJsonData)

* 7. (Optional but important in a PRG) Wait for the response
* This is essential within a program to ensure the response is received before processing
DO WHILE xmlHttp.readyState != 4 && 4 means "complete"
    * Wait or process other events while waiting
ENDDO

* 8. Retrieve the response
result = xmlHttp.responseText
? "Response Status: " + TRANSFORM(xmlHttp.status)
? "Response Text:"
? result

y eso es todo por ahora, espero les sirva el código que por cierto lo generó la IA de Google, saludos cordiales a tod@s y en especial a mi sobrina Trini que estuvo de cumpleaños hace unos días.

Pensar es gratis.

No hay comentarios: