# NodeJS

## Introduction

You can find all necessary Code for Download and Changelogs always here:

{% embed url="<https://github.com/3qnexx/APIClient-NodeJS>" %}

The NodeJS SDK for the nexxOMNIA API needs at least NodeJS 16.\* as Environment.

{% hint style="info" %}
Starting with Version 1.5.0, the SDK needs NodeJS 18.\* as Environment, **18.15+** is highly recommended.

The last Version supporting V16 is Version **1.3.1**. Install this Version, if your Environment uses a NodeJS Version < 18.0.
{% endhint %}

```javascript
npm install nexxomnia-api-nodejs
```

```javascript
const {APIClient} = require("nexxomnia-api-nodejs");
```

A very simple Example could be

```javascript
const {APIClient, MediaCall, streamtypes} = require("nexxomnia-api-nodejs");

let apiclient = new APIClient();
apiclient.configure(999,"API-SECRET","SESSION-ID");

let apicall = new MediaCall(streamtypes.VIDEO);
apicall.latest();

let result = await apiclient.call(apicall);

let obj=result.getResultIterator(true);
for(let el of obj){
    console.log(el.getGeneral().getID());
}
```

## General Usage

For any API Call, two Classes have to be instantiated. The **`APIClient`**&#x68;as to be created only once and configured with the target Domain ID, the Domain Secret and (in most Cases) a valid Session ID - in most cases, that would be the Management Session ID.

The **`APIClient`**&#x77;ill execute a valid **`APICall`**. There are many different **`APICall`**&#x43;lasses for different Aspects of the API, but they all work in a similar Way.

All API Methods, as described in this Documentation, are available on the corresponding **`APICall`**&#x43;lass. In most cases, the **`APICall`**&#x43;lass Method is "humanized" and the Naming is less technical.

Nearly every API Method can be configured by Parameters and/or Modifiers. Consequently, each **`APICall`** Class exposes a **`getParameters()`** and a **`getModifiers()`** Method, which return Helper Classes for easier accessing the correct Parameters here:

```javascript
let apicall = new MediaCall(streamtypes.VIDEO);
apicall.getParameters().setLimit(50);
apicall.getParameters().set("limit",50);
```

