Page tree
Skip to end of metadata
Go to start of metadata

Работа с REST API

Пример поиска абонентов по коду.

Если планируется значительное количество запросов, следует установить отдельную копию приложения hoper, чтобы работа с REST API не вызывала задержек в работе операторов через веб-интерфейс.

Основной язык программирования, используемый для разработки интеграций, требующих взаимодействия с API – Python.

Python

Импортируем необходимые модули:

import json
import logging
import sys
from http import HTTPStatus
from urllib import parse as urllib_parse

import requests

Задаём параметры подключения к офису оператора связи:

hoper_url = 'https://hydra.hoper.url/rest/v2/'
hoper_login = '########'
hoper_password = '*********'
http_timeout = 60

Задаём параметры поиска. Строка поиска - latera, тип 2001 - поиск по абонентам

search_string = 'latera'
search_subtype = 2001

Инициализируем логгер с выводом в stdout

logger = logging.getLogger()
logger.setLevel(logging.INFO)
stdout_logger = logging.StreamHandler()
logger.addHandler(stdout_logger)

Создаём HTTP-сессию в которой устанавливаем заголовки Content-Type и Accept

http_session = requests.Session()
http_session.headers.update(
    {
        'Content-Type': 'application/json',
        'Accept':       'application/json',
    },
)

Для работы с REST необходимо авторизоваться и получить токен для дальнейшего выполнения запросов.

Чтобы получить токен, подготавливаем запрос {"session": {"login": "########", "password": "********"}} и отправляем его по адресу  /rest/v2/login

Если авторизация не выполнилась успешно, завершаем работу скрипта

auth_url = urllib_parse.urljoin(hoper_url, 'login')
auth_params = {'session': {'login': hoper_login, 'password': hoper_password}}
response = http_session.post(
    auth_url,
    timeout=http_timeout,
    json=auth_params,
)


if response.status_code != HTTPStatus.CREATED:
    logger.error(
        'Auth error ({0}): {1}'.format(response.status_code, response.content),
    )
    sys.exit(1)

Логируем ответ сервера и получаем токен из тела ответа

logger.debug(response.content)
auth_result = json.loads(response.content)
auth_token = auth_result['session']['token']

и сохраняем его HTTP-сессии в заголовке Authorization со значением Token token=RECEIVED_TOKEN

http_session.headers.update(
    {'Authorization': 'Token token={0}'.format(auth_token)},
)

Подготавливаем и отправляем запрос на поиск абонентов

organizations_url = urllib_parse.urljoin(hoper_url, 'search')
response = http_session.get(
    organizations_url,
    timeout=http_timeout,
    params={
        'result_subtype_id': search_subtype,
        'query':             search_string
    }
)

Если запрос выполнен успешно, по каждой найденной сущности выведем её идентификатор и наименование из результата поиска

if response.status_code == HTTPStatus.OK:
    search_results = json.loads(response.content)['search_results']
    for entity in search_results:
        logger.info(
            'Customer `{0}`: `{1}`'.format(
                entity['n_entity_id'],
                entity['vc_result_name'],
            ),
        )

Если запрос выполнился с ошибкой, выведем предупреждение с полученным от сервера ответом

else:
    logger.warning(
        'Invalid response ({0}): {1}'.format(
            response.status_code,
            response.content,
        ),
    )


Полная версия скрипта:

rest-example.py
"""Hydra REST v2 example."""
import json
import logging
import sys
from http import HTTPStatus
from urllib import parse as urllib_parse

import requests

hoper_url = 'https://hydra.hoper.url/rest/v2/'
hoper_login = '########'
hoper_password = '********'
http_timeout = 60

search_string = 'latera'
search_subtype = 2001

logger = logging.getLogger()
logger.setLevel(logging.INFO)
stdout_logger = logging.StreamHandler()
logger.addHandler(stdout_logger)

http_session = requests.Session()
http_session.headers.update(
    {
        'Content-Type': 'application/json',
        'Accept':       'application/json',
    },
)

auth_url = urllib_parse.urljoin(hoper_url, 'login')
auth_params = {'session': {'login': hoper_login, 'password': hoper_password}}
response = http_session.post(
    auth_url,
    timeout=http_timeout,
    json=auth_params,
)

if response.status_code != HTTPStatus.CREATED:
    logger.error(
        'Auth error ({0}): {1}'.format(response.status_code, response.content),
    )
    sys.exit(1)
