Как правильно настроить контекст общих модулей в 1С и зачем нужны флаги «Клиент», «Сервер» и «Вызов сервера»?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке конфигураций на платформе 1С:Предприятие 8.3 для клиент-серверной архитектуры начинающие разработчики часто сталкиваются с непониманием логики работы свойств общих модулей. В палитре свойств модуля доступны флаги «Клиент (управляемое приложение)», «Сервер» и «Вызов сервера». Нередко возникает вопрос: зачем платформа позволяет устанавливать все эти флаги одновременно, как система определяет место выполнения кода и как правильно структурировать модули согласно стандартам разработки?

Разберем детально назначение каждого флага, правила компиляции процедур и функций, а также типовые шаблоны проектирования общих модулей.

Назначение основных флагов контекста общего модуля

Рассмотрим, за что отвечает каждый отдельный флаг в свойствах общего модуля:

  1. «Сервер» — указывает платформе, что экземпляр данного модуля должен компилироваться на стороне сервера 1С:Предприятия. Процедуры и функции такого модуля могут выполняться исключительно в серверном контексте и напрямую обращаться к базе данных. Если включен только этот флаг, модуль полностью скрыт от клиентского приложения.
  2. «Клиент (управляемое приложение)» — указывает, что модуль компилируется в контексте тонкого клиента или веб-клиента. В таком модуле доступен пользовательский интерфейс, но запрещены прямые запросы к базе данных и работа с серверными объектами.
  3. «Вызов сервера» — данный флаг становится доступен только при включенном флаге «Сервер». Он разрешает клиентскому приложению вызывать экспортные методы этого серверного модуля напрямую. Вызов инициируется на клиенте, управление передается на сервер, там выполняется процедура или функция, после чего результат возвращается на клиента.

Директивы компиляции против инструкций препроцессора

Проанализируем распространенную ошибку: попытку использовать директивы компиляции (&НаКлиенте, &НаСервере) внутри общих модулей. Важно помнить следующее правило платформы:

Директивы компиляции с амперсандом в общих модулях синтаксически запрещены. Они предназначены исключительно для модулей форм и модулей команд. Если попытаться написать &НаСервере в общем модуле, платформа выдаст синтаксическую ошибку при проверке конфигурации.

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


#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
Функция ПолучитьДанныеИзБазы(СсылкаНаОбъект) Экспорт
    // Этот код скомпилируется только на сервере
    Возврат СсылкаНаОбъект.ПолучитьОбъект();
КонецФункции
#КонецЕсли

#Если Клиент Тогда
Процедура ПоказатьСообщениеПользователю(ТекстСообщения) Экспорт
    // Этот код скомпилируется только на клиенте
    ПоказатьПредупреждение(, ТекстСообщения);
КонецПроцедуры
#КонецЕсли

Если же экспортная процедура или функция написана в клиент-серверном модуле без инструкций препроцессора, она компилируется в двух независимых экземплярах: одна копия существует на сервере, вторая — на клиенте.

Что происходит при совместной установке всех трех флагов?

Выясним причину, почему одновременная установка флагов «Клиент (управляемое приложение)», «Сервер» и «Вызов сервера» считается грубым антипаттерном в разработке.

Если у модуля включены и клиентский контекст, и серверный контекст с вызовом сервера, то вступает в силу правило приоритета локального контекста. Когда код на тонком клиенте вызывает метод такого модуля, платформа всегда выбирает «ближайший» экземпляр — то есть клиентский. Вызова сервера по сети не происходит. Серверный экземпляр этого метода останется невызванным, а попытка выполнить внутри метода серверные операции (например, обращение к таблицам базы данных) приведет к ошибке времени выполнения на клиенте.

Именно поэтому комбинировать флаги «Клиент» и «Вызов сервера» в одном модуле категорически не рекомендуется стандартами 1С.

Стандартное разделение общих модулей в архитектуре 1С

Для создания понятной, надежной и производительной системы методисты 1С рекомендуют разделять функционал конфигурации на четыре четких шаблона общих модулей. Разберем каждый из них по шагам:

  1. Чисто клиентские модули (постфикс Клиент)

    Устанавливается только флаг «Клиент (управляемое приложение)». Такие модули предназначены для логики отображения, открытия форм, показа диалогов, взаимодействия с торговым оборудованием и файловой системой пользователя.

  2. Чисто серверные модули (постфикс Сервер)

    Устанавливается только флаг «Сервер» (флаг «Вызов сервера» обязательно снят). Здесь размещается вся тяжелая бизнес-логика: проведение документов, расчет итогов, построение сложных запросов, обработка данных. С клиента эти модули вызвать невозможно, что существенно повышает безопасность системы и предотвращает неконтролируемые вызовы логики в обход интерфейса.

  3. Модули вызова сервера (постфикс ВызовСервера)

    Устанавливаются флаги «Сервер» и «Вызов сервера» (флаг «Клиент» обязательно снят). Данные модули выступают тонким фасадом (API) между клиентом и сервером. Они содержат компактные методы, которые клиентское приложение вызывает для получения данных с сервера. Вся тяжелая обработка из них сразу делегируется в чисто серверные модули.

  4. Клиент-серверные модули (постфикс КлиентСервер)

    Устанавливаются флаги «Клиент (управляемое приложение)» и «Сервер» (флаг «Вызов сервера» обязательно снят). Сюда помещаются универсальные алгоритмы, которые не зависят от базы данных и контекста исполнения: форматирование строк, проверка корректности ИНН, математические формулы, операции с датами. При вызове с клиента код выполняется на клиенте без сетевых задержек, а при вызове на сервере — выполняется на сервере без передачи данных по сети.

Важные ограничения: мутабельные значения и безопасность

Рассмотрим два критически важных аспекта, которые необходимо учитывать при проектировании модулей с признаком «Вызов сервера»:

  1. Недопустимость передачи мутабельных значений.

    Через границу клиент-сервер нельзя передавать объекты, которые могут изменяться и привязаны к контексту сервера. К ним относятся СправочникОбъект, ДокументОбъект, ТаблицаЗначений, НаборЗаписей. Если передать мутабельный объект в метод модуля вызова сервера, платформа сгенерирует исключение: «Ошибка передачи мутабельного значения». В параметрах и результатах таких методов разрешено использовать только сериализуемые типы: примитивные типы (число, строка, дата, булево), ссылки (СправочникСсылка, ДокументСсылка), а также структуры и массивы, состоящие из допустимых типов.

  2. Безопасность и контроль доступа.

    Любая экспортная процедура в модуле с флагом «Вызов сервера» представляет собой открытую точку входа для клиента. Если такой модуль случайно пометить признаком «Привилегированный», клиент сможет запускать серверные операции в обход системы прав (RLS). Поэтому вызовы сервера должны выполняться строго в рамках прав текущего пользователя, а включение привилегированного режима следует делать локально внутри чисто серверных процедур с помощью метода УстановитьПривилегированныйРежим(Истина).

Следуя этим правилам, мы получаем предсказуемое поведение кода, отсутствие лишнего сетевого трафика и надежную архитектуру приложения.

← На главную