This API document is designed for JavaScript developers using LOC Studio and/or LOC CLI.
LOC provides a range of agents (built-in JavaScript drivers) for data processes so that you can access internal session storage data, events or external APIs, databases at run-time.
Be noted that most LOC agents are asynchronous, so it is recommended to use await
to tackle them properly.
ctx
and ctx.task
ctx
is the context object injected by LOC into generic/aggregator logics at run-time.
You can access task-related information from ctx.task
:
Attributes | Type |
---|---|
currentLogic |
{ permanentIdentity: name; name: string; revision: number } |
dataProcess |
{ permanentIdentity: name; name: string; revision: number } |
executedLogics |
{ permanentIdentity: name; name: string; revision: number }[] |
startAt |
string (Date) |
taskId |
{ executionId: string; id: string } |
Example:
ctx.payload.http
ctx.payload.http
has the following attributes:
Attributes | Type | Example |
---|---|---|
apiGatewayIdentityContext |
{ id: string; name: string } | |
apiIdentityContext |
{ id: string; name: string } | |
body |
number[] | |
headers |
{ [name: string]: unknown; } | {"content-type":"application/json"} |
host |
string | |
method |
string | "POST" |
path |
string | /hello/greeting |
query |
string | ?param=data... |
requestId |
string | |
scheme |
string | https |
version |
string | "HTTP/1.1" |
You can read the request body from API routes like this:
For instance, if you have this JSON input that is going to be inserted into the request body,
After using the code snippets mentioned above, you can access them like this:
The JSON input will be stored in a constant variable body
after you invoke the API route with that request body. Hence, whilst querying body.name
and body.age
, you can expect the returns to be "Arthur" as a string and 42 as a number, respectively.
For example, if you send a GET request with the following QueryString:
You can extract the parameters like this:
ctx.agents.http.get(url, headers, contentType, body, config=null)
Send a HTTP GET request.
Parameters | Type | Description |
---|---|---|
url |
string | URL |
headers |
{ header1: value1; … } | HTTP Headers |
contentType |
string | "None" , "PlantText" , "Json" or "Form" |
body |
Uint8Array or null | Request body (optional only for get() ) |
config (optional) |
object | { acceptInvalidCerts: true/false } |
There are a series of agents corresponding to HTTP methods (the parameters are exactly the same):
Agents | HTTP Methods |
---|---|
ctx.agents.http.get() |
GET |
ctx.agents.http.post() |
POST |
ctx.agents.http.patch() |
PATCH |
ctx.agents.http.put() |
PUT |
ctx.agents.http.delete() |
DELETE |
All of the HTTP agents will return a Http.Response
object with the following attributes:
Attributes | Type | Description |
---|---|---|
status |
number | HTTP status code |
headers |
{ header1: value1; … } | Response headers |
body |
Uint8Array | Response body |
Example:
With the code snippets above, you are allowed to store the data from HTTP into a constant variable body
for future use.
See HTTP Agent Request Examples for more code examples.
Read and write temporary data between logics during the same execution task of a data process.
Please note that the data kept via this way (session storage) can only be accessed by the same data process. The data would also be cleaned up once the data process finishes the task.
If you want to keep data between tasks, use local storage instead.
If you feel like exchanging the data between other data processes, we suggest you use event emission to keep the data and event search to query the events.
ctx.agents.sessionStorage.putJson(key, value)
Put JSON data in the session storage.
Parameters | Type | Description |
---|---|---|
key |
string | key of session data |
value |
any | JSON object |
Example:
ctx.agents.sessionStorage.putString(key, value)
Put a string in the session storage.
Parameters | Type | Description |
---|---|---|
key |
string | key of session data |
value |
string | string data |
Example:
ctx.agents.sessionStorage.putByteArray(key, value)
Put a byte array in the session storage.
Parameters | Type | Description |
---|---|---|
key |
string | key of session data |
value |
Uint8Array | byte array |
ctx.agents.sessionStorage.get(key)
Read data by key from the session storage.
Parameter | Type | Description |
---|---|---|
key |
string | key of session data |
Example:
data
will be the same type as what you put in the session storage.
ctx.agents.sessionStorage.remove(key)
Remove (delete) a data from session storage.
Parameter | Type | Description |
---|---|---|
key |
string | Data key |
Send and query events between data processes.
See concepts to know more about LOC events.
Also, you CANNOT use event agents in Aggregator logics. Instead, you can only use them in generic logics.
ctx.agents.eventStore.emit(events)
Emit event(s) into the event store.
Parameter | Type | Description |
---|---|---|
events |
object array | events |
Example:
The maximum length of meta
is 215 bytes. You can convert a JSON object to a string using JSON.stringify()
and store it in meta
:
ctx.agents.eventStore.search(request)
Search and read event(s) from the event store.
Parameter | Type | Description |
---|---|---|
request |
object array | request parameters |
Example:
The query field name here is different with the ones you have used in ctx.agents.eventStore.emit()
. See Event Field Comparison Table for reference.
events
is an array of Event
objects. Each Event
has the following attributes:
Attributes | Type | Description |
---|---|---|
idataProcessIdentityContext |
{ name: string; permanentIdentity: string; revision: number; } | |
executionId |
string | Execution ID |
label |
{ id: number; name: string } | Event ID and name |
logicIdentityContext |
{ id: number; name: string } | |
meta |
string | Meta data |
sequence |
number | Sequence Number |
sourceDigitalIdentity |
string | Source DID |
targetDigitalIdentity |
string | Target DID |
taskId |
string | Task ID |
timestamp |
string | |
type |
string | Event group |
ctx.agents.eventStore.searchWithPattern(request)
Search sequences of events, for which 1st event has to fit 1st condition, 2nd event has to fit 2nd condition…so on.
Parameter | Type | Description |
---|---|---|
request |
object array | request parameters |
Example:
Since we are search sequences of events, you MUST provide at least two sequence patterns (each pattern contains at least one condition).
The events
above is an array similar to the one in the ctx.agents.eventStore.search()
example.
Operators | Description |
---|---|
"Eq" |
equal to (==) |
"NotEq" |
not equal to (!=) |
ctx.agents.database.connect({databaseDriver, connection=null})
Create a database object.
Parameters | Type | Description |
---|---|---|
databaseDriver |
string | Name of the driver. See DB Driver List |
connection |
object | DB Connection parameters |
For more examples of connecting with other databases, please refer to Local Database Testing with Simple Runtime.
database.connect()
Parameters)LOC currently provides the following built-in database drivers:
Database | databaseDriver | connection | |
---|---|---|---|
MySQL | "MySQL" or database.Driver.MySql |
new database.MySqlParameters (connectionInfo) |
|
PostgresSQL | "Postgres" or database.Driver.Postgres |
new database.PostgresParameters(connectionInfo) |
|
MS SQL Server | "MSSQL" or database.Driver.Mssql |
new database.MssqlParameters(connectionInfo) |
connectionInfo
ParametersParameter | Type | DB |
---|---|---|
host |
string | All (default: lodalhost ) |
port |
number | All (default: MySQL - 3306 , Postgres - 1521 , MSSQL - 1433 ) |
database |
string | All |
username |
string | All |
password |
string | All |
trustCert (optional) |
boolean | MSSQL |
options (optional) |
string | Postgres |
connectTimeout (optional) |
number | Postgres |
keepalives (optional) |
boolean | Postgres |
keepalivesIdle (optional) |
number | Postgres |
Please be noted that database.connect()
will check the connection
object. If you use an connection object which contains incorrect or unsupported parameters, an "missing connection information"
error will be thrown.
db.query(rawSql, params)
Execute a SQL query.
Parameter | Type | Description |
---|---|---|
rawSql |
string | SQL prepared statement |
params |
array | SQL query parameters |
Example:
SQL prepared statement separates parameters from the SQL statement in order to stop SQL injection. Please be noted that SQL syntax in prepared statement may differ on different databases.
db.query()
returns a Database.QueryResults
objcet with the following attributes:
Attributes | Type | Description |
---|---|---|
columns |
{ name: string; type: string }[] | Selected columns name and data type |
rows |
{ key1: any; key2 : any; … }[] | Selected rows |
db.execute(rawSql, params)
Execute a SQL statement.
Example:
db.disconnect()
Disconnect the database.
db.beginTransaction()
db.commitTransaction()
db.rollbackTransaction()
Execute/rollback a SQL statement in a transaction.
These transaction functions are based on Transact-SQL thus can only be used for MSSQL.
Example:
Access a remote file via HTTP, FTP (File Transfer Protocol) or SMB (Server Message Block) protocols.
Note: the file storage agent does not invoke SMB protocol directly. Instead, you need to provide the connection info of your SMB service (including Amazon S3) to the FST Network team. These info will be configured in your Kubernetes environment. The LOC core will handle the login and serves as a file broker between data processes and the SMB server.
A S3 URL looks like this:
Where <secret-access-key>
should be percent-encoding.
For more information, please contact FST Network.
ctx.agents.fileStorage.simpleGet(url)
Read a remote file. (For HTTP it's a GET request.)
Parameter | Type | Description |
---|---|---|
url |
string | HTTP/FTP/SMB URL |
The returned value is a Uint8Array
.
Example:
ctx.agents.fileStorage.simplePut(url, data)
Write data into a remote file. (For HTTP it's a PUT request.)
Parameters | Type | Description |
---|---|---|
url |
string | HTTP/FTP/SMB URL |
data |
Uint8Array | Content to be written into the file |
Example:
ctx.agents.fileStorage.delete(url)
Delete a remote file. (For HTTP it's a DELETE request.)
Parameter | Type | Description |
---|---|---|
url |
string | HTTP/FTP/SMB URL |
ctx.agents.fileStorage.list(url)
List all files under a directory. (Not available for HTTP file requests.)
Parameter | Type | Description |
---|---|---|
url |
string | FTP/SMB URL |
Returns Array<FileStorage.FileType>
. A FileType
has the following attributes:
Attributes | Type | Description |
---|---|---|
type |
string | "file" , "directory" or "symbolicLink" |
file |
string | name of the file/dir/symbolic link |
Example:
ctx.agents.fileStorage.createDirAll(url)
Create a new directory at specified location.
Parameter | Type | Description |
---|---|---|
url |
string | FTP/SMB URL |
Send a email via a SMTP server.
ctx.agents.smtp.connect(host, username, password)
Connect to a SMTP server and returns a smtp object.
Parameter | Type | Description |
---|---|---|
host |
string | SMTP host URL |
username |
string | SMTP username |
password |
string | SMTP password |
Example:
smtp.send(mail)
Send a email with the SMTP object.
For setSender()
, setReceivers()
and similar methods, the second name parameter can be omitted:
Local Storage is very similar to session storage. The difference is that the data can be persistent between tasks of the same data process (session data will be purged after each task).
Just like session storage, a local storage data saved by one data process cannot be accessed by other data processes. The data would also be purged if you re-deploy the data process.
Local Storage can ONLY be used in generic logics (not available in aggregator logics).
ctx.agents.localStorage.putJson(key, value, timeout)
Write a JSON data into local storage.
Parameters | Type | Description |
---|---|---|
key |
string | Data key |
value |
object | JSON data |
timeout (optional) |
number | Time limit (seconds) for persisting the data. Default: null (unlimited) |
Example:
ctx.agents.localStorage.putString(key, value, timeout)
Write a string into local storage.
Parameters | Type | Description |
---|---|---|
key |
string | Data key |
value |
string | String |
timeout (optional) |
number | Time limit (seconds) for persisting the data. Default: null (unlimited) |
ctx.agents.localStorage.putByteArray(key, value, timeout)
Write a byte array into local storage.
Parameters | Type | Description |
---|---|---|
key |
string | Data key |
value |
Uint8Array | Byte array |
timeout (optional) |
number | Time limit (seconds) for persisting the data. Default: null (unlimited) |
ctx.agents.localStorage.get(key)
Read a data from local storage.
Parameter | Type | Description |
---|---|---|
key |
string | Data key |
Example:
ctx.agents.localStorage.remove(key)
Remove (delete) a data from local storage.
Parameter | Type | Description |
---|---|---|
key |
string | Data key |
ctx.agents.logging.error(value)
ctx.agents.logging.info(value)
Log a error or general message:
Parameter | Type | Description |
---|---|---|
value |
string of object | Log message |
The message can either be a string or a JSON object.
Example:
Be warned that ctx.agents.logging
cannot parse non-JSON objects and will throw error. You can convert the object to string first:
Generally error()
(for reporting errors) and info()
(for general messages) are enough for most situations. But you can also use warn()
for something that is not an error but still requires attention:
Agent | Log level/severity |
---|---|
ctx.agents.logging.error(value) |
Highest |
ctx.agents.logging.warn(value) |
|
ctx.agents.logging.info(value) |
Lowest |
Log outputs can only be seen from the LOC Kubernetes environment or via Local Simple Runtime Execution.
ctx.agents.result.finalize(value)
Write a customised result of the data process task, and the API route will aggregate the task results of the execution this time.
Parameter | Type | Description |
---|---|---|
value |
object | string or JSON object |
Example:
The result would be included as part of the actual API response:
The data process would always return "_status":200
even though there are errors occurred.
If you see "_status":202
, it may be that the data process/API route are just deployed and are not ready yet. If you see this repeatly, it may be something went wrong in the LOC itself so the data process can never finish its task.
See: Session Storage
See: Error Logging
LOC Studio
LOC CLI