FWH y Mysql. Los nuevos escenarios...

User avatar
Carles
Posts: 937
Joined: Fri Feb 10, 2006 2:34 pm
Location: Barcelona
Contact:

Re: FWH y Mysql. Los nuevos escenarios...

Post by Carles »

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 :P 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: Select all

#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: Select all

#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: Select all

<?php
include( 'config.php' );

    //  Recolectar parámetros
    
    $cId    = isset( $_REQUEST[ 'id' ] ) ? $_REQUEST[ 'id' ] : '1';
    $cId    = intval( $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...
    
    if ($conn->connect_error) {
    
        $cError = "Connection failed: " . $conn->connect_error;
        
    } else {

        $sql    = "SELECT * FROM test where id = '" . $cId . "' LIMIT 1";
        $result = @mysqli_query( $conn, $sql );     

        if ($result->num_rows > 0) {
        
            $aData = $result->fetch_assoc();                                                
        } 
    
    }
    
    $conn->close(); 
    
    //  Enviar respuesta de la petición...
    
    $aRequest = array( 'data' => $aData, 'error' => $cError );
    
    echo json_encode( $aRequest );  
?>
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... :D
Salutacions, saludos, regards

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

https://modharbour.app
https://modharbour.app/compass
https://forum.modharbour.app
User avatar
Carles
Posts: 937
Joined: Fri Feb 10, 2006 2:34 pm
Location: Barcelona
Contact:

Re: FWH y Mysql. Los nuevos escenarios...

Post by Carles »

Rafa,
thefull wrote:Ven un día por Barna, y montamos una quedada /cena/ merendola y nos tomamos unas birras :D
Ok, me apetece un brainstorming contigo :D , 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..."

https://modharbour.app
https://modharbour.app/compass
https://forum.modharbour.app
FiveWiDi
Posts: 910
Joined: Mon Oct 10, 2005 2:38 pm

Re: FWH y Mysql. Los nuevos escenarios...

Post by FiveWiDi »

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 19.06 + Harbour 3.2, BCC 7 Windows 10
User avatar
thefull
Posts: 720
Joined: Fri Oct 07, 2005 7:42 am
Location: Barcelona
Contact:

Re: FWH y Mysql. Los nuevos escenarios...

Post by thefull »

Venga, el ejemplo del WS en Harbour, en su mínima expresion;

Code: Select all

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__)
Post Reply