FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour FWH y Mysql. Los nuevos escenarios...
Posts: 1283
Joined: Fri Feb 10, 2006 02:34 PM
Re: FWH y Mysql. Los nuevos escenarios...
Posted: Wed Jul 05, 2017 05:53 PM
Bones,

Carlos Mora wrote:Tu inquietud mental demuestra que tienes neurones muy jóvenes aún


Sobretodo despues de la cervecita, jue que calor...

A ver Carlitos… te estas exsitando :-) Intentaré primero montar un ejemplo practico sencillo para que se pueda entender y luego si quereis lo vamos escalando hasta emborracharnos todos de apis, tokens, seguridad,…

El tema es muuuuy amplio, por lo que lleva tiempo montar ejemplos y explicaciones pero vamos a intentarlo.

Como conectar desde Harbour ?

Existen varias maneras pero las que mas se usan son usando la librería y dll’s para el uso de curl y las librerias TipClientHttp. Vamos de inicio a usar la segunda por su facilidad quizas en su manejo. La librería curl es mas potente pero a la vez mas compleja por ahora de explicar.

He montado una clase muy básica para conectar a un WS usando un método post que nos servira tambien para pasar parámetros al WS. Por el foro hay numerosos ejemplos

Code (fw): Select all Collapse
#include 'fivewin.ch'

*--------
CLASS TWS
*--------

    DATA  aBuffer                AS ARRAY     INIT {}
    DATA  oUrl                  
    DATA  oClient                  
            
    DATA  cUrl                   AS CHARACTER INIT ''
    DATA  lClientOpen            AS LOGICAL   INIT .F.
    DATA  lShowError             AS LOGICAL   INIT .T.

    METHOD New( cUrl )  CONSTRUCTOR

    METHOD Post( uParam )
    
    METHOD ShowError()

    METHOD Init()
   
ENDCLASS

*--------------------------
METHOD New( cUrl ) CLASS TWS
*--------------------------

    DEFAULT cUrl := ''
    
    ::cUrl  := cUrl 

RETU Self

*---------------------
METHOD Init() CLASS TWS
*---------------------

    ::oURL          := TUrl():New( ::cUrl )
    ::oClient       := TIpClientHttp():New( ::oUrl )
    
    ::lClientOpen   := ::oClient:Open()

RETU NIL


*-----------------------------
METHOD Post( uParam ) CLASS TWS
*-----------------------------
    LOCAL cJson
    LOCAL oError 
    local hRequest  := NIL  
    LOCAL lError    := .F. 
    LOCAL x
    
    ::Init()
    
    IF !::lClientOpen 
        RETU NIL
    ENDIF   
    
    IF Valtype( uParam ) == 'U' 
        MsgAlert( 'No se han definido parámetros para método Post' )
        RETU NIL
    ENDIF   
    
    TRY 

        ::oClient:Post( uParam )
            
      CATCH oError 
          
        lError := .t.
        xBrowse( oError )
    END 
    

    IF lError 
        
        RETU NIL
      ELSE 
      
        IF ::oClient:nReplyCode == 200  
    
            cJson := ::oClient:Read()

            if ( valtype(cJson) == 'C' )        

                hRequest := {=>}
                
                IF ( hb_jsonDecode( cJSON, @hRequest ) ) > 0
                            
                ENDIF 
            
            ELSE
            
                RETU NIL
                
            ENDIF
            
          ELSE 
          
            ::ShowError()
    
        ENDIF             
      
    ENDIF   

RETU hRequest 

*--------------------------
METHOD ShowError() CLASS TWS
*--------------------------
    LOCAL nReplyCode 
    
    IF ! ::lShowError
        RETU NIL
    ENDIF

    nReplyCode := ::oClient:nReplyCode
    
    DO CASE
        CASE nReplyCode == 404
        
            MsgAlert(   'Error: ' + Chr( VK_TAB ) + ::oClient:cReply + CRLF + ;
                        'Url:   ' + Chr( VK_TAB ) + ::oClient:oUrl:cAddress + CRLF +  ;
                        'File:  ' + Chr( VK_TAB ) + ::oClient:oUrl:cFile + CRLF +  ;                        
                        'Server:' + Chr( VK_TAB ) + ::oClient:oUrl:cServer, 'ShowError' )
                        
        OTHERWISE
            
            xBrowse( ::oClient )
            
            MsgInfo( ::oClient:lastErrorMessage(), 'LastErorMessage' )
            
    ENDCASE

