Tags:
create new tag
view all tags

Data API

The Data API provides a set of tools you can use to have your APPX applications respond to web based queries.


Overview

The Data API is a collection of tools that will allow you to easily write subroutines that can respond to web based requests. It is designed to provide an interface between the APPX runtime environment and Web-based services such as a Web server or a mobile application.

Prerequisites

The Data API requires:

  • A sever running nodejs 10 or higher, and a web server
  • An installation of version 5.5 or higher of the APPX runtime environment
  • A dedicated APPX username/password set up in the APPX runtime environment for logins
  • A dedicated APPX Login Manager instance to login to the APPX runtime environment as an APPX user

Installation/Removal

First, define a new user in the APPX User file. This should NOT be an account that is also an O/S user. Assign the user a password using the 'Change Aux Password' button.

Next, unzip the 'dataservices.zip' file into the $APPXPATH/services directory.

Install the required Node JS modules (run this as root or an Administrator):

npm install --loglevel=error

Several nodejs modules will be installed

Install the APPX Data Services service instance. Replace items in <> with values of your choice, for example:

<webport> = The port you want to the API to listen on.
<portnumber> = The login manager port of your APPX server. This is the port you defined for the Data API, not your normal login port. See "Manually installing a new APPX Login Manager Service Instance" below.
<appx username> = the user you defined above (not an OS user). This is the APPX user the API will log in as.
<appx password> = the password of the user defined in APPX
<appxhost> = the host name of your APPX server
<name> = The name you want to use for this service (optional)
<configuration file name> = the name of a configuration file that contains the parameters. This file is created when you remove the Data API and provides you a quick way to re-install using the previous settings

The install service command:

node servicectl.js install -p <webport> --appxhost=<hostname> --appxport=<portnumber> --appxuser=<appx username> --appxpass=<appx password>


Examples:

node servicectl.js install -p 3000 --appxhost=myhost --appxport=8161 --appxuser=Test --appxpass=password

To install from a saved configuration file:

node servicectl.js install --configfilename=default-3000.json.bak

After installation a configuration file will be created in the 'config' subdirectory of the APPX Data Services directory. That configuration file is a JSON formatted file and will be named default-xxxxx.json where xxxxx is the <webport> number specified on the during installation. The configuration file is where you can change the parameters that were specified during the installation.

Also, you can change other parameters that weren’t specified during installation such as whether to use SSL and the SSL certificate file and its key file.

For example:

To specify that SSL be used on the web interface change:
"enablessl": true
in the "AppConfig" section.

To specify that SSL be used on the APPX login manager interface change:
"enablessl": true
in the "ProviderConfig" section.

To sepcify the SSL certificate and key files for Windows change:

"systemcert": "C:\\Certs\\myhost.crt",
"certificatepath": "C:\\Certs\\myhost.crt",
"privatekeypath": "C:\\Certs\\myhost.key",

and for Linux set;

"systemcert": "/opt/certs/myhost.crt",
"certificatepath": "/opt/certs/myhost.crt",
"privatekeypath": "/opt/certs/myhost.key",

in the "AppConfig" section.

Removal

The remove service command:

node servicectl.js remove --p=<webport>

Example:

node servicectl.js remove --p=3000

After removal, the there will be a backup copy of the configuration file created in the APPX Data Services directory service with a .bak extension. This backup copy can be used for reinstallation of a APPX Data Services instance as shown above.

Creating a Persistent Authentication Token

For faster logins you can create a persistent authentication token that can be used in place of the appxuser and appxpassword. To create that token, run the script as shown below, after substituting <username> with the actual name of the user:


node createPAT.js --username=<username>

After creating the token, copy it into the APPX login manager 'tokens' directory.

Then, in the configuration file, change the "ProviderConfig" section parameter as follows: "appxtoken": <token file name>
Next, in the "ProviderConfig" section change the following: "appxuser": "" and "appxpass": ""
Finally, stop and then restart the APPX Data Services service

Manually installing a new APPX Login Manager Service Instance

On a new APPX installation, you had the opportunity to set up a Data API port. If you did not do that, or if you are upgrading from a previous version, you will have to manually add the Data API login. Use the command line examples below to do this. These commands should be executed in the APPX login manager executable directory.

Replace items in <> with values of your choice, for example:
<service name> = AppxDSLoginManager -8161
<service display name> = AppxDSLoginManager -8161
<portnumber> = 8161
<full path to appx engine executable> = for Linux: /opt/appxserver/appx | for Windows: c:\appx\Appx.exe
<path to the appx data directory> = for Linux: /opt/appxserver/data | for Windows: c:\appx\data