In this simple Example, the basic Way to set Parameters is shown (the **`set`**&#x4D;ethod). Every valid Parameter though has also an explicit Setter (here **`setLimit`**), which additionally check Consistency and Validity of the given Parameter.

Methods with unique Parameters (like in the **/manage** API Endpoint), expose these Parameters directly on the Method and handle the necessary Parameter Logic themselves.

The call Method of the **`APIClient`** takes the configured API Call and directly starts it. It returns an Instance of the **`APIResult`** Class then, which can be handled like this:

```javascript
let result = apiclient.call(apicall);

if(result.isSuccess()){

    result.getRawResponse();
    result.getResult();
    
    if(result.supportsResultObject()){
        result.getResultObject();
    }
    
    if(result.supportsIterator()){
        result.getResultIterator(true);
    }

}else{
    console.log(result.getMetadata().getErrorHint());
}
```

The **`APIResult`**&#x43;lass can directly return the received JSON via **`getRawResponse`**- or, only the "result" Part of the Response via **`getResult`**.

For more advanced Usage, it can also return an Instance of the **`ResultObject`**&#x43;lass, which allows to query the JSON in a more human Way:

```javascript
id = result.getRawResponse()["result"]["general"]["ID"];
id = result.getResultObject().getGeneral().getID();
```

Especially the media API returns very often Lists of Media Objects. For Iterating directly over the JSON Array, the result Class exposes an Iterator via **`getResultIterator`**. The Iterator itself can return the pure JSON Objects or **`ResultObject`** Class Instances as above.

## Creating new Elements

### Media Creation via API

The SDK allows also to create new Media. Technically, there are Media Types, that need an initial File (like a Video), and Media Types, that exist of Data alone (an Article for example).

File-driven Media Types can be created by giving a URL, that the API will use to download and process the Input and create an Item from it:

```javascript
let videoURL="https://example.com/video.mp4";

let apicall = new MediaManagementCall();
apicall.setStreamtype(streamtypes.VIDEO);
apicall.createFromURL(videoURL);

let result = apiclient.call(apicall);

if(result.isSuccess()){
    // the ID of the new Video via ResultObject:
    videoID = result.getResultObject().getGeneratedID();

    // or via JSON Objects: 
    videoID = result.getResult()['itemupdate']['generatedID'];
}
```

Data-driven Media Types will be created like this:

```php
let apicall = new MediaManagementCall();
apicall.setStreamtype(streamtypes.ARTICLE);
apicall.createFromData("Article Title","Article Refnr");

let result = apiclient.call(apicall);

if(result.isSuccess()){
    // the ID of the new Article via ResultObject:
    articleID = result.getResultObject().getGeneratedID();

    // or via JSON Objects: 
    articleID = result.getResult()['itemupdate']['generatedID'];

}
```

###

### Creating Structure Elements

Structure Elements like Channels, Formats and Categories are not Media Items. They exist on the Domain Level only and can be created like Data-driven Elements via API:

```javascript
let apicall = new DomainManagementCall();
apicall.addChannel({'title':'Channel','refnr':'123','parent':0,'pos':1});

let result = apiclient.call(apicall);

if(result.isSuccess()){
    // the ID of the new Channel
    channelID = result.getResultObject().getGeneratedID();

    // or via JSON Objects: 
    channelID = result.getResult()['itemupdate']['generatedID'];

}
```

The Attributes for this Example are listed in the Domain Management API:

{% content-ref url="../management-api/endpoints/domain-management" %}
[domain-management](https://api.docs.nexx.cloud/management-api/endpoints/domain-management)
{% endcontent-ref %}

### Media Creation via UploadHandler

Alternatively, you can upload a local File directly with the **`UploadHandler`**&#x43;lass:

```javascript
const {APIClient, UploadHandler} = require("nexxomnia-api-nodejs");

let localPath="/var/www/myfolder/video.mp4";

let uploadhandler = new UploadHandler();
uploadhandler.setAPIClient(apiclient);

let apiresult = uploadhandler->uploadMedia(localPath,streamtypes.VIDEO);

//the UploadHandler returns an API Result, that can be used as usual
let videoID = apiresult.getResultObject().getGeneratedID();
```

### Using the UploadHandler

Besides the pure Upload of new Media Files, the UploadHandler offers even more Helpers for all API Endpoints, that need a phsyical File (like Covers and Captions):

```javascript
let coverPath="/var/www/myfolder/cover.jpg";
let captionPath="/var/www/myfolder/caption.vtt";

let uploadhandler = new UploadHandler();
uploadhandler.setAPIClient(apiclient);

uploadhandler.setMediaCover(coverPath,streamtypes.VIDEO,videoID);
uploadhandler.addMediaCaptions(captionPath,streamtypes.VIDEO,videoID,"es");
```

## Available APICall Classes

### Media API

The most important Difference to other Classes here is the need for setting the target Streamtype (in the Constructor or via explicit Method). By default, the Class uses "video" as Streamtype. You can use the Enum Class **`streamtypes`** to be sure or just use a String.

```javascript
apicall.setStreamtype(streamtypes.IMAGE);
```

The Media API offers by far the highest Amount of Modifiers and Parameters, which are exposed as described above. It also nearly always returns Lists of Media, which implies using the Interator Object on the result Class.

Very often, it is necessary to get all possible Results in one Array. The API itself does not return more than 100 Elements per Call, but if all possible Results are needd, the **`call`**&#x4D;ethod of the **`APIClient`**&#x6F;ffers a second Parameter, which will handle the Parameters and Interating over the API Responses to construct a **`APIResult`**&#x4F;bject with indeed all Result Objects.

{% content-ref url="../media-api" %}
[media-api](https://api.docs.nexx.cloud/media-api)
{% endcontent-ref %}

### Management APIs

As the Management API offers by far the most Methods, the API Client offers MediaManagement and DomainManagement Classes for the corresponding Method Helpers.

Like the Media API, the Classes offer a **`setStreamtype`**&#x61;nd a **`setItem`**&#x4D;ethod, which is extremely helpfull especially on Media Management, where one specific Media Item of a specific Streamtype should be modified.

{% content-ref url="../management-api/endpoints/management-endpoint" %}
[management-endpoint](https://api.docs.nexx.cloud/management-api/endpoints/management-endpoint)
{% endcontent-ref %}

{% content-ref url="../management-api/endpoints/media-export-management" %}
[media-export-management](https://api.docs.nexx.cloud/management-api/endpoints/media-export-management)
{% endcontent-ref %}

{% content-ref url="../management-api/endpoints/domain-management" %}
[domain-management](https://api.docs.nexx.cloud/management-api/endpoints/domain-management)
{% endcontent-ref %}

### Statistics API

The Statistics API returns in nearly every case lists of Key=>Value Pairs. Therefore, the Usage of the **`getResult`**&#x4D;ethod of the **`response`**&#x4F;bject is is most cases sufficient.

Please notice, that some Methods can return huge Lists. As Paging is not supported in this API, you can set the Limit to higher Values (like 100000). Furthermore, this API might take longer than all other APIs, as it returns realtime Data. The apiclient therefore sets a Timeout of 30 Seconds by default, it Endpoints of this API are called. It is possible though to raise this Value even more:

```javascript
apiclient.setTimeout(60);
```

{% content-ref url="../management-api/endpoints/statistics-endpoint" %}
[statistics-endpoint](https://api.docs.nexx.cloud/management-api/endpoints/statistics-endpoint)
{% endcontent-ref %}

###

### Domain API

The Domain API exposes various structural Objects, that are connected to a Domain. The classic Example is a List of Channels via **`getChannels`**. In most Cases, the response should be iterated over with an Iterator, but as most Lists are very short and Paging is (in most Cases) not supported, the **`getResult`**&#x4D;ethod is enough.

{% content-ref url="../management-api/endpoints/domain-endpoint" %}
[domain-endpoint](https://api.docs.nexx.cloud/management-api/endpoints/domain-endpoint)
{% endcontent-ref %}

###

### System API

The System API is very straight forward, as it basically only returns Objects/Arrays of System Constants. The Usage of the **`getResult`**&#x4D;ethod of the **`APIResponse`**&#x4F;bject is is most cases sufficient.

{% content-ref url="../management-api/endpoints/system-endpoint" %}
[system-endpoint](https://api.docs.nexx.cloud/management-api/endpoints/system-endpoint)
{% endcontent-ref %}

###

### Session API

The Session API is available in the SDK, but in nearly every Case, this Backend SDK should use the constant "Management Session", given by 3Q. Nevertheless, it is possible to start and extend Sessions with this Class, if needed.

{% content-ref url="../frontend-api/endpoints/session-endpoint" %}
[session-endpoint](https://api.docs.nexx.cloud/frontend-api/endpoints/session-endpoint)
{% endcontent-ref %}

### Processing API

The most important Method of the Processing API is the MultiTask Method, which allows to query multiple API Endpoints at the same time. To make sure, the Parameters are built correctly, each Task, that is given to the Method is itself a Class. It is used like this:

```javascript
let apicall = new ProcessingCall();

let tasks = [];
let task = new Task("task-1");
task.setEndpoint(streamtypes.AUDIO);
task.setMethod("byid");
task.setItem(999);
tasks.push(task);

apicall.multiTask(tasks);
```

{% content-ref url="../media-api/endpoints/processing-endpoint" %}
[processing-endpoint](https://api.docs.nexx.cloud/media-api/endpoints/processing-endpoint)
{% endcontent-ref %}

## Custom APICall

For advanced Usage, you can omit all predefined Methods and Helpers and use a custom APICall. Please notice, that in this Case, you have to be very sure about the right Endpoints, Methods, HTTP Verbs and Parameters.

```javascript
let apicall = new CustomCall();
apicall.setVerb(defaults.VERB_GET);
apicall.setPath("/videos/byid/123");
apicall.getParameters().set("additionalFields","channel");
```
