Web Services |
Web Services is the exchange of information between applications using the standard Web protocol for browsers. As a consumer, you can obtain information provided on the Web such as the weather conditions and access information provided by other Web-based applications. As a service provider, you can allow other applications to access your information and accept requests for information from other applications. With PxPlus, you can be a consumer of Web services, a provider of services or both.
Refer to the information below on Web requests, using the PxPlus utility "*plus/web/request" for Submitting a Web Request, and oAuth2 Authorization.
Web messages (HTTP/HTTPS) have two main components: a header that describes the message and a body that contains the message. The header consists of simple concise text lines of Keyword: Value and primarily defines content size, type, source and destination.
The processing of Web requests begins with a URL:
http://target-system-name/target...?parameters
Where:
target can be either a physical file or a process/program.
The two basic types of requests are:
GET Request |
Requests the contents of a target from the server | |
POST Request |
Sends some data (i.e. a form) to a specific target on the server |
Example:
The following is an example of a Web request:
URL:
http://www.pvxplus.com/pgsrvr.pvp?pg=products
A request is sent to the system www.pvxplus.com.
The request sent is a GET of the file pgsrvr.pvp.
The server assesses the request to determine the action that is needed; i.e. whether it must send back the contents of the file or run the file and return its results. In this example, the .pvp tells the server to run the file.
When running the file, the target will be passed the parameters pg=products.
The result of what the program outputs is displayed by the browser.
REST (Representational State Transfer) is a set of commonly used design principles for Web services that adheres to the following fundamental design requirements:
The criteria behind using REST design is to avoid using parameters. REST requests should expose a directory-like structure in URI (Uniform Resource Identifier).
Example:
Below is an example of how this can be done via the Apache Web Server by configuring aliases to map:
http://yoursite.com/services/qry.pxp?lib=xxx&panel=yyy&type=HTML
to
http://yoursite.com/services/query/xxx/yyy/html
PxPlus Web Services are designed to conform to the REST design principles.
PxPlus provides the following utility for submitting a request with data and returning the result:
"*plus/web/request"
The *plus/web/request utility supports secure (HTTPS://) and unsecure (HTTP://) requests. It uses HTTP version 1.1 protocol to make Web requests and receive responses. If necessary, *plus/web/request can be forced to use HTTP version 1.0 protocol by defining the global variable %web_request_http_ver$ as "1.0".
(Support for the use of HTTP version 1.1 protocol was added in PxPlus 2021.)
The default request is a GET if no data is provided; otherwise, a POST is used. The following eight entry points for additional request types are available: GET, POST, DELETE, PUT, TRACE, OPTIONS, PATCH and HEAD. This utility also allows you to specify the content type, custom SSL certificate and additional headers.
CALL"*plus/web/request", url$, postdata$, recvdata$, recvhdr$, mimetype$, certificate$, extrahdrs$, method$, timeout
Where:
|
url$ |
Specifies target server and if secure or non-secure |
|
postdata$ |
Data to send to the server |
|
recvdata$ |
String variable to receive response |
|
recvhdr$ |
Header of response received |
|
mimetype$ |
Optional content type of data |
|
certificate$ |
Optional path of certificate, if needed |
|
extrahdrs$ |
Optional additional headers to include on send |
|
method$ |
HTTP request method |
|
timeout |
Timeout value (if not provided, defaults to 15 seconds) |
(The timeout option was added in PxPlus 2020.)
The header describes the message and contains information about the transmission. The "*plus/web/request" utility includes the use of extra headers, which are typically used for authorization information, cookies and the From email name. Extra headers can also be used to include an if-modified-since request, which allows the Web service to send data if it has changed; otherwise, it will return an error 304.
UNIX/Linux provides the 'curl' command that allows you to make Web requests from a Command line. A typical 'curl' command line would look as follows:
curl https://instance_name.salesforce.com/services/data/v31.0/-H 'Authorization: Bearer sessionID' –d client=123456 >Respfile
Compare this to using a *plus/web/request:
CALL "*plus/web/request",
"https://instance_name.salesforce.com/services/data/v31.0/","client=123456", Resp$,Hdr$,"","","Authorization: Bearer sessionID"
To access PxPlus Web Services, a Web server must be operating and configured to run PxPlus programs. PxPlus Web Services can run on either the PxPlus EZWeb Server or the Apache Web Server.
PxPlus EZWeb Server
The PxPlus EZWeb Server handles Web Services by default without additional configuration. See EZWeb Server.
Apache Web Server
The Apache Web Server must first be configured to run PxPlus programs. See Apache Interface for instructions on configuring Apache.
The next step is to configure the Apache Web Server to handle PxPlus Web Services by adding the following lines to the httpd.conf file:
#uncomment out this line
LoadModule rewrite_module modules/mod_rewrite.so
SetEnv TEMP /tmp
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
Alias /services/rgraph/ "/pxplus/lib/_plus/inomads/add-ons/charts/rgraph/"
<Directory "/pxplus/lib/_plus/inomads/add-ons/charts/rgraph/">
Options Indexes FollowSymLinks
AllowOverride None
# Use line below for Apache 2.4 and later
Require all granted
# Use next 3 lines below for Apache 2.2 and earlier
# Order allow,deny
# Allow from all
# DirectoryIndex index.html
</Directory>
Alias /services/ "/pxplus/lib/_web/services/"
<Directory "/pxplus/lib/_web/services/">
Options Indexes FollowSymLinks
AllowOverride None
# Use line below for Apache 2.4 and later
Require all granted
# Use next 3 lines below for Apache 2.2 and earlier
# Order allow,deny
# Allow from all
# DirectoryIndex index.html
</Directory>
RewriteEngine On
RewriteRule "/do/([^/]+)/(.*)" "/services/do.pxp?id=$1&args=$2" [B,PT]
The "*obj/oauth2" object performs oAuth2 authorization with third-party Web services. It allows you to get authorized with Web services, such as Google, Salesforce or any Web service that uses oAuth2 authorization.
You set up a UserID/Client with the Web service provider. They will provide you with a Client ID and a secret code, as well as two URLs: one to the Authorization server, and one to the Token server. Once you have this information, the process consists of two stages:
• The First stage is to have the user grant your application (based on Client ID and secret code) access to an account of the provider.
• The Second stage is where you can access the user data from the server.
You can use the PVX Plus hosted oAuth2 agent or self-host the oAuth2 agent if you want to avoid relying on the PVX Plus servers being up.
See *OBJ/OAUTH2 object.
(Support for self-hosting the oAuth2 agent was added in PxPlus 2023.)
Example:
! This is an example of doing a fill authorization
clientID$="this_should_be_your_client_id"
clientSecret$="this_should_be_your_client_secret"
!
! Init oAuth2 object
oAuth2=new("*obj/oauth2")
oAuth2'Service$="salesforce"
oAuth2'client_id$=clientID$
oAuth2'client_secret$=clientSecret$
!
oAuth2'Enable_Certification("Do you consent to allow access of your Salesforce account to example app?")
!
! Wait a little for it to process
wait 1
!
! Get user logon URL
url$=oAuth2'Get_Authorization_URL$()
!
! Open login URL in users default browser
system_helpurl$
!
! Wait for user to complete sign-in and allow us access
input "Press any key to continue after logging into account and allowing PxPlus access:",*;
print ""
!
oAuth2'Get_Access_token() ! Gets a short lived token
!
! Save the refresh token
serial "token",err=*next
open purge (hfn)"token"
print (lfo)oAuth2'Refresh_token$
close (lfo)
! Set this into header for all subsequent requests
extrahdr$="Authorization: Bearer "+oAuth2'Access_token$
! Response ALSO included which server has users data
dim oAuth2$
dim load oAuth2${all}=oAuth2'jsonData$
! So we need to derive the system that has the user data
base_url$=oAuth2$["instance_url"]+"/services/data/v30.0"
drop object oAuth2 ! Done with this object
! So now let us run a query
q$="SELECT NAME FROM Account"
url$=base_url$+"/query/?q="+cvs(q$,"ASCII:URL")
call "*plus/web/request",url$,"",resp$,resphdr$,"","",extrahdr$
dim json$
dim load json${all}=resp$
print "Formatted reply:",'LF',dim(list edit json${all})