Definicja API Rest

Definicja odpowiedzi

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:

{
    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ą.

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

Żą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
}

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

Żądania

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

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

GET

Żą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

Żą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

W Eximee Designer zostały dostarczone podpowiedzi API.

Ilustracja 1. Podpowiedzi żądań GET / POST/ PUT / DELETE.
Ilustracja 2. Opis podpowiedzi dotyczącej konkretnego żądania (GET).

Ilustracja 3. Widok po wstawieniu kodu automatycznie z poziomu podpowiedzi.

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.

Ilustracja 4. Podpowiedź serviceId poza znakiem: ' oraz "

Ilustracja 5. Podpowiedź serviceId ograniczona znakiem: "

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

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/)

Last updated

Was this helpful?