# Контроллер
Внимание!
В классе контроллера Вы не можете получить доступ к его полям и методам напрямую,
так как this
связан с контекстом контроллера (описан на этой странице).
Для доступа к собственным полям используйте this.controller
.
Не будет работать:
module.exports = class Test {
constructor () {
this.defaultName = 'stranger';
}
_getGreeting (name) {
return `Hello, ${name || this.defaultName}!`;
}
hello () {
return this._getString(this.query.name);
}
}
Будет работать:
module.exports = class Test {
_getGreeting (name) {
return `Hello, ${name || this.controller.defaultName}!`;
}
hello () {
return this.controller._getString(this.query.name);
}
}
# Отправка данных
Для отправки данных пользователю из HTTP-обработчика Вы можете использовать метод
контекста контроллера this.send
, вернуть значение (не пустой return
) или
выбросить исключение HttpError
Пример:
module.exports = class Test {
// Ниже представлены полностью аналогичные реализации отправки данных
async getSmth () {
return await db.Smth.find({ ... }).lean();
}
async getSmth () {
this.send(await db.Smth.find({ ... }).lean());
}
getSmth () {
db.Smth.find({ ... }).lean().exec((err, list) => {
if (err) this.send(err.toString(), 500);
else this.send(list);
});
}
}
# Хуки
# onLoad
Вызывается до вызова любого обработчика в данном контроллере с передачей контекста (значения в this
).
Может прервать обработку запроса, например, если пользователь не имеет нужный уровень доступа.
Так же возможно добавление дополнительных данных в контекст обработчика, таких как информация об авторизации.
Примеры:
module.exports = class Bill {
async onLoad () {
const header = this.header('Authorization');
if (!header || !header.startsWith('Bearer')) {
return this.send('Incorrect auth type', 400);
}
const customer = await db.Customer
.findOne({ apiToken: header.slice(7) })
.select('_id')
.lean();
if (!customer) {
return this.send('Incorrect auth token', 403);
}
this.auth = { customer: customer._id };
}
async list () {
return await db.Bill.find({ customer: this.auth.customer }).lean();
}
}
module.exports = class Admin {
async onLoad () {
if (this.session.access != 'admin') {
// Соединение будет закрыто без ответа
this.drop();
}
}
}
# Свойства
# this.address
Содержит информацию об IP-адресе пользователя.
{
// Тип адреса. Значения: ipv4, ipv6
type: String,
// IP-адрес в формате, указанном в `type`
value: String
}
# this.controller
Объект содержащий все поля и методы текущего контроллера. При вызове любого обработчика
из этого объекта передаётся контекст (значение this
) в этот обработчик.
# this.data
Содержит данные, полученные из тела POST запроса.
Поддерживает такие типы, как application/json
, multipart/form-data
и application/x-www-form-urlencoded
.
# this.query
Содержит значения GET параметров запроса.
Пример:
// При запросе страницы http://localhost:8081/MyController/action?foo=bar
this.send(this.query);
// отправит в ответ { "foo": "bar" }
# this.session
Внимание!
Доступно, только если сессии включены и корректно настроены в файле конфигурации.
Содержит данные текущей сессии.
См. также: Сессия
# Методы HTTP обработчиков
# this.drop
Сбрасывает соединение без ответа на запрос.
# this.header
name: String
- имя заголовкаvalue: String
- значение, по-умолчанию не указано
Использование:
Если значение не указано, то возвращает значение заголовка из запроса, иначе
устанавливает заголовок name
в значение value
для ответа.
Пример:
Код ниже при запросе с заголовком X-Data: my custom header
отправит ответ
с заголовком X-Data-Status: Accepted
.
if (this.header('X-Data') == 'my custom header') {
this.header('X-Data-Status', 'Accepted');
}
# this.redirect
Аргументы:
url: String
Использование:
Перенаправляет пользователя на указанный URL.
Пример:
this.redirect('https://google.com');
# this.send
Аргументы:
data: Any
- данные для отправкиcode: Number
- HTTP код ответа, по-умолчанию200
isPure: Boolean
- еслиtrue
, тоdata
передаётся без изменений, иначеdata
будет сериализован, по-умолчаниюfalse
Использование:
Отправка JSON совместимых данных (строки, числа, объекты и т.д.)
this.send({ hello: true });
Отправка буфера или файла
Внимание!
При отправке файла нужно обязательно указывать аргументы
code
иisPure
.this.send(fs.readFileSync('cat.png'), 200, true);
# Хуки WebSocket обработчиков
# open
Вызывается сразу после установки подключения.
# close
Вызывается сразу после отключения клиента.
# error
Аргументы:
code: number
- коды ошибки WebSocket (opens new window)message?: string
- описание ошибка, опционально
Вызывается при возникновении ошибки на уровне WebSocket соединения.
Также в этом случае вызывается хук close
.
# Методы WebSocket обработчиков
# this.emit
Аргументы:
event: String
- имя события...args: Any
- любые аргументы, которые будут переданны в обработчик события
Использование:
Отправляет событие event
через открытое WebSocket соединение.
Пример:
controllers/Socket.js
:
this.emit('test-event', 'works', true);
Где-то в клиентской части (пример для dc-api-client
):
API.Socket.on('test-event', (prop, value) => {
console.log(prop + ': ' + value);
// works: true
});
# this.subscribe
Аргументы:
channel: String
- имя канала
Использование:
Добавляет для данного соединения подписку на данные из указанного канала.
Пример:
controllers/Socket.js
:
// Добавляем соединению подписку на канал
this.subscribe('chat');
// Выполняет отправку данных, аналогично `this.emit('chat-message', 'Hello there!')`,
// для всех соединений, подписанных на канал "chat".
this.broadcast('chat', 'chat-message', 'Hello there!');
# this.unsubscribe
Аргументы:
channel: String
- имя канала (опционально)
Использование:
Удаляет для данного соединения подписку на указанный канал, иначе удаляет все подписки.
# this.broadcast
Аргументы:
channel: String
- имя каналаevent: String
- имя события...args: Any
- аргументы, передаваемые в обработчик события
Использование:
Отправляет событие через все соединения, имеющие подписку на указанный канал.
Если вместо имени канала передаётся null
, то выполняется рассылка события для всех
активных WebSocket соединений.
# this.end
Аргументы:
msg: String
- по-умолчанию пустая строкаcode: Number
- по-умолчанию1000
(закрытие без ошибкок)
Использование:
Закрывает текущее WebSocket соединение с сообщением msg
и кодом закрытия code
.
Обычное закрытие соединения:
this.end();
Закрытие с сообщением:
this.end('Internal server error', 1011);
См. также: Коды закрытия WebSocket (opens new window)