logger.debug(response.content)

auth_result = json.loads(response.content)
auth_token = auth_result['session']['token']

http_session.headers.update(
    {'Authorization': 'Token token={0}'.format(auth_token)},
)

organizations_url = urllib_parse.urljoin(hoper_url, 'search')
response = http_session.get(
    organizations_url,
    timeout=http_timeout,
    params={
        'result_subtype_id': search_subtype,
        'query':             search_string
    }
)

if response.status_code == HTTPStatus.OK:
    search_results = json.loads(response.content)['search_results']
    for entity in search_results:
        logger.info(
            'Customer `{0}`: `{1}`'.format(
                entity['n_entity_id'],
                entity['vc_result_name'],
            ),
        )
else:
    logger.warning(
        'Invalid response ({0}): {1}'.format(
            response.status_code,
            response.content,
        ),
    )


PHP

Задаём параметры подключения к офису оператора связи:

<?php
$hoper_url = 'https://hydra.hoper.url/rest/v2/';
$hoper_login = '########';
$hoper_password = '********';
$http_timeout = 60;

Задаём параметры поиска. Строка поиска - latera, тип 2001 - поиск по абонентам

$search_string = 'latera';
$search_subtype = 2001;

Подготавливаем HTTP-заголовки Content-Type и Accept для запросов

$http_headers = [
    'Content-Type: application/json',
    'Accept: application/json',
];

Для работы с REST необходимо авторизоваться и получить токен для дальнейшего выполнения запросов.

Чтобы получить токен, подготавливаем запрос {"session": {"login": "########", "password": "********"}} по адресу /rest/v2/login

curl_setopt($curl_auth, CURLOPT_POST, true);
curl_setopt($curl_auth, CURLOPT_URL, $hoper_url . "login");
curl_setopt($curl_auth, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_auth, CURLOPT_HTTPHEADER, $http_headers);
curl_setopt($curl_auth, CURLOPT_TIMEOUT, $http_timeout);
curl_setopt($curl_auth, CURLOPT_POSTFIELDS, json_encode(
    ["session" => ["login" => $hoper_login, "password" => $hoper_password]]
));

выполняем его и получаем результаты. Если авторизация не выполнилась успешно, завершаем работу скрипта

$auth_response = curl_exec($curl_auth);
$auth_status = curl_getinfo($curl_auth, CURLINFO_HTTP_CODE);
curl_close($curl_auth);

if ($auth_status != 201) {
    echo "Auth error (" . $auth_status . "): " . $auth_response . "\n";
    exit(1);
}

Получаем токен, который сервер выдал в теле ответа и сохраняем его в списке заголовков для следующих запросов

$auth_token = json_decode($auth_response, true)['session']['token'];
$http_headers[] = 'Authorization: Token token=' . $auth_token;

Подготавливаем и отправляем запрос на поиск абонентов

$curl_search = curl_init();
curl_setopt($curl_search, CURLOPT_URL,
    $hoper_url . "search?result_subtype_id=" . $search_subtype . "&query=" . $search_string
);
curl_setopt($curl_search, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_search, CURLOPT_HTTPHEADER, $http_headers);
curl_setopt($curl_search, CURLOPT_TIMEOUT, $http_timeout);

$search_response = curl_exec($curl_search);
$search_status = curl_getinfo($curl_search, CURLINFO_HTTP_CODE);

Если запрос выполнен успешно, по каждой найденной сущности выведем её идентификатор и наименование из результата поиска. Если запрос выполнился с ошибкой, выведем предупреждение с полученным от сервера ответом

if ($search_status == 200) {
    $search_result = json_decode($search_response, true);
    foreach ($search_result['search_results'] as $entity) {
        echo "Customer: " . $entity['n_entity_id'] . ": " . $entity['vc_result_name'] . "\n";
    }
} else {
    echo "Invalid response (" . $search_status . "): " . $search_response . "\n";
}


Полная версия скрипта

rest-example.php
<?php
$hoper_url = 'https://hydra.hoper.url/rest/v2/';
$hoper_login = '########';
$hoper_password = '********';
$http_timeout = 60;

$search_string = 'latera';
$search_subtype = 2001;

$http_headers = [
    'Content-Type: application/json',
    'Accept: application/json',
];

