Home » Company » Blog » Using the DataFlex REST Library

Using the DataFlex REST Library

(Originally published on the DataFlex Wiki)

6 of 6

The simple example of a RESTful service set out in the article A Simple RESTful Service involved quite a bit of work to produce an API for only one table.

An alternative approach is to use the REST library I have created, which can be downloaded from here.

To use it, unzip that file into some directory, then, from the workspace you are developing in, use that as a library; in the Studio choose: Tools -> Maintain Libraries… -> Add Library, then navigate to where you unzipped it and within it select the “RESTLibrary.sws” file.

That will add a new section to the Studio’s Class Palette entitled “REST”.

With the WebApp project selected in the Studio, choose: File -> New -> Other -> DataFlex Source File, naming it, for this example, “WebOrderAPI”, which will create a blank package file. Into that, from the new REST section of the class palette, drag an object of the cRESTfulService class. Rename the object oWebOrderAPI.

Then again choose: File -> New -> Other -> DataFlex Source File, this time naming it ApiCustomersHandler. Into that blank file drag an object of the cRestResourceHandler class. Change the object’s name to oApiCustomersHandler and set its psInterfacePath property (an empty string by default) to “customers“.

Then in the DDO Explorer pane (lower-right in the Studio by default) click the “+” book icon (Add DDO: ) and select the cCustomerDataDictionary.

Drag a cRESTApiObject from the class palette to below the comment “Add your cRESTApiObjects here“. Rename it to “oCustomers”. Set its phoDD property to oCustomer_DD, its psCollName (collection name) property to “customers” (plural) and its psInstName (instance name) property to “customer” (singular).

Uncomment one of the “Send AddListColumn” lines and change its “Table.Column” to Customer.Customer_Number, then copy that line and make the copy for Customer.Name. (You can keep adding those to your heart’s content, but lists should be sparing of such detail.)

Go back to your WebOrderAPI file and under the comment line: ‘Add “Use” statements for your cResourceHandler objects here:’ add the line: “Use APICustomersHandler.pkg“.

For development you may want to change the pbVerboseErrors setting to True, although for deployment it should probably be set back to False, to avoid confusing users with a pile of technical detail, which they neither should, nor want to, be exposed to.

You should perhaps, for future-proofing a real API, change the psPath setting from its default of “api” to “api/v1” (to provide for v2, v3 and so on in the future) – Note: this will change the URL which you use to make calls to it.

That should leave you with (some additional comments are mine):

WebOrderAPI.pkg:

Use cRESTfulService.pkg
 
Object oWebOrderAPI is a cRESTfulService
    Set psPath to "api/v1"       // Changed to provide for future versions
    Set pbVerboseErrors to True  // For development only, return to False for deployment
     
    // Add "Use" statements for your cResourceHandler objects here:
    Use APICustomersHandler.pkg  // You add this line
     
    Procedure APIRoot
        Handle hoResp
         
        Get CreateJsonObject to hoResp
        Send AddRegisteredCollections hoResp        
         
        Send OutputJson hoResp
    End_Procedure
     
    Procedure ProcessHttpRequest String sVerb
        String sPart0
         
        Get PathPart 0 to sPart0
        Move (Lowercase(sPart0)) to sPart0
         
        Case Begin
         
            Case ((sVerb = C_httpGet) and (sPart0 = ""))
                Send APIRoot
                Case Break
             
            Case (IsRegisteredPath(Self, sPart0))
                Send AutoProcess sPart0
                Case Break
         
            Case Else
                Send UnrecognisedOperation
                Case Break
         
        Case End
         
    End_Procedure
 
End_Object

The overall structure with your web app will be something like this (although the diagram includes additional cRESTResourceHandler objects and cRESTApiObjects, making up a fuller API):

Security

This example does not have any security built into it yet, but the cRESTfulService class does understand a bit about Basic Auth, so we can add the following short OnPreRequest procedure to the oWebOrderAPI object:

Procedure OnPreRequest String sVerb String sPath
    tBasicAuthCredentials tCreds
    Boolean bOK
     
    Set psUsername to ""  // Reset it to blank at the start of *every* request
    Get BasicAuthCredentials to tCreds
     
    If (tCreds.sUserName <> "") Begin
        Clear WebAppUser
        Move tCreds.sUserName to WebAppUser.LoginName
        Find Eq WebAppUser by Index.1
         
        If (Found) Begin
            Move (ComparePasswords(ghoWebSessionManager, Trim(WebAppUser.Password), ;
                                                         tCreds.sPassword)) to bOK
                                                          
            If bOK ;
                Set psUsername to tCreds.sUserName
        End
         
    End
     
End_Procedure

As you can see, that relies on the ComparePasswords function of the WebSessionManager object, which will not be present in a Basic Web Project, so if using such, you would have to replace that, perhaps with a simple:

Move (Trim(WebAppUser.Password) = Trim(tCreds.sPassword)) to bOK

Which assumes that you are not using encrypted passwords, however how to handle those is left as an exercise for the reader!

Then at the top of the file add “Open WebAppUser“, while at the top of the oWebOrderAPI object add “Property String psUsername“.

Finally, right at the beginning of the ProcessHttpRequest procedure add:

If (psUsername(Self) = "") Begin
    Send BasicAuthRequired "Web Order API"
    Procedure_Return
End

Fuller instructions for creating an API using the REST library can be found in my course notes from Synergy 2019, although complete documentation for the library has sadly yet to make it to the top of my ToDo pile (it will be a lot of work).

6 of 6

See also

Leave a Reply