Linux:
sudo ./appxLoginMgr -install -name=<service name> -displayName="<service display name>" -SockPort=<portnumber> -engine=<full path to appx engine executable> -AuthenticationMethod=Appx-User -ImpersonateGroup=NamedGroup\(appxgrp\) -ImpersonateUser=NamedUser\(appx\) -AppxProcessName=WEBSERVICES -AppxProcessType=SUBROUTINE -AppxApplication=0LA -ServiceType=data APPXPATH=<path to the appx data directory> APPX_KEYMAP=Windows
Example:
sudo ./appxLoginMgr -install -name=AppxDSLoginManager-8161 -displayName="AppxDSLoginManager-8161" -SockPort=8161 -engine=/opt/appxserver/appx -AuthenticationMethod=Appx-User -ImpersonateGroup=NamedGroup\(appxgrp\) -ImpersonateUser=NamedUser\(appx\) -AppxProcessName=WEBSERVICES -AppxProcessType=SUBROUTINE -AppxApplication=0LA -ServiceType=data APPXPATH=/opt/appxserver/data APPX_KEYMAP=Windows

Windows:
cmd /c "appxLoginMgr.exe -install -name=<service name> -displayName=<service display name> -SockPort=<portnumber> -engine=<full path to appx engine executable> -AppxApplication=0LA -AppxExecutable=c:\appx55\Appx.exe -AppxProcessName=WEBSERVICES -AppxProcessType=SUBROUTINE -AuthenticationMethod=Appx-User -ServiceType=data APPXPATH=<path to the appx data directory> APPX_KEYMAP=Windows"
Example:
cmd /c "appxLoginMgr.exe -install -name=AppxDSLoginManager-8161 -displayName=AppxDSLoginManager-8161 -SockPort=8161 -engine=c:\appx\Appx.exe -AppxApplication=0LA -AppxExecutable=c:\appx\Appx.exe -AppxProcessName=WEBSERVICES -AppxProcessType=SUBROUTINE -AuthenticationMethod=Appx-User -ServiceType=data APPXPATH=c:\appx\data APPX_KEYMAP=
Windows"

Testing the APPX Data Services interface for connectivity

Once installed, you can test connectivity by entering the URL's below in a web browser or by using curl (Note: curl is available by default in Windows 10 since 5/2019).

To test connectivity between the browser/curl and APPX Data Services (Note: replace items in <> with the value of your host/ip and webport) use these examples. These do not require Services to be defined in APPX:

https://<myhost>:<webport>/DsTest (Note: will return the value OK)

https://<myhost>:<webport>/DsVer (Note: will return the APPX Data Services version number in JSON format {i.e. {"Data Services Version":"1.0.0.20021010"}
})

https://<myhost>:<webport>/DsDate (Note: will return the APPX Data Services service current date/time in in JSON format {i.e."LocalDateTime":" 02/10/2020 15:43:31"},{"UtcDateTime":" 02/10/2020 20:43:31"} ))

Note: If you don't have SSL enabled in the "AppConfig" section remove the 's' in https

To test connectivity between the browser/curl and the APPX runtime environment via the APPX Data Services service use these examples. You must have defined the example services first, see 'Adding your Services' below:

https://<myhost>:<webport>/api/DateTest (Note: will return the APPX runtime current date/time in JSON format {i.e. {"DateTime":"02/10/20 15:46 04"} ))

https://<myhost>:<webport>/api/GetApps (Note: will return a list of applications on your server in JSON format {i.e. {"id":"Application Design","label":"0AD 00 - Application Design","value":"0AD"},... etc, } )

https://<myhost>:<myport>/api/GetApps?ver=00 (Note: will return all available APPX applications who's version number = '00' in JSON format {i.e. {"id":"Application Design","label":"0AD 00 - Application Design","value":"0AD"},... etc, } )

https://<myhost>:<myport>/api/GetApps?prefix=1 (Note: will return all available APPX applications who's name prefix = '1' in JSON format {i.e. {"id":"ChartDirector Examples","label":"1CD 00 - ChartDirector Examples","value":"1CD"},... etc, } )

https://<myhost>:<myport>/api/GetApps?ver=00&prefix=1 {Note: will return in JSON format {i.e. {"id":"ChartDirector Examples","label":"1CD 00 - ChartDirector Examples","value":"1CD"},... etc, } )

https://<myhost>:<myport>/api/GetFiles?ap=DMO&ver=00 (Note: will return the files of an APPX application in JSON format {i.e. {"id":"Sales Activity Transactions..","label":"ACTIVITY - Sales Activity Transactions..","value":"ACTIVITY"},... etc, } )

https://<myhost>:<myport>/api/GetFiles?ap=DMO&ver=00&prefix=A (Note: will return the files of an APPX application in JSON format {i.e. {"id":"Sales Activity Transactions..","label":"ACTIVITY - Sales Activity Transactions..","value":"ACTIVITY"},... etc, } )

https://<myhost>:<myport>/api/GetFields?ap=DMO&ver=00 (Note: will return the fields of an APPX application in JSON format {i.e. {"id":"Employee Responsible","label":"ACTIVITY ADDED BY - Employee Responsible","value":"ACTIVITY ADDED BY"},... etc, } )

