# Definicja API Rest

## Definicja odpowiedzi <a href="#id-restapi-wolaniezewnetrznychuslugrestowych-scriptcode-definicjaodpowiedzi" id="id-restapi-wolaniezewnetrznychuslugrestowych-scriptcode-definicjaodpowiedzi"></a>

API obsługuje **TYLKO** usługi RESTowe, które zwracają typ **`application/json`** .

Domyślny ContentType z jakim wysyłamy zapytania do usługi to **`application/json.`** Obsługiwany jest również **`multipart/form-data,`** jeżeli w nagłówku zostanie przekazany parametr **`{'Content-Type': 'multipart/form-data'}.`** Na przykład:

```
api.rest.v1.get('serviceId', {queryParams: {'key': 'value'}}, {'Content-Type': 'multipart/form-data'});
```

Odpowiedź z usługi wygląda następująco:

```json
{
    status: {
        code: int,
        message: String
    },
    headers: Map<String, String>,
    body: Map<String, Object>
}
```

Wszystkie elementy w odpowiedzi są przetworzone jako natywne zmienne w JavaScript. Można się do nich dostać np. w ten sposób:

```
response.status.code   // <--- uzyskanie wartości z pola `code`, zawierającego kod odpowiedzi, np. 200
response.status.message   // <--- uzyskanie wartości z pola `message`, zawierającego wiadomość odpowiedzi, np. "Accepted"
 
response.headers.language    // <---  uzyskanie wartości nagłówka zwrotnego o nazwie `language`
 
response.body.user.type    // <--- uzyskanie wartości konkretnego pola z odpowiedzi, gdzie odpowiedź ma wygląd: {"user": {"type": "typUzytkownika"}}
```

## Definicja wyjątku

W przypadku innego kodu zwrotnego, niż 2XX dostaniemy wyjątek możliwy do obsłużenia.\
Np. w sytuacji z kodem 404 (usługa nie dostępna lub błędny adres), kod 405 (niepoprawna metoda) lub kod 500 (błąd wewnętrzny po stronie usługi).

Wyjątek wygląda następująco:

```
{
    status: {
        code: int,
        message: String
    },
    body: String
}
```

Aby zweryfikować, czy jest to wyjątek do obsłużenia przez nas, możemy sprawdzić, czy złapany element posiada pola, które nas interesują.

```javascript
try {
    // zawołaj usługę zewnętrzną
} catch (exception) {
    if (exception.status !== undefined && exception.status.code !== undefined) {
        // obsługa naszego wyjątku, np. zwrócenie wartości domyślnej
    } else {
        // to nie jest nasz wyjątek, możemy go obsłużyć lub puścić dalej
        throw exception;
    }
}
```

## Definicja żądania <a href="#id-restapi-wolaniezewnetrznychuslugrestowych-scriptcode-definicjazadania" id="id-restapi-wolaniezewnetrznychuslugrestowych-scriptcode-definicjazadania"></a>

Żądanie może zostać sparametryzowane.

Żądania mogą zawierać payload:

```
api.rest.v1.post(SERVICE_ID, PATH, HEADER, PAYLOAD, TIMEOUTS);
api.rest.v1.put(SERVICE_ID, PATH, HEADER, PAYLOAD, TIMEOUTS);
```

Oraz mogą być bez payloadu:

```
api.rest.v1.get(SERVICE_ID, PATH, HEADER, TIMEOUTS);
api.rest.v1.delete(SERVICE_ID, PATH, HEADER, TIMEOUTS);
```

Poniżej definicja parametrów:

```
SERVICE_ID: String;  // <--- np. 'mojServiceId'
 
HEADER: Map<String, String>;  // <--- np. {'mojHeader': 'wartosc'}
 
PAYLOAD: Map<String, Object>;  // <--- dowolny, poprawny obiekt, np. {'user': 123, 'name': 'Lisa'}
TIMEOUTS: Map<String, Integer>;  // <--- obiekt definiujący timeouty dla  wywoływanej usługi np. {connectionTimeout: 2000, readTimeout: 2000}
```