RETU NIL


No he podido crear mas corta la clase, pero quien le quiera hechar un ojo es sencilla

El objetivo es desde FWH poder conectar a un WS q he creado sencillo el cual le pasaremos un ID y nos devolverá la info del user. Mas sencillo no se puede hacer.

El proceso desde FWH sera: Introducir ID, Conectar con el WS, Ejecutar un Post pasandole el id, recuperar datos y mostrarlo.

Code (fw): Select all Collapse
#include 'fivewin.ch'

#define URL_ENDPOINT   "http://itarraco.com/fweb/ws/customer.php" 

FUNCTION Test_Post( oApp )

    local oWs, hRequest, hReg 
    local hParam    := {=>}
    LOCAL nId    := 1
    
    IF ! MsgGet( 'Id', 'Id. Customer ( 1 a 100000)', @nId )
        RETU NIL
    ENDIF

    hParam[ 'id' ] := nId

    oWs := TWS():New( URL_ENDPOINT )
    
    hRequest := oWs:Post( hParam )  

    IF valtype( hRequest ) == 'H'           
        
        hReg = hRequest[ 'data' ]
        
        IF ( ValType( hReg ) == 'H' )
        
            hb_HCaseMatch( hReg, .F. )  // Indiferent majusqules/minuscules     
            
            xBrowse( hReg, 'Datos' )

            MsgInfo( 'Id'    + chr( VK_TAB ) + hReg['id']    + CRLF + ;
                     'First' + chr( VK_TAB ) + hReg['first'] + CRLF + ;
                     'Last'  + chr( VK_TAB ) + hReg['last'], 'Resultat' )   
        ELSE 
            
            MsgAlert( 'No Data' )
                
        ENDIF

    ELSE 
      
        MsgAlert( 'No hay datos', 'Sistema' )
    
    ENDIF

RETU NIL


De la misma manera he creado un test de modificacion de 2 campos…No lo pongo para no alargar el tema y practicamente es lo mismo

El ejecutable de test lo podeis bajar de aqui -> https://www.dropbox.com/s/d6tqbq5s5qp1vsx/fws.rar?dl=0


WebService

No es el objetivo ahora explicar como se monta un WS, un servico REST, SOAP, … pero a manera didactica he crear un microservicio básico (no hay tema de seguridad, validaciones, …) pero podeis ver como se basa el sistema. El ws hemos dicho que aceptara un id para buscar los datos y que nos los escupa. El proceso será: Recogida de parametros, validacion, proceso y devolver resultado, muy fácil. Lo he creado con php, pero se puede crear con numerosos lenguajes. Rafa (que se esta dejando ya barba, porque ve que queda bien...) nos preparará pronto un pequeño ejemplo con Harbour :-)

Code (php): Select all Collapse
<div class="php" id="{CB}" style="font-family: monospace;"><?php
<a href="http://www.php.net/include">include</a>( 'config.php' );

    //  Recolectar parámetros
    
    $cId    = isset( $_REQUEST[ 'id' ] ) ? $_REQUEST[ 'id' ] : '1';
    $cId    = <a href="http://www.php.net/intval">intval</a>( $cId );   

    // Crear conexión a la base de datos 
    
    $conn   = new mysqli( DB_SERVER, DB_USER, DB_PSW, DB_DATABASE );
    $cError = '';
    $aData  = null;
    
    
    // Crear procesos...
    
    <a href="http://www.php.net/if">if</a> ($conn->connect_error) {
    
        $cError = "Connection failed: " . $conn->connect_error;
        
    } <a href="http://www.php.net/else">else</a> {

        $sql    = "SELECT * FROM test where id = '" . $cId . "' LIMIT 1";
        $result = @<a href="http://www.php.net/mysqli_query">mysqli_query</a>( $conn, $sql );     

        <a href="http://www.php.net/if">if</a> ($result->num_rows > 0) {
        
            $aData = $result->fetch_assoc();                                                
        } 
    
    }
    
    $conn->close(); 
    
    //  Enviar respuesta de la petición...
    
    $aRequest = array( 'data' => $aData, 'error' => $cError );
    
    <a href="http://www.php.net/echo">echo</a> <a href="http://www.php.net/json_encode">json_encode</a>( $aRequest );  