https://<myhost>:<myport>/api/GetFields?ap=DMO&ver=00&prefix=CONTACT (Note: will return the fields of an APPX application in JSON format {i.e. {"id":"Added By","label":"CONTACT ADDED BY - Added By","value":"CONTACT ADDED BY"},... etc, } )

If you have not yet added the example services, then it should just return {"Error":"Command not in SERVICE"}.

If you do not want to open <webport> on your server, you can set up a reverse proxy in your web server. Instructions vary by web server and platform, consult your documentation.

Adding Your Own Services

Before you can do anything useful with the Data API, you will have to create the services and add them to the 0SA Services file under System Administration ->Configuration -> Data Services. The first time you run this, you will be given the option of adding the example services. We recommend you accept that option so you have some examples to work with:

services.png

Services are always written as an APPX subroutine. The 'Service Cmd' is the command the remote client must put in the URL, ie, https://<hostname>:<webport>/api/<ServiceCmd&gt;. If the Database is not specified here, then it must be specified on the URL, ie, https://<hostname>:<webport>/api/<ServiceCmd>?db=<APPXDatabaseId&gt;.

Subroutine Guidelines

When the Data API is invoked, it will:

  • Open the necessary stream files, including a debug log if APPX_DATASVC_LOG is specified and points to a writeable file
  • Parse the command line
  • Validate the service name and Database Id (either from the command line or Service file) and return any errors
  • Determine which service is being requested
  • If the service is valid it will invoke the appropriate subroutine or return an error if not valid
  • Close all the stream files at the completion of the subroutine.
Your subroutine can use various APIs to retrieve command line parameters, write responses, log errors, etc: The format of the data returned to the caller is up to you and the caller to agree on. The Data API makes no assumptions about the format, although all the examples return data in JSON format.

Here is a simple example to return the current date/time:

      PASS         TEST DATE                  FIELD            SHARE? N
      GOSUB    --- .DATA DEBUG LOG
      *
      SET DATE --- WORK DATE TIME
      CNV TEXT --- TEMP 80                    =  --- WORK DATE TIME
      SET      --- STREAM BUFFER              =      { "DateTime": "
      APPEND   --- STREAM BUFFER              0  --- TEMP 80
      APPEND   --- STREAM BUFFER              0      " }
      GOSUB    --- .DATA WRITE STREAM

Since there are no parameters to this routine, it does not need to use .DATA GET PARAM VALUE to extract them or .DATA BAD REQUEST to return any errors. Consult the subroutines in 1EX for more complicated examples. Note the subroutine does not end with a RETURN statement. Your subroutine will be invoked via a SUBR command, so it should either have an explicit END command, or simply run out of code (as in this example).

Your subroutine can do whatever it needs to in order to return the requested data. If you are going to be using the .STREAM APIs, do not use stream names of SOCKET-IN, SOCKET-OUT or DEBUG. These are reserved for the Data API.

Troubleshooting

  • You cannot use a normal login service for this, you must set up a separate data login service. A normal login service will not work.
  • Make sure the <appxport> points to this new data login service, not your normal login service.
  • Make sure you specify both <appxuser> and <appxpass> when you create the service.
  • Make sure the <appxuser> and <appxpass> you specified can log on to APPX.
  • You can point APPX_DATASVC_LOG to a file to get a log.

Using Received Data

To make use of incoming data when that data is a single record (or single item), use the .DATA GET PARAM VALUE subroutine to retrieve each value. That will only work for single records, though. However, the API can also be used to import files in json format. Read through the --- RAWJSON memory file, and look for records where RAWJSON PATH is /data/{VariableName} - the specified data will be in RAWJSON VALUE. All are alpha fields, of course. Since json files are sequential, you can identify which field will start each record and which will end it. When you get to the last file, or when all required fields are nonblank, you can write into your target file or take whatever steps are necessary.

Sample code, importing a json file with multiple records, each with two fields containing Airline Codes and Airline Names:

      BEG READ --- RAWJSON                HOLD 0 KEY IS  RAWJSON SNO
      IF       --- RAWJSON PATH               EQ     /data/AirlineCode
T     SET      SYS AIRLINE CODE               =  --- RAWJSON VALUE
      IF       --- RAWJSON PATH               EQ     /data/AirlineName
T     SET      SYS AIRLINE NAME               =  --- RAWJSON VALUE
T     WRITE    SYS AIRLINE                FAIL 0
      END READ --- RAWJSON

Here's a curl statement that will work to call that subroutine, assuming the subroutine is connected in Data Services to the name "SampleAPI":

curl -H "Content-Type: application/json" --data-binary @/airlineinfo.json https://serverURL.com/api/SampleAPI

Comments


-- Jean Neron - 2020-03-03

Edit | Attach | Watch | Print version | History: r4 < r3 < r2 < r1 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r4 - 2020-08-13 - AlKalter
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback