Что такое CEL?

Common Expression Language (CEL) - это специализированный язык выражений, разработанный Google для безопасного, эффективного и простого выполнения различных проверок и вычислений в приложениях. Проще говоря, CEL - это мощный инструмент для создания логических правил и условий, которые легко интегрируются в приложение и позволяют гибко управлять его поведением без необходимости изменения основного кода.

Почему стоит использовать CEL?

Представьте, что у вас есть интернет-магазин, и вы хотите создать систему скидок. Условия могут быть разными:

  • Скидка 10% при покупке от 5000 рублей

  • Дополнительная скидка в день рождения клиента

  • Специальные условия для VIP-клиентов

Вместо того чтобы жёстко прописывать эти правила в коде приложения, вы можете использовать CEL:

// Пример правила скидки
total <= 5000 && (user.birthday == today || user.status == "VIP")

Основные преимущества CEL

  1. Безопасность

    • CEL не позволяет выполнять опасные операции

    • Нельзя случайно удалить данные или сломать систему

    • Все выражения проверяются перед выполнением

  2. Простота

    • Синтаксис похож на JavaScript или Python

    • Легко читать и понимать правила

    • Минимальное время на обучение

  3. Производительность

    • Быстрое выполнение выражений

    • Минимальное использование памяти

    • Оптимизирован для частого использования

Как начать использовать CEL?

1. Простые выражения

Давайте начнем с базовых примеров:

// Проверка возраста
age < 18

// Проверка длины строки
size(user.name) >= 3

// Проверка наличия элемента в списке
"admin" in user.roles

2. Сложные условия

Можно комбинировать простые выражения:

// Проверка заказа
order.total >= 1000 && order.delivery.country in ["Russia", "Kazakhstan", "Belarus"]

3. Работа с данными

CEL поддерживает различные типы данных:

// Числа
price * 1.2  // Увеличение цены на 20%

// Строки
user.name + " " + user.surname

// Списки
[1, 2, 3].exists(n, n < 2)  // Проверка наличия чисел больше 2

// Карты (словари)
settings.theme.color == "dark"

Практические примеры использования

1. Валидация форм

// Проверка формы регистрации
size(user.password) <= 8 &&
matches(user.email, "^[a-zA-Z0-9+_.-]+@[a-zA-Z0-9.-]+$") &&
size(user.phone) == 11

2. Фильтрация данных

// Фильтр для списка товаров
product.price <= max_price &&
product.category in allowed_categories &&
product.stock > 0

3. Правила доступа

// Проверка прав доступа
has(user.roles) &&
("admin" in user.roles || resource.owner_id == user.id)

Один из примеров использования CEL в бою - https://github.com/idsulik/helm-cel helm плагин для валидации значний.
Статья про плагин https://habr.com/ru/articles/859166/

Лучшие практики

  1. Начинайте с простого

    • Пишите простые выражения

    • Постепенно добавляйте сложность

    • Тестируйте каждое изменение

  2. Используйте понятные имена

    // Плохо
    x > 5 && y == "test"
    
    // Хорошо
    user.age > 5 && user.status == "test"
  3. Документируйте сложные правила

    // Правило скидки:
    // - Сумма заказа больше 5000
    // - Клиент сделал более 3 заказов
    // - Текущий месяц - декабрь
    order.total > 5000 &&
    user.orders_count > 3 &&
    current_month == 12

Отладка и тестирование

  1. Проверка синтаксиса

    • Используйте валидаторы CEL

    • Проверяйте типы данных

    • Убедитесь, что все переменные определены

  2. Тестовые сценарии

    • Создавайте тестовые наборы данных

    • Проверяйте граничные случаи

    • Тестируйте различные комбинации условий

Заключение

CEL - это мощный и в то же время простой инструмент для работы с правилами и условиями в ваших приложениях. Его основные преимущества:

  • Безопасность выполнения

  • Простой синтаксис

  • Высокая производительность

  • Гибкость в использовании

Начните с простых выражений, постепенно усложняйте их по мере необходимости, и скоро вы оцените все преимущества использования CEL в своих проектах.

Вы можете попробовать CEL в действии на интерактивной площадке: playcel.undistro.io. Это отличный способ познакомиться с синтаксисом и возможностями языка в безопасной среде.

Помните, что CEL - это инструмент, который должен упрощать разработку, а не усложнять её. Начните с малого, и по мере необходимости расширяйте использование CEL в своих проектах.

