Class wwJsonServiceClient

Class to make it super easy to call JSON REST services with Visual FoxPro. Use it standalone with the CallMethod() method to call a service directly, or - better - create a subclass and build a dedicated service class implementation.

For a more detailed look please check out the following blog post:

You can use this class to:

  • Directly call JSON REST services
  • Subclass it and implement service methods that map a service

Directly call a JSON REST Service

The direct approach just uses the CallService() method directly.

*** Load dependencies
do wwhttp
do wwJsonSerializer

loProxy = CREATEOBJECT("wwJsonServiceClient")

*** Optional - get access to HTTP client to set headers
* loHttp = loProxy.CreatewwHttp()
* loHttp.AddHeader("Authorization","Bearer 54321")

lcUrl = "http://albumviewer.west-wind.com/api/albums"
lvData = ""      && FoxPro value, object, collection
lcVerb = "GET"   && HTTP Verb

*** Make the service call - returns a Collection of objects
loAlbums = loProxy.CallService(lcUrl,lvData,lcVerb)

IF (loProxy.lError)
   ? loProxy.cErrorMsg
   RETURN
ENDIF   

*** Iterate the collection
lnCount = loAlbums.Count

*** First Album object
? loAlbums.Item(1).Title

*** Iterate
FOR EACH loAlbum in loAlbums 
   ? loAlbum.Title  + ;
     " by " + loAlbum.Artist.ArtistName + ;
     " (" +  TRANSFORM(loAlbum.Tracks.Count) + " tracks)"
   FOR EACH loTrack IN loAlbum.Tracks
		? "  " + loTrack.SongName
   ENDFOR
ENDFOR

Note that you can also pass data to the service. JSON REST endpoints that expect data typically expect a single JSON parameter - which can be an object with many sub properties - to represent input values. To pass a parameter, simply provide a FoxPro object that maps the structure of the JSON expected by the service and this class will serialize the FoxPro object/value into JSON for you.

Creating a Service Proxy Class

To use, subclass this class and implement your service methods that then uses CallService() to call JSON service endpoints.

DEFINE CLASS CustEomerServiceClient as wwJsonServiceClient

cServiceBaseUrl = "http://localhost:23332/localizationService.ashx?method="

FUNCTION GetResourceSets()
    LOCAL loResult
    loResult = loClient.CallService(this.cServiceBaseUrl + "GetResourceSets")

    IF (this.lError)
       RETURN .NULL.
    ENDIF
    
    RETURN loResult
ENDFUNC

FUNCTION UpdateResource(loResource)
    LOCAL loResult, loSerializer
    
    *** Optional - get serializer to override settings
    loSerializer = loProxy.CreateSerializer()
    loSerializer.PropertyNameOverrides = "resourceId,resourceValue"

    *** Service returns update resource
    loResult = loClient.CallService(this.cServiceBaseUrl + "UpdateResource",loResource,"PUT")

    IF (this.lError)
       RETURN NULL
    ENDIF
    
    RETURN loResult
ENDFUNC

ENDDEFINE

To use this you would then just use:

loProxy = CREATEOBJECT("CustomerServiceClient")



loResources = loProxy.GetResources()
if ISNULL(loResources)
   ? loProxy.cErrorMsg
   RETURN
ENDIF   

? loResources.Count
? loResources.Item(0).Locale
? loResources.Item(0).Text


loResource = GetMyResourceToUpdateFromSomewhere()
loResource = loProxy.UpdateResource(loResource)

if !llResult
   ? loProxy.cErrorMsg
   RETURN
ENDIF   

? loResource.ResourceId
? loResource.Locale
? loResource.Text

This latter approach is preferrable as it treats service access like a business object where all logic created around the service is created in one place. It allows you to reuse the service calls and isolate your error handling and future maintenance all in one place.

Class Members

MemberDescription

CallService

o.CallService(lcUrl,lvData,lcVerb)

CreateSerializer

o.CreateSerializer(loSerializer)

CreatewwHttp

o.CreatewwHttp(loHttp)

Example


************************************************************************
DEFINE CLASS CustomerServiceClient as wwJsonServiceClient
*********************************************************

************************************************************************
*  GetCustomers
***************
FUNCTION Customers(loParms)
LOCAL loCustomers

loCustomers = THIS.CallService(this.cServiceBaseUrl + "customers.csvc", loParms)

IF THIS.lError
   RETURN null
ENDIF   

RETURN loCustomers
ENDFUNC
*   GetCustomers

************************************************************************
*  UpdateCustomer
*****************
FUNCTION UpdateCustomer(loCustomer)

loCustomer = THIS.CallService(this.cServiceBaseUrl + "customer.csvc",loCustomer,"PUT")

IF THIS.lError
   RETURN null
ENDIF 

RETURN loCustomer
ENDFUNC
*   UpdateCustomer

ENDDEFINE

Requirements

Assembly: wwJsonSerializer.prg • wwHttp.prg (dependency)

See also:

Class wwJsonServiceClient

© West Wind Technologies, 1996-2018 • Updated: 03/05/18
Comment or report problem with topic