A web service for your data

This forum is for posting of useful information
Message
Author
User avatar
rdonnay
Site Admin
Posts: 4774
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

A web service for your data

#1 Post by rdonnay »

I have created several web services for eXpress++ customers which allow remote access to DBFNTX and DBFCDX data via a web browser or an Xbase++ program.

Each of these servers use the same architecture.
The only difference is the custom endpoints, which all follow a simple architecture.

For example, I wrote a webservice that connects to all the .DLLs of a back-office taxi application (written in Xbase++) that is used by several Kiosks (running a Javascript application on Android tablets). The drivers use the Kiosks to submit an application to drive and the Kiosk app scans their DMV, TLC, SSN licenses, signature, entered data and submits all info to the webservice via an endpoint. This has saved a lot of time for the people in the office.

The same web service architecture is also used by 2 other eXpress++ customers who need to give remote access to customer's data.

The endpoint code simply uses Xbase++ functions to access the data and communicate with the client.
That data can even be accessed using SQL even though the data is DBFNTX or FOXCDX by using the ADS local server DLL. No ADS license required.

Below is a screenshot of the WebService.exe running on the server (notice all info received and sent is a JSON object).
The screen is eXpress++ code.

There is no additional Web Server required, such as IIS or Apache and all SQL statements (if used) are handled by AdsLoc32.dll, even DBFNTX and FOXCDX. 

If you are interested in how to create a customized WebService, using this endpoint concept, let me know.
KioskService.JPG
KioskService.JPG (264.04 KiB) Viewed 18650 times
Here is a code example of a custom endpoint:

Code: Select all

METHOD WebService:KioskGetLeaseRecord()

LOCAL oParams := DataObject():new(), oRecord, oLeaseId, ;
      oLease, oResponse := DataObject():new(), cLeaseId, cResponse

::httpResponse:addHeader('Access-Control-Allow-Origin','*')
::httpResponse:addHeader('Access-Control-Allow-Methods','GET,POST,OPTIONS')
::httpResponse:addHeader('Access-Control-Allow-Headers','Content-Type')

oParams := ::getVar("LEASE")

oLease := Json2Var(oParams)
oLease := oLease:lease

::ParamsSetData("KioskGetLeaseRecord", oLease )

cLeaseID := oLease:leaseID

UseDb('LSE')

IF LSE->(dbSeek(cLeaseID))
  oRecord := LSE->(DC_DbRecord():new())
  LSE->(DC_DbScatter(oRecord))
  oResponse:LeaseRecord := oRecord
  oResponse:status := 200
ELSE
  oResponse:statusMessage := 'Lease ' + cLeaseId + ' not found!'
  oResponse:status := 404
ENDIF

cResponse := ::ResponseFormat(oResponse,::httpResponse, 'JSON' )

::Write2Log('KioskGetLeaseRecord', oResponse, oLease)

dbCloseAll()

RETURN cResponse
The eXpress train is coming - and it has more cars.

skiman
Posts: 1195
Joined: Thu Jan 28, 2010 1:22 am
Location: Sijsele, Belgium
Contact:

Re: A web service for your data

#2 Post by skiman »

Hi Roger,

Are you using xb2net of the httpclient of Xbase++? Are you using http or https?
Best regards,

Chris.
www.aboservice.be

User avatar
rdonnay
Site Admin
Posts: 4774
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: A web service for your data

#3 Post by rdonnay »

This is 100% Xbase++ code.

I have one configuration that uses https and the other 2 are http, because they are on private networks.

Here is a portion of the code:

Code: Select all

soHttpEndpoint := MyHttpEndpoint():new(nPort)

IF 'HTTPS:' $ Upper(scPublicHost)
  lStarted := soHttpEndpoint:setCertificateFromFile( DC_Curpath() + "\TaxiFleetNyc.pfx","pwd................l")
ENDIF

* ==============

CLASS MyHttpEndpoint FROM HttpEndpoint

EXPORTED:

METHOD defaultProcessors
METHOD start

ENDCLASS

METHOD MyHttpEndpoint:start()

RETURN SUPER:start()

* ---------

METHOD MyHttpEndpoint:defaultProcessors()

LOCAL aRet := SUPER:DefaultProcessors()
AAdd( aRet , "MyHtmlFileProcessor" )

RETURN(aRet)

* ------------

CLASS CustomWebHandler FROM WebHandler

EXPORTED:

VAR startTime

INLINE METHOD GetVar( cVarName )
RETURN ::httpRequest:getForm():getVariable(cVarName)

INLINE METHOD SetErrorBlock()
// ::httpRequest:setAcceptCharset( "utf8" ) // specific charset
ErrorBlock({|e|::LogError(e,self)})
RETURN self

// Dispatch the request to existing methods. Return a generic
// web page for all other requests.
//
INLINE METHOD Execute( cMethodName )

LOCAL cResponse := "", oError, cLog, aStack

::setErrorBlock()

IF IsMethod(SELF, cMethodName)

  scMethod := cMethodName

  AssignUser('1099','WebApp')

  ::startTime := Seconds()

  IF ::validate()
    WebID(1) // Store new WebID
    cResponse := SUPER:execute( cMethodName )

    IF Left(cResponse,3) = '500'
      wtf cResponse, Time() COLOR GRA_CLR_RED
    ENDIF

    WebID(2) // Clear WebID
    dbCloseAll()
  ELSE
    cResponse := '401 (Unauthorized)'
  ENDIF

  ::setErrorBlock()

  RETURN cResponse
ENDIF

