Перейти к основному содержимому

Сервисы

Веб-сервисы REST в Netuno — это скрипты JavaScript, выполняемые на сервере (Back-end), которые позволяют напрямую взаимодействовать с базой данных приложения. С их помощью можно:

  • Читать данные из базы данных
  • Вставлять новые записи
  • Обновлять существующие данные
  • Удалять данные
  • Выполнять сложную логику, связанную с расчётами или обработкой данных.
  • Интегрироваться с внешними системами.

Каждый сервис доступен по URL (endpoint), что позволяет веб-интерфейсам (Front-end), мобильным приложениям или другим внешним системам безопасно и стандартизированно получать данные вашего приложения.

Предварительные требования​

  • Иметь базовые знания JavaScript, React.js и HTML.
  • Знакомство с SQL и структурой папок приложения.
  • Рекомендуется иметь базовые знания о формах, полях и связях.

Если у вас возникли вопросы на этих этапах, обратитесь к:

Первые шаги​

Мы будем использовать приложение для учёта рабочего времени, цель которого — подсчитать общее количество часов, отработанных каждым сотрудником.

Структура приложения:

структура-приложения.png

примечание

Поле id автоматически создаётся и управляется Netuno во всех таблицах, поэтому задавать его вручную не нужно.

Сервисы приложения Netuno находятся в папке server/services/.

Структура папок​

moe-prilozhenie/
└── server/
└── services/
├── sotrudniki.js ← файл сервиса
└──...

Создание сервиса​

В папке server/services/ создайте новый файл, который определит URL вашего сервиса. В этом примере назовите файл sotrudniki.js.

совет
  • Используйте только строчные буквы.
  • Если имя составное, разделяйте слова дефисом (-).
  • Примеры: sotrudniki.js, otchet-po-chasam.js, uchet-vhodov.js.

Запрос к базе данных​

Netuno предоставляет глобальный объект _db для нативного взаимодействия с базой данных.

Для выполнения SQL-запроса используется метод _db.query().

// Выполняет SQL-запрос, который группирует общее количество часов по сотрудникам
const dbZapisi = _db.query(`
SELECT DISTINCT
sotrudnik.imya, SUM(DATEDIFF(HOUR, zapis.nachalo, zapis.konec)) AS total
FROM sotrudnik INNER JOIN zapis
ON sotrudnik.id = zapis.sotrudnik_id
WHERE sotrudnik.active = true AND zapis.active = true
GROUP BY sotrudnik.imya
ORDER BY total ASC
`);
Разбор SQL-запроса
  • INNER JOIN: объединяет таблицы sotrudnik и zapis по внешнему ключу sotrudnik_id.

  • DATEDIFF(HOUR, zapis.nachalo, zapis.konec): вычисляет разницу в часах между началом и окончанием работы.

  • SUM(...) AS total: суммирует все отработанные часы каждого сотрудника.

  • WHERE ... active = true: фильтрует выборку, учитывая только сотрудников и записи, которые не были удалены (активны).

  • GROUP BY sotrudnik.imya: группирует суммы по имени каждого сотрудника.

  • ORDER BY total ASC: сортирует итоговый результат по возрастанию количества отработанных часов.

Обработка данных​

Метод _db.query() возвращает данные во внутреннем формате Netuno.

Чтобы отправить чистый ответ в формате JSON, необходимо преобразовать эти данные с помощью глобальных объектов _val.list() (для массивов) и _val.map() (для объектов).

// Создаёт пустой список для хранения обработанных данных
const spisok = _val.list();

// Перебирает каждую запись, возвращённую SQL-запросом
for (const dbZapis of dbZapisi) {
spisok.add(
_val.map()
.set("imya", dbZapis.getString("imya")) // Извлекает имя как текст
.set("total", dbZapis.getInt("total")) // Извлекает итоговое значение как целое число
);
}

Используемые методы​

