SASjs Adapter¶
The SASjs adapter is a JS library and a set of SAS Macros that handle the communication between the frontend app and backend SAS services.
There are three parts to consider:
- JS request / response
- SAS inputs / outputs
- Configuration
JS Request / Response¶
To install the library you can simply run npm install @sasjs/adapter
or include a <script>
tag with a reference to our CDN.
Full technical documentation is available here. The main parts are:
Instantiation¶
The following code will instantiate an instance of the adapter:
let sasJs = new SASjs.default(
{
appLoc: "/Your/SAS/Folder",
serverType:"SAS9"
}
);
SAS Logon¶
The login process can be handled directly, as below, or as a callback function to a SAS request.
sasJs.logIn('USERNAME','PASSWORD'
).then((response) => {
if (response.isLoggedIn === true) {
console.log('do stuff')
} else {
console.log('do other stuff')
}
}
Request / Response¶
A simple request can be sent to SAS in the following fashion:
sasJs.request("/path/to/my/service", dataObject)
.then((response) => {
// all tables are in the response object, eg:
console.log(response.tablewith2cols1row[0].COL1.value)
})
let dataObject={
"tablewith2cols1row": [{
"col1": "val1",
"col2": 42
}],
"tablewith1col2rows": [{
"col": "row1"
}, {
"col": "row2"
}]
};
There are optional parameters such as a config object and a callback login function.
The response object will contain returned tables and columns. Table names are always lowercase, and column names uppercase.
The adapter will also cache the logs (if debug enabled) and even the work tables. For performance, it is best to keep debug mode off.
SAS Inputs / Outputs¶
The SAS side is handled by a number of macros in the macro core library.
The following snippet shows the process of SAS tables arriving / leaving:
/* fetch all input tables sent from frontend - they arrive as work tables */
%webout(FETCH)
/* some sas code */
data some sas tables;
set from js;
run;
%webout(OPEN) /* open the JSON to be returned */
%webout(OBJ,some) /* `some` table is sent in object format */
%webout(ARR,sas) /* `sas` table is sent in array format, smaller filesize */
%webout(OBJ,tables,fmt=N) /* unformatted (raw) data */
%webout(OBJ,tables,dslabel=newtable) /* rename tables on export */
%webout(OBJ,tables,dslabel=truncated, maxobs=10) /* send back max 10 rows */
%webout(CLOSE) /* close the JSON and send some extra useful variables too */
Configuration¶
Configuration on the client side involves passing an object on startup, which can also be passed with each request. Technical documentation on the SASjsConfig class is available here. The main config items are:
appLoc
- this is the folder under which the SAS services will be created.serverType
- eitherSAS9
orSASVIYA
.serverUrl
- the location (including http protocol and port) of the SAS Server. Can be omitted, eg if serving directly from the SAS Web Server, or in streaming mode.debug
- iftrue
then SAS Logs and extra debug information is returned.useComputeApi
- iftrue
and the serverType isSASVIYA
then the REST APIs will be called directly (rather than using the JES web service).contextName
- if missing or blank, anduseComputeApi
istrue
andserverType
isSASVIYA
then the JES API will be used.
The adapter supports a number of approaches for interfacing with Viya (serverType
is SASVIYA
). For maximum performance, be sure to configure your compute context with reuseServerProcesses
as true
and a system account in runServerAs
. This functionality is available since Viya 3.5. This configuration is supported when creating contexts using the CLI.
Using JES Web App¶
In this setup, all requests are routed through the JES web app, at YOURSERVER/SASJobExecution
. This is the most reliable method, and also the slowest. One request is made to the JES app, and remaining requests (getting job uri, session spawning, passing parameters, running the program, fetching the log) are made on the SAS server by the JES app.
{
appLoc:"/Your/Path",
serverType:"SASVIYA"
}
Using the JES API¶
Here we are running Jobs using the Job Execution Service except this time we are making the requests directly using the REST API instead of through the JES Web App. This is helpful when we need to call web services outside of a browser (eg with the SASjs CLI or other commandline tools). To save one network request, the adapter prefetches the JOB URIs and passes them in the __job
parameter.
{
appLoc:"/Your/Path",
serverType:"SASVIYA",
useComputeApi: true
}
Using the Compute API¶
This approach is by far the fastest, as a result of the optimisations we have built into the adapter. With this configuration, in the first sasjs request, we take a URI map of the services in the target folder, and create a session manager - which spawns an extra session. The next time a request is made, the adapter will use the 'hot' session. Sessions are deleted after every use, which actually makes this less resource intensive than a typical JES web app, in which all sessions are kept alive by default for 15 minutes.
{
appLoc:"/Your/Path",
serverType:"SASVIYA",
useComputeApi: true,
contextName: 'yourComputeContext'
}