cResponse += "<!DOCTYPE html>"
cResponse += "<html>"
cResponse +=   "<head><title>Unhandled request</title></head>"
cResponse +=   "<body>"
cResponse +=     "<h2>No handler for: "+cMethodName+"</h2>"
cResponse +=     "<small>Sorry</small>"
cResponse +=   "</body>"
cResponse += "<html>"

RETURN cResponse

METHOD LogError

ENDCLASS

* =====================

CLASS WebService FROM CustomWebHandler

  EXPORTED:

  METHOD ParamsSetData
  METHOD GetForm
  METHOD ResponseFormat
  METHOD Restart
  METHOD Validate
  METHOD Ping
  METHOD Crash
  METHOD Write2Log
  METHOD ExecuteFunction
  METHOD KioskDriverSearch
  METHOD KioskDriverUpdate
  METHOD KioskDriverSignature
  METHOD KioskDriverPhoto
  METHOD KioskDriverBankAccount
  METHOD KioskHelp
  METHOD KioskIsHack
  METHOD KioskGetForm
  METHOD KioskSendSms
  METHOD KioskDeleteDriver
  METHOD KioskEvent
  METHOD KioskGetReceipts
  METHOD KioskGetReceiptsPdf    // Receive array of Receipt numbers, echo receipt number array of ids
  METHOD KioskEmailReceipts     // Echo receipt number array of ids, subject, array of email addresses
  METHOD KioskForceErrorDriverUpdate
  METHOD KioskGetLeaseRecord
  METHOD TwilioSMSReceived
  METHOD TwilioSMSStatus
  METHOD ImageJpg
  METHOD ValidateUSPSAddress

ENDCLASS
The eXpress train is coming - and it has more cars.

Victorio
Posts: 633
Joined: Sun Jan 18, 2015 11:43 am
Location: Slovakia

Re: A web service for your data

#4 Post by Victorio »

Hi Roger,
Because I am using DBFCDX, I am interesting about it. Will be this on next update subscription (price ?) ? Or how can I examine it on future ?

Viktor

User avatar
rdonnay
Site Admin
Posts: 4774
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: A web service for your data

#5 Post by rdonnay »

Will be this on next update subscription (price ?)
Yes, it will. But I am going to also make this available to anyone on this forum, because it is basically a sample program that works with most Xbase++ 2.0 releases that have web classes like HttpEndpoint, WebHandler, HttpClient and functions like Var2Json, Json2Var.

It will need customizing for your specialized application, but that is simply showing how to write your own EndPoint Methods and they would all follow a simple and common structure.

I will also install a version of the WebService on the donnay-software.com server that you can test with your own web browser or other web client.

I started this topic because I wanted to see how much interest there is out there in the Xbase++ legacy world.
The eXpress train is coming - and it has more cars.

User avatar
rdonnay
Site Admin
Posts: 4774
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: A web service for your data

#6 Post by rdonnay »

Here is a simple client program that I used to test the SQLQuery endpoint that I wrote for a customer.
His data is all DBFNTX.

Code: Select all

#INCLUDE "dcdialog.CH"

FUNCTION Main()

LOCAL GetList[0], cSql := "", cSite, oHttp, cResponse, oResp, cDomain, nMaxRows := 10

cDomain := DC_IniRead('WebClient.ini','SYSTEM','host')

cSite := "http://" + cDomain + ":8082/webservice/sqlquery"

cSql := "Select code, cou_id1 from cus"

DO WHILE .t.

  @ 0,0 DCSAY cSite FONT '10.Lucida Console Bold' SAYSIZE 0

  @ 1,0 DCMULTILINE cSql SIZE 100,5 FONT '10.Lucida Console'

  @ 7,0 DCSAY 'Max Rows' GET nMaxRows SAYSIZE 0

  DCREAD GUI FIT TITLE 'SqlQuery' ADDBUTTONS TO lStatus

  IF Empty(cSql) .OR. !lStatus
    RETURN nil
  ENDIF

  oHttp := HttpClient():new(cSite)

  oHttp:setMethod('POST')
  oHttp:httpRequest:setParameter( 'SQL', cSql )
  oHttp:httpRequest:setParameter( 'MaxRows', nMaxRows )
  oHttp:httpRequest:setParameter( 'RespType', 'JSON' )

  cResponse := oHttp:send()
  oResponse := Json2Var(cResponse)

  wtf cResponse, oResponse pause

  IF IsMemberVar(oResponse,'data')
    wtf oResponse:data pause
  ENDIF

ENDDO

return nil

* --------

PROC appsys ; RETURN
The eXpress train is coming - and it has more cars.

Wolfgang Ciriack
Posts: 481
Joined: Wed Jan 27, 2010 10:25 pm
Location: Berlin Germany

Re: A web service for your data

#7 Post by Wolfgang Ciriack »

I am very interessed in seeing the samples and demo.
_______________________
Best Regards
Wolfgang

Koverhage
Posts: 151
Joined: Mon Feb 01, 2010 8:45 am

Re: A web service for your data

#8 Post by Koverhage »

I am too
Klaus

k-insis
Posts: 120
Joined: Fri Jan 28, 2011 4:07 am

Re: A web service for your data

#9 Post by k-insis »

Same .

Will licensed release be shipped with source as with Express?


Koverhage wrote: Wed Apr 10, 2024 10:33 pmI am too

User avatar
rdonnay
Site Admin
Posts: 4774
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: A web service for your data

#10 Post by rdonnay »

Will licensed release be shipped with source as with Express?
Everything I have ever included with eXpress++ or other donations have always included source code.

This is the way of the world today, and it makes all of us better.

I guess I will need to give this a higher priority, because I received more interest in this than expected.

The basic code base is complete and has been tested for over 2 years.
Now I just need to put together a sample for all of you to test with.
The eXpress train is coming - and it has more cars.

Post Reply