?></div>


Para que entendais como se podria usar este ws, seria: domino/servicio/parámetro_id que puesto en escena seria http://itarraco.com/fweb/ws/customer/1

Y para finalizar he montado una pagina web sencilla que consumira del mismo WS que FWH para que podais cerrar el circulo y penseis ya en la potencia de estos escenarios.

http://itarraco.com/fweb/ws/customer.html

Intentar desde FWH modificar un registro para desde web tambien consultarlo...

Creo que de momento se puede entender el tema. En los proximos post Carlitos que es una machine en estos temas nos va a dar ideas y ejemplos de conexiones

quim wrote:...
Y que decir de una vieja aplicacion que a través de un WS puede alimentar artículos o recibir pedidos de un Prestashop, por WS REST a traves de la API que nos provee?

Realmente es otra dimensión


El comentario de Quim es la base para entender la potencia.

Tertulias de verano cierra por hoy... :-)
Salutacions, saludos, regards

"...programar es fácil, hacer programas es difícil..."

UT Page -> https://carles9000.github.io/
Forum UT -> https://discord.gg/bq8a9yGMWh
HIX -> https://github.com/carles9000/hix
Posts: 1283
Joined: Fri Feb 10, 2006 02:34 PM
Re: FWH y Mysql. Los nuevos escenarios...
Posted: Thu Jul 06, 2017 05:50 AM
Rafa,

thefull wrote:Ven un día por Barna, y montamos una quedada /cena/ merendola y nos tomamos unas birras :-)


Ok, me apetece un brainstorming contigo :-) , eso si con unas pocas birritas. A ver si segunda quincena de Julio podemos montar algo.
Salutacions, saludos, regards

"...programar es fácil, hacer programas es difícil..."

UT Page -> https://carles9000.github.io/
Forum UT -> https://discord.gg/bq8a9yGMWh
HIX -> https://github.com/carles9000/hix
Posts: 1445
Joined: Mon Oct 10, 2005 02:38 PM
Re: FWH y Mysql. Los nuevos escenarios...
Posted: Fri Jul 07, 2017 10:11 AM

FANTÁSTICO!!!!

Eso es lo que yo llamo un "guíaburros"; y como yo soy muy burro me viene de perlas!!!!

Yo ya sabía de los WS pero no sabía como hacerlos, gracias a vosotros ya se!!!

Grandes, sois GRANDES!

Un Saludo

Carlos G.



FiveWin 25.12 + Harbour 3.2.0dev (r2502110321), BCC 7.7 Windows 11 Home

Posts: 731
Joined: Fri Oct 07, 2005 07:42 AM
Re: FWH y Mysql. Los nuevos escenarios...
Posted: Thu Jul 13, 2017 12:07 PM
Venga, el ejemplo del WS en Harbour, en su mínima expresion;

Code (fw): Select all Collapse
oServer := UHttpdNew( )
IF ! oServer:Run( { ;
         "Port"                => nPort, ;
         "Idle"                => {| o | iif( hb_FileExists( ".uhttpd.stop" ), ( FErase( ".uhttpd.stop" ), o:Stop() ), NIL ) }, ;
         "Mount"          => { ;
             "/customer"                        => {|| testjson() } } } )
ENDIF