$curl_auth = curl_init();
curl_setopt($curl_auth, CURLOPT_POST, true);
curl_setopt($curl_auth, CURLOPT_URL, $hoper_url . "login");
curl_setopt($curl_auth, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_auth, CURLOPT_HTTPHEADER, $http_headers);
curl_setopt($curl_auth, CURLOPT_TIMEOUT, $http_timeout);
curl_setopt($curl_auth, CURLOPT_POSTFIELDS, json_encode(
    ["session" => ["login" => $hoper_login, "password" => $hoper_password]]
));

$auth_response = curl_exec($curl_auth);
$auth_status = curl_getinfo($curl_auth, CURLINFO_HTTP_CODE);
curl_close($curl_auth);

if ($auth_status != 201) {
    echo "Auth error (" . $auth_status . "): " . $auth_response . "\n";
    exit(1);
}

$auth_token = json_decode($auth_response, true)['session']['token'];
$http_headers[] = 'Authorization: Token token=' . $auth_token;

$curl_search = curl_init();
curl_setopt($curl_search, CURLOPT_URL,
    $hoper_url . "search?result_subtype_id=" . $search_subtype . "&query=" . $search_string
);
curl_setopt($curl_search, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_search, CURLOPT_HTTPHEADER, $http_headers);
curl_setopt($curl_search, CURLOPT_TIMEOUT, $http_timeout);

$search_response = curl_exec($curl_search);
$search_status = curl_getinfo($curl_search, CURLINFO_HTTP_CODE);

if ($search_status == 200) {
    $search_result = json_decode($search_response, true);
    foreach ($search_result['search_results'] as $entity) {
        echo "Customer: " . $entity['n_entity_id'] . ": " . $entity['vc_result_name'] . "\n";
    }
} else {
    echo "Invalid response (" . $search_status . "): " . $search_response . "\n";
}


Java

Пример с использованием Apache HttpComponents (org.apache.httpcomponents) и json-java (org.json)

Импортируем необходимые библиотеки

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.IOException;

Создаём стартовый класс и метод

public class RestAPI {

  public static void main(String[] args) {

Задаём параметры подключения к офису оператора связи:

String hoperUrl = "https://hydra.hoper.url/rest/v2/";
String hoperLogin = "########";
String hoperPassword = "********";
int httpTimeout = 60;

Задаём параметры поиска. Строка поиска - latera, тип 2001 - поиск по абонентам

String searchString = "latera";
int searchSubtype = 2001;

Для работы с REST необходимо авторизоваться и получить токен для дальнейшего выполнения запросов.

Чтобы получить токен, подготавливаем JSON для запроса {"session": {"login": "########", "password": "********"}}

JSONObject authParamsCredentials = new JSONObject();
authParamsCredentials.put("login", hoperLogin);
authParamsCredentials.put("password", hoperPassword);
JSONObject authParams = new JSONObject();
authParams.put("session", authParamsCredentials);

Подготавливаем конфигурацию http-клиента, указываем в ней использование таймаута выполнения запроса и создаём http-клиент

RequestConfig config = RequestConfig.custom()
    .setSocketTimeout(httpTimeout * 1000).build();
try (CloseableHttpClient httpclient = HttpClientBuilder.create().setDefaultRequestConfig(config)
    .build()) {

Отправляем POST запрос /rest/v2/login с подготовленными параметрами

HttpPost authRequest = new HttpPost(hoperUrl + "login");
HttpEntity stringEntity = new StringEntity(authParams.toString(),
    ContentType.APPLICATION_JSON);
authRequest.setEntity(stringEntity);
CloseableHttpResponse authResponse = httpclient.execute(authRequest);

Если запрос выполнен успешно, получаем токен из ответа сервера. Если авторизация не выполнилась успешно, завершаем работу скрипта

String authToken = "";
if (authResponse.getStatusLine().getStatusCode() == HttpStatus.SC_CREATED) {
  JSONObject authResponseData = new JSONObject(
      EntityUtils.toString(authResponse.getEntity()));
  authToken = authResponseData.getJSONObject("session").getString("token");
} else {
  System.err.println("Auth error (" + authResponse.getStatusLine().getStatusCode() + "): "
      + EntityUtils.toString(authResponse.getEntity()));
  System.exit(1);
}

Отправляем GET-запрос на поиск, добавляя в него заголовок Authorization со значением Token token=RECEIVED_TOKEN

String getUrl = hoperUrl + "search?result_subtype_id=" +
    searchSubtype +
    "&query=" +
    searchString;
HttpGet searchRequest = new HttpGet(getUrl);
searchRequest.addHeader("Authorization", "Token token=" + authToken);
CloseableHttpResponse searchResponse = httpclient.execute(searchRequest);

Если запрос выполнен успешно, по каждой найденной сущности выведем её идентификатор и наименование из результата поиска. Если запрос выполнился с ошибкой, выведем предупреждение с полученным от сервера ответом.

if (searchResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
  JSONObject searchResponseData = new JSONObject(
      EntityUtils.toString(searchResponse.getEntity()));
  JSONArray searchResults = searchResponseData.getJSONArray("search_results");

  for (int i = 0; i < searchResults.length(); i++) {
    JSONObject row = (JSONObject) searchResults.get(i);
    System.out.println(
        "Customer " + row.getInt("n_entity_id") + ": " + row.getString("vc_result_name"));
  }
} else {
  System.err.println(
      "Invalid response (" + searchResponse.getStatusLine().getStatusCode() + "): "
          + EntityUtils.toString(searchResponse.getEntity()));
}

Завершаем блок try, метод main и класс

    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
}


Полная версия

build.gradle
plugins {
    id 'java'
    id 'application'
}

group 'org.example'
version '1.0-SNAPSHOT'

mainClassName='RestAPI'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.json:json:20220320'
    implementation 'org.apache.httpcomponents:httpclient:4.5.13'
}
settings.gradle
rootProject.name = 'java-rest-example'
src/main/java/RestAPI.java
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.IOException;

public class RestAPI {