РесурсОписание
_val.list()Создаёт список (эквивалент Array в JS).
_val.map()Создаёт объект «ключ — значение» (эквивалент Object или JSON).
.add(...)Добавляет новый элемент в конец списка.
.set("chave", valor)Задаёт новое свойство и соответствующее значение в map-объекте.
.getString("coluna")Извлекает значение указанного столбца в виде текста (String).
.getInt("coluna")Извлекает значение указанного столбца в виде целого числа (Integer).

Возврат данных​

Объект _out используется для отправки обработанного списка клиенту в формате JSON.

// Отправляет список как HTTP-ответ в формате JSON
_out.json(spisok);

Практический пример​

На этом завершающем этапе мы объединим все изученные концепции, чтобы создать рабочий сервис.

Полный код ниже выполняет запрос к базе данных для расчёта общего количества отработанных часов и возвращает эти данные в формате JSON.

// 1. Запрашивает общее количество часов, отработанных каждым активным сотрудником
const dbZapisi = _db.query(`
SELECT DISTINCT
sotrudnik.imya, SUM(DATEDIFF(HOUR, zapis.nachalo, zapis.konec)) AS total
FROM sotrudnik INNER JOIN zapis
ON sotrudnik.id = zapis.sotrudnik_id
WHERE sotrudnik.active = true AND zapis.active = true
GROUP BY sotrudnik.imya
ORDER BY total ASC
`);

// 2. Создаёт структуру данных для ответа
const spisok = _val.list();

// 3. Обрабатывает и сопоставляет результаты
for (const dbZapis of dbZapisi) {
spisok.add(
_val.map()
.set("imya", dbZapis.getString("imya"))
.set("total", dbZapis.getInt("total"))
);
}

// 4. Возвращает данные в формате JSON
_out.json(spisok);

Доступ к сервису​

После создания и настройки сервиса в Netuno он будет готов к использованию и тестированию напрямую через браузер или к интеграции с другими приложениями.

Способы доступа​

Сервис можно использовать с помощью:

  • Браузер: для быстрого тестирования методов GET.

  • HTTP-клиенты: инструменты вроде Postman, Insomnia или Thunder Client.

  • Front-end: через fetch-запросы или библиотеки вроде Axios.

Структура URL​

По умолчанию Netuno автоматически сопоставляет файлы, созданные в папке сервисов, с веб-адресами.

Если приложение запущено локально на стандартном порту, адрес будет следующим:

http://localhost:9000/services/sotrudniki

Как работает маршрутизация?

Netuno использует систему автоматической маршрутизации на основе файловой системы:

Исходная папка: все файлы в server/services/ становятся маршрутами.

Сопоставление: файл sotrudniki.js преобразуется в endpoint /services/sotrudniki.

Расширения: обратите внимание, что расширение .js в URL опускается. При необходимости можно использовать суффикс .netuno (например, /services/sotrudniki.netuno), но доступ без расширения рекомендуется как более чистый и стандартный.

Пример HTTP-ответа: Если в вашей базе данных есть подходящие данные, ответ сервера будет похож на следующий:

[
{
"imya": "Елена Смирнова",
"total": 40
},
{
"imya": "Сергей Иванов",
"total": 35
},
{
"imya": "Мария Петрова",
"total": 45
}
]

Глобальные объекты системы​

При разработке сервисов в Netuno мы часто будем использовать нативные объекты, которые упрощают взаимодействие с базой данных, управление запросами и вывод информации.

Эти объекты представляют собой предварительно настроенные экземпляры, готовые к использованию в серверных скриптах (файлах .js). Они избавляют от необходимости импортировать внешние библиотеки для базовых задач, таких как SQL-запросы или чтение параметров.

ОбъектОписание
_dbВыполнение операций с базой данных (query, insert, update, delete).
_valСоздание и обработка структур данных (list, map).
_outОтправка ответов пользователю (JSON, HTML...).
_reqДоступ к параметрам, отправленным в запросе пользователя (GET, POST).
_logЗапись сообщений об ошибках или отладочной информации в консоль сервера.

Если у вас возникнут трудности или появятся предложения по улучшению, свяжитесь с нами.

Наша команда и сообщество готовы помочь.

Удачной разработки!