Сервисы
Веб-сервисы REST в Netuno — это скрипты JavaScript, выполняемые на сервере (Back-end), которые позволяют напрямую взаимодействовать с базой данных приложения. С их помощью можно:
- Читать данные из базы данных
- Вставлять новые записи
- Обновлять существующие данные
- Удалять данные
- Выполнять сложную логику, связанную с расчётами или обработкой данных.
- Интегрироваться с внешними системами.
Каждый сервис доступен по URL (endpoint), что позволяет веб-интерфейсам (Front-end), мобильным приложениям или другим внешним системам безопасно и стандартизированно получать данные вашего приложения.
Предварительные требования
- Иметь базовые знания JavaScript, React.js и HTML.
- Знакомство с SQL и структурой папок приложения.
- Рекомендуется иметь базовые знания о формах, полях и связях.
Если у вас возникли вопросы на этих этапах, обратитесь к:
Первые шаги
Мы будем использовать приложение для учёта рабочего времени, цель которого — подсчитать общее количество часов, отработанных каждым сотрудником.
Структура приложения:

Поле 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
`);
-
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 | Запись сообщений об ошибках или отладочной информации в консоль сервера. |
Если у вас возникнут трудности или появятся предложения по улучшению, свяжитесь с нами.
Наша команда и сообщество готовы помочь.
Удачной разработки!