  public static void main(String[] args) {
    String hoperUrl = "https://hydra.hoper.url/rest/v2/";
    String hoperLogin = "########";
    String hoperPassword = "********";
    int httpTimeout = 60;

    String searchString = "latera";
    int searchSubtype = 2001;

    JSONObject authParamsCredentials = new JSONObject();
    authParamsCredentials.put("login", hoperLogin);
    authParamsCredentials.put("password", hoperPassword);
    JSONObject authParams = new JSONObject();
    authParams.put("session", authParamsCredentials);

    RequestConfig config = RequestConfig.custom()
        .setSocketTimeout(httpTimeout * 1000).build();

    try (CloseableHttpClient httpclient = HttpClientBuilder.create().setDefaultRequestConfig(config)
        .build()) {
      HttpPost authRequest = new HttpPost(hoperUrl + "login");
      HttpEntity stringEntity = new StringEntity(authParams.toString(),
          ContentType.APPLICATION_JSON);
      authRequest.setEntity(stringEntity);
      CloseableHttpResponse authResponse = httpclient.execute(authRequest);

      String authToken = "";
      if (authResponse.getStatusLine().getStatusCode() == HttpStatus.SC_CREATED) {
        JSONObject authResponseData = new JSONObject(
            EntityUtils.toString(authResponse.getEntity()));
        authToken = authResponseData.getJSONObject("session").getString("token");
      } else {
        System.err.println("Auth error (" + authResponse.getStatusLine().getStatusCode() + "): "
            + EntityUtils.toString(authResponse.getEntity()));
        System.exit(1);
      }

      String getUrl = hoperUrl + "search?result_subtype_id=" +
          searchSubtype +
          "&query=" +
          searchString;
      HttpGet searchRequest = new HttpGet(getUrl);
      searchRequest.addHeader("Authorization", "Token token=" + authToken);
      CloseableHttpResponse searchResponse = httpclient.execute(searchRequest);

      if (searchResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
        JSONObject searchResponseData = new JSONObject(
            EntityUtils.toString(searchResponse.getEntity()));
        JSONArray searchResults = searchResponseData.getJSONArray("search_results");

        for (int i = 0; i < searchResults.length(); i++) {
          JSONObject row = (JSONObject) searchResults.get(i);
          System.out.println(
              "Customer " + row.getInt("n_entity_id") + ": " + row.getString("vc_result_name"));
        }
      } else {
        System.err.println(
            "Invalid response (" + searchResponse.getStatusLine().getStatusCode() + "): "
                + EntityUtils.toString(searchResponse.getEntity()));
      }

    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
}



  • No labels