Definicja PATH wygląda następująco:

```
{
    pathParams: List<String>,   // <--- kolejne elementy namiaru na usługę, np. ['api', 'v1', 'path', 'to', 'endpoint'] dla /api/v1/path/to/endpoint
    queryParams: Map<String, String> // <--- należy pamiętać, że query params to zawsze string
}
```

Definicja TIMEOUTS wygląda następująco:

```
{
    connectionTimeout: Integer,   // <--- limit czasu nawiązywania połączenia w milisekundach
    readTimeout: Integer // <--- limit czasu odczytu odpowiedzi w milisekundach
}
```

{% hint style="danger" %}
**Brak TIMEOUTS**

W momencie gdy obiekt **TIMEOUTS** nie zostanie zdefiniowany dla wykonanego zapytania REST zostaną nadane wartości zaczerpnięte z konfiguracji. Znajdują się one w parametrach:

\<config>

\<eximee>\
\<restclient>\
\<connection-timeout>\
\<default>1000\</default>\
\<maximum>10000\</maximum>\
\</connection-timeout>\
\<read-timeout>\
\<default>10000\</default>\
\<maximum>30000\</maximum>\
\</read-timeout>\
\</restclient>\
\</eximee>

\</config>

<br>

Parametr:

* **default** określa wartość zaciąganą gdy obiekt **TIMEOUTS** nie zostanie zdefiniowany
* **maximum** określa maksymalną wartość jaką może ustawić LOW-CODE Developer podczas przygotowywania zapytania (jeśli ustawi większą niż podana zostanie ustawiona wartość **maximum**)
  {% endhint %}

Przykładowe wykonanie żądań znajdują się w sekcjach niżej.

## Żądania <a href="#id-restapi-wolaniezewnetrznychuslugrestowych-scriptcode-zadania" id="id-restapi-wolaniezewnetrznychuslugrestowych-scriptcode-zadania"></a>

Dla każdego z poniższych żądań zakładamy spójną konfigurację:

```xml
scriptservice:
  api:
    - serviceId: "serviceId"
      url: "http://moj.service/"
```

### GET <a href="#id-restapi-wolaniezewnetrznychuslugrestowych-scriptcode-get" id="id-restapi-wolaniezewnetrznychuslugrestowych-scriptcode-get"></a>

Żądanie bez payloadu.

Przykłady:

```
// curl -X GET http://moj.service/
api.rest.v1.get('serviceId', {}, {});
 
// curl -X GET http://moj.service/get/path
api.rest.v1.get('serviceId', {pathParams: ['get', 'path']}, {});
 
// curl -X GET http://moj.service/get?key=value
api.rest.v1.get('serviceId', {pathParams: ['get'], queryParams: {'key': 'value'}}, {});
 
// curl -X GET http://moj.service/get?key=value -H 'Header-Key: header-value'
api.rest.v1.get('serviceId', {pathParams: ['get'], queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'});
 
// curl -X GET http://moj.service/?key=value -H 'Header-Key: header-value'
api.rest.v1.get('serviceId', {queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'});
 
// curl -X GET http://moj.service/?key=value -H 'Header-Key: header-value' connectionTimeout: 2s readTimeout: 5s
api.rest.v1.get('serviceId', {queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'}, {connectionTimeout: 2000, readTimeout: 5000});
```

Oraz przykładowy ScriptService:

```
function callService(context) {
    const response = api.rest.v1.get('httpbin', {pathParams: ['get']}, {});
    const requestSize = response.headers['Content-Length'];
    return {'result': 'Wysłano żądanie o wielkości: ' + requestSize};
}
```

### DELETE

Żądanie bez payloadu.

Przykłady:

```
// curl -X DELETE http://moj.service/
api.rest.v1.delete('serviceId', {}, {});
 
// curl -X DELETE http://moj.service/delete/path
api.rest.v1.delete('serviceId', {pathParams: ['delete', 'path']}, {});
 
// curl -X DELETE http://moj.service/delete?key=value
api.rest.v1.delete('serviceId', {pathParams: ['delete'], queryParams: {'key': 'value'}}, {});
 
// curl -X DELETE http://moj.service/delete?key=value -H 'Header-Key: header-value'
api.rest.v1.delete('serviceId', {pathParams: ['delete'], queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'});
 
// curl -X DELETE http://moj.service/?key=value -H 'Header-Key: header-value'
api.rest.v1.delete('serviceId', {queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'});
 
// curl -X DELETE http://moj.service/?key=value -H 'Header-Key: header-value' connectionTimeout: 2s readTimeout: 5s
api.rest.v1.delete('serviceId', {queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'}, {connectionTimeout: 2000, readTimeout: 5000});
```

Oraz przykładowy ScriptService:

```
function callService(context) {
    const response = api.rest.v1.delete('httpbin', {pathParams: ['delete']}, {});
 
    if (response.status.code === 200) {
        return {'result': 'Usunięto poprawnie element'};
    } else {
        return {'result': 'Element został już usunięty, albo wystąpił inny problem'};
    }
}
```

### POST <a href="#id-restapi-wolaniezewnetrznychuslugrestowych-scriptcode-post" id="id-restapi-wolaniezewnetrznychuslugrestowych-scriptcode-post"></a>

Żądanie z payloadem.

Przykłady:

```
// curl -X POST http://moj.service/ -d '{}'
api.rest.v1.post('serviceId', {}, {}, {});
 
// curl -X POST http://moj.service/post/path -d '{}'
api.rest.v1.post('serviceId', {pathParams: ['post', 'path']}, {}, {});
 
// curl -X POST http://moj.service/post -d "{'user': 123, 'name': 'Lisa'}"
api.rest.v1.post('serviceId', {pathParams: ['post']}, {}, {'user': 123, 'name': 'Lisa'});
 
// curl -X POST http://moj.service/post?key=value -d '{}'
api.rest.v1.post('serviceId', {pathParams: ['post'], queryParams: {'key': 'value'}}, {}, {});
 
// curl -X POST http://moj.service/post?key=value -d '{}' -H 'Header-Key: header-value'
api.rest.v1.post('serviceId', {pathParams: ['post'], queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'}, {});
 
// curl -X POST http://moj.service/post?key=value -d "{'user': 123, 'name': 'Lisa'}" -H 'Header-Key: header-value'
api.rest.v1.post('serviceId', {pathParams: ['post'], queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'}, {'user': 123, 'name': 'Lisa'});
 
// curl -X POST http://moj.service/?key=value -d '{}' -H 'Header-Key: header-value'
api.rest.v1.post('serviceId', {queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'}, {});
 
// curl -X POST http://moj.service/?key=value -d "{'user': 123, 'name': 'Lisa'}" -H 'Header-Key: header-value'
api.rest.v1.post('serviceId', {queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'}, {'user': 123, 'name': 'Lisa'});
 
// curl -X POST http://moj.service/?key=value -d "{'user': 123, 'name': 'Lisa'}" -H 'Header-Key: header-value' connectionTimeout: 2s readTimeout: 5s
api.rest.v1.post('serviceId', {queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'}, {'user': 123, 'name': 'Lisa'}, {connectionTimeout: 2000, readTimeout: 5000});

// curl -X POST 'http://moj.service/post/multipartFormData' --form 'given_names="Lisa"' --form 'surname="Nowak"'
api.rest.v1.post('serviceId',{pathParams:['post','multipartFormData']},{'Content-Type': 'multipart/form-data'},{given_names:'Lisa',surname:'Nowak'})
```

Oraz przykładowy ScriptService:

```
function callService(context) {
    const response = api.rest.v1.post('httpbin', {pathParams: ['post']}, {}, {'user': {'name': 'Bernard'}, 'type': 'changeName'});
    const newName = response.body.json.user.name;
    return {'result': 'Nowe imię to: ' + newName};
}
```

### PUT

Żądanie z payloadem.

Przykłady:

```
// curl -X PUT http://moj.service/ -d '{}'
api.rest.v1.put('serviceId', {}, {}, {});
 
// curl -X PUT http://moj.service/put/path -d '{}'
api.rest.v1.put('serviceId', {pathParams: ['put', 'path']}, {}, {});
 
// curl -X PUT http://moj.service/put -d "{'user': 123, 'name': 'Lisa'}"
api.rest.v1.put('serviceId', {pathParams: ['put']}, {}, {'user': 123, 'name': 'Lisa'});
 
// curl -X PUT http://moj.service/put?key=value -d '{}'
api.rest.v1.put('serviceId', {pathParams: ['put'], queryParams: {'key': 'value'}}, {}, {});
 
// curl -X PUT http://moj.service/put?key=value -d '{}' -H 'Header-Key: header-value'
api.rest.v1.put('serviceId', {pathParams: ['put'], queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'}, {});
 
// curl -X PUT http://moj.service/put?key=value -d "{'user': 123, 'name': 'Lisa'}" -H 'Header-Key: header-value'
api.rest.v1.put('serviceId', {pathParams: ['put'], queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'}, {'user': 123, 'name': 'Lisa'});
 
// curl -X PUT http://moj.service/?key=value -d '{}' -H 'Header-Key: header-value'
api.rest.v1.put('serviceId', {queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'}, {});
 
// curl -X PUT http://moj.service/?key=value -d "{'user': 123, 'name': 'Lisa'}" -H 'Header-Key: header-value'
api.rest.v1.put('serviceId', {queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'}, {'user': 123, 'name': 'Lisa'});
 
// curl -X PUT http://moj.service/?key=value -d "{'user': 123, 'name': 'Lisa'}" -H 'Header-Key: header-value' connectionTimeout: 2s readTimeout: 5s
api.rest.v1.put('serviceId', {queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'}, {'user': 123, 'name': 'Lisa'}, {connectionTimeout: 2000, readTimeout: 5000});
```

Oraz przykładowy ScriptService:

```
function callService(context) {
    const response = api.rest.v1.put('httpbin', {pathParams: ['put']}, {}, {'name': 'Lisa', 'country': 'PL', 'birthday': '29-02-1999'});
    const userName = response.body.json.name;
    return {'result': 'Użytkownik został dodany do bazy. Imię użytkownika: ' + userName};
}

```

### PATCH

Żądanie z payloadem.

Przykłady:

```
// curl -X PATCH http://moj.service/ -d '{}'
api.rest.v1.patch('serviceId', {}, {}, {});
 
// curl -X PATCH http://moj.service/post/path -d '{}'
api.rest.v1.patch('serviceId', {pathParams: ['post', 'path']}, {}, {});
 
// curl -X PATCH http://moj.service/post -d "{'user': 123, 'name': 'Lisa'}"
api.rest.v1.post('serviceId', {pathParams: ['patch']}, {}, {'user': 123, 'name': 'Lisa'});
 
// curl -X PATCH http://moj.service/post?key=value -d '{}'
api.rest.v1.patch('serviceId', {pathParams: ['patch'], queryParams: {'key': 'value'}}, {}, {});
 
// curl -X PATCH http://moj.service/post?key=value -d '{}' -H 'Header-Key: header-value'
api.rest.v1.patch('serviceId', {pathParams: ['patch'], queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'}, {});
 
// curl -X PATCH http://moj.service/post?key=value -d "{'user': 123, 'name': 'Lisa'}" -H 'Header-Key: header-value'
api.rest.v1.patch('serviceId', {pathParams: ['patch'], queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'}, {'user': 123, 'name': 'Lisa'});
 
// curl -X PATCH http://moj.service/?key=value -d '{}' -H 'Header-Key: header-value'
api.rest.v1.patch('serviceId', {queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'}, {});
 
// curl -X PATCH http://moj.service/?key=value -d "{'user': 123, 'name': 'Lisa'}" -H 'Header-Key: header-value'
api.rest.v1.patch('serviceId', {queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'}, {'user': 123, 'name': 'Lisa'});
 
// curl -X PATCH http://moj.service/?key=value -d "{'user': 123, 'name': 'Lisa'}" -H 'Header-Key: header-value'  connectionTimeout: 2s readTimeout: 5s
api.rest.v1.patch('serviceId', {queryParams: {'key': 'value'}}, {'Header-Key': 'header-value'}, {'user': 123, 'name': 'Lisa'}, {connectionTimeout: 2000, readTimeout: 5000});
```

Oraz przykładowy ScriptService:

```

function callService(context) {
    const response = api.rest.v1.patch('httpbin', {pathParams: ['patch']}, {}, {'user': {'name': 'Bernard'}, 'type': 'changeName'});
    const newName = response.body.json.user.name;
    return {'result': 'Nowe imię to: ' + newName};
}
```

## Eximee Designer <a href="#id-restapi-wolaniezewnetrznychuslugrestowych-scriptcode-eximeedesigner" id="id-restapi-wolaniezewnetrznychuslugrestowych-scriptcode-eximeedesigner"></a>

W Eximee Designer zostały dostarczone podpowiedzi API.

<figure><img src="/files/J3IO9QdFd2i91Q6wLGyB" alt=""><figcaption><p><em><strong>Ilustracja 1</strong>. Podpowiedzi żądań GET / POST/ PUT / DELETE.</em></p></figcaption></figure>

<figure><img src="/files/jscrATXNvQzMju5aPROg" alt=""><figcaption><p><em><strong>Ilustracja 2</strong>. Opis podpowiedzi dotyczącej konkretnego żądania (GET).</em></p></figcaption></figure>

<figure><img src="/files/cooxGMStXvDbglhGCXK0" alt=""><figcaption><p><em><strong>Ilustracja 3</strong>. Widok po wstawieniu kodu automatycznie z poziomu podpowiedzi.</em></p></figcaption></figure>

Oraz podpowiedzi możliwych serviceId do wykorzystania w aktualnym momencie.\
W przypadku problemu z pobraniem aktualnej listy serviceId, edytor kontynuuje działanie, ale nie dostarcza informacji o żadnym serviceId.

<figure><img src="/files/GSRy8tPuCGASRlDbTQ1C" alt=""><figcaption><p><em><strong>Ilustracja 4</strong>. Podpowiedź serviceId poza znakiem: ' oraz "</em></p></figcaption></figure>

<figure><img src="/files/srf4Js0QEomneIHttuIM" alt=""><figcaption><p><em><strong>Ilustracja 5</strong>. Podpowiedź serviceId ograniczona znakiem: "</em></p></figcaption></figure>

{% hint style="info" %}
Przykłady

"**demo\_api\_RestTest**" - wykonanie żądań z różnymi parametrami

"**demo\_api\_exchangeRate\_404**" - obsługa wyjątku

"**demo\_api\_exchangeRate\_validator**" - przykład walidatora z wołaniem usługi zewnętrznej
{% endhint %}

### Testowanie API (Postman)

Postman to narzędzie do testowania i pracy z API, które pozwala łatwo wysyłać zapytania HTTP (np. GET, POST) i analizować odpowiedzi serwera. (<https://www.postman.com/>)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.eximee.com/budowanie-aplikacji/logika-biznesowa/scriptcode/restapi-integracje-z-zewnetrznymi-systemami/definicja-api-rest.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