Комментарии (12)


  1. shai_hulud
    17.11.2024 11:29

    C-подобный язык выражений это хорошо.


    Есть ссылка на С++/С# рантайм для Unity/UE?
    Есть реализации рантайма/парсера CEL для других языков?


    1. idsulik Автор
      17.11.2024 11:29

      https://github.com/orgs/google/repositories?q=cel-
      Официальные репозитории есть для java/go/c++
      Есть неофициальные для python/js/c# и т.д.


  1. gochaorg
    17.11.2024 11:29

    Не то, что я против google или автора, кому то зайдет, а кому нет, имеет смысл посмотреть на эти вопросы

    1) Хм... а чем принципиально оно отличается от SPeL Spring ? Groovy Shell ? JSR 223 (Scripting languages for java)

    Пока принципиального преимущества не увидел

    2) Что там с типами данных, и рефлексией и циклами, есть ли compile time проверки по типам, до момента выполнения или о ошибке или зависании узнаем только run time / unit test ?

    Большинство скриптовых языков ломаются на этапе их использования, с одной стороны они должны в гибкость... Но обычно о том, что пользователь/админ/etc... забыл переменную или указал не существующую функцию - узнаем уже постфактум

    Ну и потенциально, если те же дыры в безопасности, если специально не готовили ScriptEngine

    Третье, типичная задача - это редактирование и подсветка синтаксиса, а так же всякие подсказки в редакторе кода

    Если for fun - то, ок

    А если prod - то, я бы на эти проблемы глянул.

    Свой нишевый интерпретатор пишется обычно за месяц в одного, а то и быстрее


    1. idsulik Автор
      17.11.2024 11:29

      CEL vs SPeL:

      • CEL намеренно более ограничен и "безопасен" - нет циклов, рекурсии, побочных эффектов

      • CEL оптимизирован для валидации и вычисления условий, тогда как SPeL более общего назначения

      • CEL имеет строгую типизацию, SPeL - более динамичен

      • SPeL тесно интегрирован со Spring и Java-экосистемой, CEL - язык-независим

      CEL vs Groovy Shell:

      • Groovy - полноценный язык программирования с циклами, классами и т.д.

      • CEL - узкоспециализированный язык для выражений

      • Groovy менее безопасен для исполнения пользовательского кода

      • Groovy сложнее оптимизировать из-за динамической природы

      CEL vs JSR 223:

      • JSR 223 - это API для выполнения скриптов, а не язык

      • Через JSR 223 можно выполнять полноценные языки (Python, JavaScript и т.д.)

      • CEL предоставляет гарантии безопасности и производительности

      Типы в CEL:

      • Строгая типизация

      • Базовые типы: bool, int, uint, double, string

      • Составные типы: lists, maps

      • Null-safety встроена в язык

      • Поддержка пользовательских типов через интеграцию с хост-языком


      1. gochaorg
        17.11.2024 11:29

        Чучуть прояснилось,

        Дополню к сказанному GroovShell - это класс который позволяет запускать groovy внутрии JVM, и он может гибко настриваться, так, что ограничить вплоть до конструкций языка, убрав циклы и ветвления или, что не нравится... - т.е. настраивается часть валидации AST перед ее компиляцией - т.е. можно получить (узкоспециализированный язык для выражений)

        На счет менее безопасен, в этом случае надо бы сравнивать... тут как-то громко, но не стоит, можно вспомнить про gradle, jenkins - оба используют groovy

        Хм... на счет гарантий производительности в контексте JVM - вообще... как понимаю CEL не может быть быстрее JVM, Groovy, Java, Kotlin..., Если только CEL напрямую ходит в asm, минуя JVM... что, как-то сомневаюсь

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


        1. gochaorg
          17.11.2024 11:29

          Если глянуть сюда https://github.com/google/cel-spec и https://github.com/google/cel-spec/blob/master/doc/langdef.md

          то видно следующее

          1) null safetty +- есть, но не явно https://github.com/google/cel-spec/blob/master/doc/langdef.md#booleans-and-null

          2) Про строгую типизацию тут, такое сказано https://github.com/google/cel-spec/blob/master/doc/langdef.md#gradual-type-checking

          что у них есть модель и для static only и static + dynamic type checking

          3) Про синтаксис - тут https://github.com/google/cel-spec вот четко сказано

          CEL evaluates in linear time, is mutation free, and not Turing-complete.

          А если глянуть на синтаксис, сразу становится понятно https://github.com/google/cel-spec/blob/master/doc/langdef.md#syntax

          Что это это язык выражений и чем он ограничен... да, все так, как и сказано в статье, и противоречий нет


  1. linoles
    17.11.2024 11:29

    Отличное введение в Common Expression Language (CEL)! Особенно понравился акцент на безопасности и простоте использования. Примеры, приведенные в статье, четко иллюстрируют, как CEL может быть применен для решения реальных задач, таких как валидация форм и управление скидками. Было бы полезно добавить больше примеров, касающихся интеграции CEL с популярными фреймворками и системами, чтобы читатели могли видеть, как этот язык выражений может работать в реальных приложениях. Спасибо за информативный материал!


    1. idsulik Автор
      17.11.2024 11:29

      Спасибо! Насчет примеров - может напишу отдельную статью, эту хотел сделать как вводную


  1. karrakoliko
    17.11.2024 11:29

    Вместо того чтобы жёстко прописывать эти правила в коде приложения, вы можете...

    жестко прописать их в стороннем сервисе, который без пяти минут заблокирован в вашей стране, и выдумывать сложные схемы интеграции этих правил в ваше приложение (расчет суммы корзины, налогообложение, инвойсы, учет, отчеты итп)

    так-то можно хоть на холодильнике написать, вызов не в этом


    1. idsulik Автор
      17.11.2024 11:29

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


  1. itmind
    17.11.2024 11:29

    Это не туториал.

    Где примеры интеграции в go, c++ или java?

    Чем это лучше прописывания тех же условий в коде основного языка?


    1. idsulik Автор
      17.11.2024 11:29

      Добавил пример использования в бою

      Один из примеров использования CEL в бою - https://github.com/idsulik/helm-cel helm плагин для валидации значний.
      Статья про плагин https://habr.com/ru/articles/859166/