// Server, post y get son variables publicas de UHttpdNew
function testjson(  )
  Local hDato := {=>}
  Local codigo, dDesde

  if server[ "REQUEST_METHOD" ] == "POST"
     codigo := hb_HGetDef( post, "codigo", "01" ) 
     dDesde := hb_HGetDef( post, "desde", DTOC( date() ) ) 
  elseif server[ "REQUEST_METHOD" ] == "GET"
     codigo := hb_HGetDef( get, "codigo", "01" ) 
     dDesde := hb_HGetDef( get, "desde", DTOC( date() ) ) 
  endif

   UAddHeader( "Content-Type", "application/json" )
  
   hDato["name"] := "rafa"
   hDato["priority"] := "high"
   
   hDato["notification"]  := {=>} 
   hDato["notification"]["title"] := "Example"
   hDato["notification"]["text"]  := "Information PUSH"
    
   hDato["data"]  := {=>} 
   hDato["data"]["message"] := "This is a test for Harbour!"
    
return hb_jsonencode( hDato, .T.  )
Saludos

Rafa Carmona ( rafa.thefullARROBAgmail.com___quitalineas__)
Posts: 84
Joined: Wed Oct 24, 2007 12:48 PM
Re: FWH y Mysql. Los nuevos escenarios...
Posted: Fri Mar 26, 2021 08:16 AM
Carlos Mora wrote:
Carles wrote:Hi

Carlos Mora wrote:Es que al Carles casi no le he conocido con esa barba hipster! Jaja.


Cito

La cultura hipster es una subcultura de jóvenes bohemios de clase media-alta que se establecen por lo general en barrios que experimentan procesos de gentrificación.


Gracias por lo de joven :-). En septiembre ya me caen los 50 :-) , un chavalin !!!

Ahora entiendo! Lo que me confundió era ese aire de niño de familia bien! :-) :-) :-)
No le hagas caso a los 50, muchas espectativas y al final no cambia nada, la vida es un continuo. Da por culo cambiar a veces de casillero en las estadísticas, pero no va más allá. Tu inquietud mental demuestra que tienes neurones muy jóvenes aún.

Tengo un ejemplo que muestra hacia adonde van las apps y como vamos a integrarlas, muy a la fintech. En pocos días me meto con integrar microservicios bancarios a la app de contabilidad (FW+Harbour) con los microservicios de la banca. El primero será el BBVA, del cual me estoy empollando las APIs. El usuario habilita el acceso a la API del banco con su usuario, contraseña, y un token de 6 dígitos que recibe en la app del BBVA en el momento de entrar. A partir de allí puedo consultar los extractos bancarios de todas sus cuentas, lo que me permite hacer la conciliación y/o registro de las cuentas bancarias. Luego veré como se hace con otros bancos, pero seguramente todo va igual.

Este ejemplo del banco representa el 'consumo' de un microservicio. Ahora bien ¿Que tal si nuestra aplicacion de facturación publica las facturas y los vencimientos y cobros para que los clientes los puedan consultar desde su aplicación? No importa como esté hecho tu ERP, tienes que publicar información a la que se accede luego de autenticarte, y usas JSON o XML para la respuesta. Cuando tengas creado ese microservicio, no solo podrás hacer que los clientes puedan integrar su aplicacion con la tuya, sino que además podrías encargarle a alguien que escriba una app web de acceso para los clientes donde pueden consultar la misma informacion, pero en un Portal del Cliente. Y el programador WEB no tiene que conocer donde estan las facturas ni si estan en DBF/NTX o en una BBDD Oracle, le da igual, solo necesita conocer como acceder al microservicio y como le devuelve las respuestas. Además, imaginaros que el ERP, que lo tenias escrito con DBFNTX, ahora lo migras a SQL con TDolphin o Eagle. Solo cambias el microservicio, el resto de las aplicaciones 'clientes' ni se enterará del cambio ni tendra que reprogramar nada.
Y, ojo, esto no es un delirio: me consta que Rafa tiene puñados de cosas como estas usando el webserver de Harbour. ¿Es así Rafa?

Los cambios apuntan a la integración de las aplicaciones, y tenemos que empezar a ver nuestras aplicaciones como servicios integrados, y que esa integracion sea una ventaja competitiva.


Buenos días, estoy interesado en descargar los extractos bancarios automáticamente, quisiera saber si conseguiste usar la API de BBVA.
Yo he hecho un primer intento y no he conseguido que me devuelva el token para acceder a los extractos. Podrías poner un ejemplo.
Gracias.

Continue the discussion