Если кто не в курсе, Данглас — автор нового проекта (и спецификации) https://github.com/dunglas/vulcain
А также Mercure и ApiPlatform (который поддерживает и GraphQL и несколько спецификаций классического REST).
Так что в его твитте есть немного желтизны — сам он вовсе не так радикально настроен.
Автор не осветил важный аспект, который эксплуатирует новый проект Дангласа. Даже два аспекта:
1) GraphQL запросы делает через Post, что уже некомильфо — нельзя использовать многие стратегии кэширования ответов.
2) много компактных структур данных имеют больше шансов на переиспользование. А значит и кэшировать мелкие ответы более выгодно. HTTP/2 снимает многие аргументы против такой стратегии. И уменьшает смысл в генерации монструозных документов на каждый "специальный случай".
Докер ни причём. Промышленная революция требует всё большей глубины разделения труда и унификации процессов производства. В контексте обсуждаемого вопроса глубина разделения этого труда реализуется через делегирование отдельных этапов сборки контейнеров… Но это не запрещает осуществлять самый разный контроль над результатами такого аутсорса. И над внутренними процессами тоже.
Я не утверждал, что докер был раньше. Я говорю, что инструменты вторичны — первичны идеи и паттерны. Пакеты, модули, контейнеры — это всё про одно: инкапсуляция, наследование, полиморфизм :)
Именно поэтому я радуюсь, что докер дорос до того, чтобы для борьбы с ним большие дяди объединились и написали спецификации. Чтобы вы могли заменить его по частям на что-то более зрелое, конструктивно православное и т.п.
Работаю с докером уже несколько лет. В двух последних проектах рискнул выкатывать и на прод тоже. Так уж получилось, что на фоне других частей проекта — эта не самая проблемная. А значит в немедленной замене не нуждается.
Наверное есть что-то похожее, но другое. Наверное, у всех найдётся за что попинать этот (и любой другой) инструмент. Но.
Мои задачи с ним выполняются быстрее, чем без него. Проблемы бывают, но я уже готов их решать. Есть граничные случаи, есть баги между версиями, но со всем этим в принципе можно жить.
Бывают трудные места для понимания и объяснения другим, но в целом кривая обучения довольно пологая. Инвестиции от обучения сотрудников базовым навыкам возвращаются быстро. Новые сотрудники могут начать работу в течение нескольких часов. И большая часть этого времени не будет связана с контейнерами (поставить, настроить IDE, и прочее).
Хочу попробовать инструмент от Фланта (flant/werf aka dapp), хочу заменить bash-скрипты на ansible и make-файлы, собираюсь развернуть кластер k8s… Но это не мешает мне уже работать и решать свои задачи достаточно эффективно.
Хочу сказать, что докер — он как танк. Даже самый лучший и современный танк обладает врождёнными родовыми уязвимостями. Но никто в здравом уме не пошлёт танки в бой без пехоты и других видов техники, которые эти уязвимости будут закрывать. Докер — для командной игры. Некоторые его недостатки можно и нужно закрывать другими инструментами. Например, виртуальными машинами.
Но, самое главное — что кроме докера, как реализации, есть ещё runC и другие спецификации, которые подстёгивают развитие альтернативных реализаций отдельных кубиков workflow контейнеризации и оркестрации.
И уж конечно, дольше докера проживёт сама идея «инфраструктура как код». На чём бы вы её не воплощали — это уже большой шаг от ремесленника к инженеру. Начните с чего угодно — главное начать.
КО утверждает:
1) Простые вещи должны делаться просто. И их проще несколько раз переделывать целиком, чем обеспечить стабильность-совместимость-и-непротиворечивость-на-века-аминь.
2) Типовых задач — больше 80%. А значит, простые решения будут востребованы всегда. Любая «расширяемая» парадигма, должна уметь деградировать до «hello world», чтобы получить шанс попасть на этот праздник жизни.
3) И тем не менее, взгляд на то, как наилучшим образом решать типовые задачи, имеет каждый суслик в поле. Без этого прогресса не будет, хотя и неразберихи тоже полно.
4) Решение сложных задач — это всегда вызов. Иначе они не назывались бы сложными. Более того: сложная задача сегодняшнего дня может перейти в статус типовой завтра. При решении сложных задач приходится сталкиваться с границами возможностей всего: железа, софта, спецификаций. И иногда приходится изобретать своё, чтобы расширить границы возможного.
5) Автоматизация разработки и её человекоориентированность — это разные цели. Порой, диаметрально противоположные. Для машины удобнее xml, wsdl и прочие строгие вещи. Для человека — html, json (как html, только для ajax). И тут снобизм неуместен: интернет как явление мог бы не состояться, если бы не было простого html и браузеров, очень терпимых к ошибкам в нём. В простых задачах сначала идёт человекоориентированность. И только по мере усложнения и развития приоритет автоматизации усиливается.
6) Интероперабельность, совместимость, интеграция — это задача в третьем измерении, которая решается с учётом первых двух. Если вообще возникает. В огромном числе простых задач — вопросы интероперабельности отсутствуют как класс. Хоть на коне танцуй!
REST недостаточно строг, чтобы его можно было легко и безболезненно использовать для решения сложных задач. Но он позволяет стартануть прямо из Блокнота, после 5 минут видеоурока. В этом его главная фишка.
С другой стороны, запрос на строгость и спецификации есть. А значит будут и спецификации и их достаточно широкая поддержка. Чтобы ещё какое-то подмножество сложных задач стало типовыми.
Или в этой аналогии имеется ввиду, что для того, чтобы пройти они как раз используют второе измерение?
Насколько я понял, это зависит от типа измерения. Можно представить двух людей с абсолютно одинаковыми доходами, но представить двух канатоходцев в одной точке физического пространства — нельзя.
С другой стороны, множество людей с измеренными доходами уже формируют двумерное пространство: одно измерение — дискретное (люди), другое — непрерывное (доходы). И термин «одинаковый доход» уже подразумевает проекцию на ось доходов из пространства большей размерности.
Для начала нам понадобится консольтная утилита symfony lnstaller:
Как раз она нам и не понадобится. И это видно дальше по тексту. Symfony Flex — это замена инсталлятору. Реализованная в виде плагина к composer. С помощью этого плагина можно поставить и предыдущие версии Symfony (3.3 точно ставится).
Суть улучшения в более кросс-технологичных соглашениях (public vs web, config vs app/config, .env vs app/config/parameters.yml, *.yaml vs *.yml, etc). И в большей автоматизации на основе этих соглашений. Отдельные элементы автоматизации методично добавлялись и вылизывались в течение всех релизов третьей ветки (а некоторые появились ещё в 2.x).
Магия там под строгим контролем: любая неоднозначность при компиляции заканчивается бросанием исключения. И требует ручного конфигурирования.
Но, если совсем грубо, правильно описанные и разложенные абстракции, позволяют автоматически нагенерить очень много конкретики. И получить гораздо больше удовольствия от замечательного шаблона DI.
А управление внешними зависимостями позволило более аккуратно нарезать артефакты. Что позволяет не только устанавливать зависимости пачками, но и по-настоящему удалять их пачками в автоматическом режиме. При этом, везде остаётся возможность переконфигурировать, положить в другое место, написать свой рецепт…
Учитывая, что дебагер общается на отдельном порту, должно быть возможно. Другой вопрос, насколько шустро это будет шевелиться.
Я этим не занимался на Symfony2 + PHP5.5, потому что адово тормозило — как я понял, из-за большого количества файлов. Очень хочу как-нибудь попробовать на Symfony3+PHP7.
На текущем Rails-проекте я это тоже пробовал — тоже сильно тормозит. Время от времени можно, но лучше уж <% debugger %> вставлять. Имхо.
1) DB-first. Унаследованное приложение, нужно сгенерить сущности и связи из существующей схемы.
рельсы могут сделать файл schema.rb, которые по сути тот же sql дамп схемы, но на DSL. Делать модели — это уже дополнительные гемы неизвестной кривизны. Ввиду отсутствия явных атрибутов моделей и их типов, сама задача не так актуальна. Нафигачить руками has_one, belongs_to… — это не суперподвиг.
доктрина скафолдить модели умеет искаропки (а симфони на их основе скафолдит весь CRUD). Конфигурация мэппинга может храниться в классах аннотациями или конфигах (xml, yaml). Каждый вариант бывает сильно удобнее в каких-то конкретных кейсах. В конфиге указываются как связи, так и типы данных.
2) Model first — когда модели, их мэппинг и данные описаны… минутку но в рельсах можно описать данные только в миграциях через DSL, который по сути только обёртка над SQL DDL. Негде описать какой тип данных ожидает *модель*. Сгенерить полноценный diff в такой ситуации — просто нереальная задача. Данных недостаточно. Есть средства, которые позволяют как-бы восстановить картину по истории миграций, но они будут бессильными, если какие-то модификации проведены без миграций или описаны через sql. DSL, кстати по умолчанию (по соглашению, ага) не индексирует и не создаёт fk на связочные поля. Ну ладно консистентность (я это правда сказал?!), но это же тормозит!!!
Доктрина ориентируется на текущий мэппинг в коде. Это истина в последней инстанции — всё остальное требуется под неё подогнать. Именно таким образом, при тестировании на копии прода на одном из проектов, мы внезапно обнаруживали изменения в схеме, которые самовольно делали DBA. Более того, имея на руках полную информацию о мэппинге и типах полей, доктрина сама создает связочные таблицы, внешние ключи и индексы. В смысле генерит заполненную миграцию, которую вы потом можете применить as is, дополнить или переписать полностью. И никаких DSL — сразу SQL под конкретную БД.
В рельсах миграции являются важным источником знаний о том, чего хотел разработчик модели. И эти знания могут расходиться с информацией из schema.rb. Поэтому миграции лучше копить и копить.
schema.rb перегенерится после каждой миграциии и это источник постоянных конфликтов мержей. Поэтому в нашем проекте я его вообще пока сунул в gitignore. Пока не придумал, как его правильно готовить, без головняков на ровном месте. Скорее всего будем после релиза его генерить на проде в какой-нибудь schema.rb.prod, а потом при разворачивании девелоперских и тестовых сборках, переименовывать в schema.rb и стартовать с него.
В доктрине миграции — это служебный код, который, после срабатывания миграции, можно безболезненно удалить (и написать delete на табличку schema_migrations, чтобы вычищались неактуальные версии миграций). Был бы дамп с достаточно свежей версией. Нет дампа — тоже не беда. Можно сгенерить нулевую миграцию относительно пустой базы. И начать историю с чистого листа.
Про отличия ActiveRecord от DataMapper я не буду распространяться, кроме того, что для сложных задач, второй безусловно предпочтительнее.
Это, конечно, не всё, что я имею сказать по этому поводу, но на этом уже можно остановиться…
Это удобно только если не рассматривать в качестве альтернативы полноценный debug-режим. Который позволяет не вставлять отладочный код в текст, а пользоваться брек-поинтами в IDE.
Что же касается веб-панелей, то я просто тащусь от симфонийской: symfony.com/blog/new-in-symfony-2-8-redesigned-web-debug-toolbar
Потому что в ней не только информации в разы больше, без всяких вмешательств в код, но есть ещё и профилировщик встроенный (которому ещё можно задавать дополнительные точки фиксации). Причём всё это с историей и независимыми репортами на каждый запрос (включая AJAX), а не так, что эксепшены в соседних окнах чистят сессию друг другу.
Буквально недавно пересел с Symfony2 на Rails4.
* unless скорее порадовал
* byebug и REHL очень порадовал (потому что app-сервер в дебаг-режиме еле ползает, впрочем как и php5.5-fpm + Symfony2).
* жизнь без интерфейсов и type hinting — боль и тонны загадочного кода
* всякие динамические акссессоры и «вопросительные» методы где-то радуют, а где-то бесят. Вообще не кажется удобным, что каждый объект обладает невообразимой тучей методов и свойств, на все случаи жизни. Причём часть из них IDE не находит, хотя и поскрипывает по паре секунд на каждый запрос автокомплита.
* Жизнь без DI кажется ненадёжной и иллюзорной.
* RVM штука классная, но на фоне развития Docker-контейнеров уже не смотрится killer future.
* bundler по сравнению с Composer слабоват. Может я ещё не всё про него узнал
* конкретно Rails скорее разочаровал. До этого подходил к нему серьёзно ещё на второй версии. На фоне прогресса Symfony с первой до третьей версии, изменения в рельсах за это время ничтожны (включая и пятую версию тоже).
Но больше всего угнетает ActiveRecord и миграции. Раньше даже не осознавал, насколько это ловко сделано в Doctrine[Migrations] и сколько боли доставляет отсутствие «полной» конфигурации объектного мэппинга в рельсах.
Если кто не в курсе, Данглас — автор нового проекта (и спецификации) https://github.com/dunglas/vulcain
А также Mercure и ApiPlatform (который поддерживает и GraphQL и несколько спецификаций классического REST).
Так что в его твитте есть немного желтизны — сам он вовсе не так радикально настроен.
Автор не осветил важный аспект, который эксплуатирует новый проект Дангласа. Даже два аспекта:
1) GraphQL запросы делает через Post, что уже некомильфо — нельзя использовать многие стратегии кэширования ответов.
2) много компактных структур данных имеют больше шансов на переиспользование. А значит и кэшировать мелкие ответы более выгодно. HTTP/2 снимает многие аргументы против такой стратегии. И уменьшает смысл в генерации монструозных документов на каждый "специальный случай".
Именно поэтому я радуюсь, что докер дорос до того, чтобы для борьбы с ним большие дяди объединились и написали спецификации. Чтобы вы могли заменить его по частям на что-то более зрелое, конструктивно православное и т.п.
Наверное есть что-то похожее, но другое. Наверное, у всех найдётся за что попинать этот (и любой другой) инструмент. Но.
Мои задачи с ним выполняются быстрее, чем без него. Проблемы бывают, но я уже готов их решать. Есть граничные случаи, есть баги между версиями, но со всем этим в принципе можно жить.
Бывают трудные места для понимания и объяснения другим, но в целом кривая обучения довольно пологая. Инвестиции от обучения сотрудников базовым навыкам возвращаются быстро. Новые сотрудники могут начать работу в течение нескольких часов. И большая часть этого времени не будет связана с контейнерами (поставить, настроить IDE, и прочее).
Хочу попробовать инструмент от Фланта (flant/werf aka dapp), хочу заменить bash-скрипты на ansible и make-файлы, собираюсь развернуть кластер k8s… Но это не мешает мне уже работать и решать свои задачи достаточно эффективно.
Хочу сказать, что докер — он как танк. Даже самый лучший и современный танк обладает врождёнными родовыми уязвимостями. Но никто в здравом уме не пошлёт танки в бой без пехоты и других видов техники, которые эти уязвимости будут закрывать. Докер — для командной игры. Некоторые его недостатки можно и нужно закрывать другими инструментами. Например, виртуальными машинами.
Но, самое главное — что кроме докера, как реализации, есть ещё runC и другие спецификации, которые подстёгивают развитие альтернативных реализаций отдельных кубиков workflow контейнеризации и оркестрации.
И уж конечно, дольше докера проживёт сама идея «инфраструктура как код». На чём бы вы её не воплощали — это уже большой шаг от ремесленника к инженеру. Начните с чего угодно — главное начать.
1) Простые вещи должны делаться просто. И их проще несколько раз переделывать целиком, чем обеспечить стабильность-совместимость-и-непротиворечивость-на-века-аминь.
2) Типовых задач — больше 80%. А значит, простые решения будут востребованы всегда. Любая «расширяемая» парадигма, должна уметь деградировать до «hello world», чтобы получить шанс попасть на этот праздник жизни.
3) И тем не менее, взгляд на то, как наилучшим образом решать типовые задачи, имеет каждый суслик в поле. Без этого прогресса не будет, хотя и неразберихи тоже полно.
4) Решение сложных задач — это всегда вызов. Иначе они не назывались бы сложными. Более того: сложная задача сегодняшнего дня может перейти в статус типовой завтра. При решении сложных задач приходится сталкиваться с границами возможностей всего: железа, софта, спецификаций. И иногда приходится изобретать своё, чтобы расширить границы возможного.
5) Автоматизация разработки и её человекоориентированность — это разные цели. Порой, диаметрально противоположные. Для машины удобнее xml, wsdl и прочие строгие вещи. Для человека — html, json (как html, только для ajax). И тут снобизм неуместен: интернет как явление мог бы не состояться, если бы не было простого html и браузеров, очень терпимых к ошибкам в нём. В простых задачах сначала идёт человекоориентированность. И только по мере усложнения и развития приоритет автоматизации усиливается.
6) Интероперабельность, совместимость, интеграция — это задача в третьем измерении, которая решается с учётом первых двух. Если вообще возникает. В огромном числе простых задач — вопросы интероперабельности отсутствуют как класс. Хоть на коне танцуй!
REST недостаточно строг, чтобы его можно было легко и безболезненно использовать для решения сложных задач. Но он позволяет стартануть прямо из Блокнота, после 5 минут видеоурока. В этом его главная фишка.
С другой стороны, запрос на строгость и спецификации есть. А значит будут и спецификации и их достаточно широкая поддержка. Чтобы ещё какое-то подмножество сложных задач стало типовыми.
Насколько я понял, это зависит от типа измерения. Можно представить двух людей с абсолютно одинаковыми доходами, но представить двух канатоходцев в одной точке физического пространства — нельзя.
С другой стороны, множество людей с измеренными доходами уже формируют двумерное пространство: одно измерение — дискретное (люди), другое — непрерывное (доходы). И термин «одинаковый доход» уже подразумевает проекцию на ось доходов из пространства большей размерности.
Как раз она нам и не понадобится. И это видно дальше по тексту. Symfony Flex — это замена инсталлятору. Реализованная в виде плагина к composer. С помощью этого плагина можно поставить и предыдущие версии Symfony (3.3 точно ставится).
Суть улучшения в более кросс-технологичных соглашениях (public vs web, config vs app/config, .env vs app/config/parameters.yml, *.yaml vs *.yml, etc). И в большей автоматизации на основе этих соглашений. Отдельные элементы автоматизации методично добавлялись и вылизывались в течение всех релизов третьей ветки (а некоторые появились ещё в 2.x).
Магия там под строгим контролем: любая неоднозначность при компиляции заканчивается бросанием исключения. И требует ручного конфигурирования.
Но, если совсем грубо, правильно описанные и разложенные абстракции, позволяют автоматически нагенерить очень много конкретики. И получить гораздо больше удовольствия от замечательного шаблона DI.
А управление внешними зависимостями позволило более аккуратно нарезать артефакты. Что позволяет не только устанавливать зависимости пачками, но и по-настоящему удалять их пачками в автоматическом режиме. При этом, везде остаётся возможность переконфигурировать, положить в другое место, написать свой рецепт…
Я этим не занимался на Symfony2 + PHP5.5, потому что адово тормозило — как я понял, из-за большого количества файлов. Очень хочу как-нибудь попробовать на Symfony3+PHP7.
На текущем Rails-проекте я это тоже пробовал — тоже сильно тормозит. Время от времени можно, но лучше уж <% debugger %> вставлять. Имхо.
рельсы могут сделать файл schema.rb, которые по сути тот же sql дамп схемы, но на DSL. Делать модели — это уже дополнительные гемы неизвестной кривизны. Ввиду отсутствия явных атрибутов моделей и их типов, сама задача не так актуальна. Нафигачить руками has_one, belongs_to… — это не суперподвиг.
доктрина скафолдить модели умеет искаропки (а симфони на их основе скафолдит весь CRUD). Конфигурация мэппинга может храниться в классах аннотациями или конфигах (xml, yaml). Каждый вариант бывает сильно удобнее в каких-то конкретных кейсах. В конфиге указываются как связи, так и типы данных.
2) Model first — когда модели, их мэппинг и данные описаны… минутку но в рельсах можно описать данные только в миграциях через DSL, который по сути только обёртка над SQL DDL. Негде описать какой тип данных ожидает *модель*. Сгенерить полноценный diff в такой ситуации — просто нереальная задача. Данных недостаточно. Есть средства, которые позволяют как-бы восстановить картину по истории миграций, но они будут бессильными, если какие-то модификации проведены без миграций или описаны через sql. DSL, кстати по умолчанию (по соглашению, ага) не индексирует и не создаёт fk на связочные поля. Ну ладно консистентность (я это правда сказал?!), но это же тормозит!!!
Доктрина ориентируется на текущий мэппинг в коде. Это истина в последней инстанции — всё остальное требуется под неё подогнать. Именно таким образом, при тестировании на копии прода на одном из проектов, мы внезапно обнаруживали изменения в схеме, которые самовольно делали DBA. Более того, имея на руках полную информацию о мэппинге и типах полей, доктрина сама создает связочные таблицы, внешние ключи и индексы. В смысле генерит заполненную миграцию, которую вы потом можете применить as is, дополнить или переписать полностью. И никаких DSL — сразу SQL под конкретную БД.
В рельсах миграции являются важным источником знаний о том, чего хотел разработчик модели. И эти знания могут расходиться с информацией из schema.rb. Поэтому миграции лучше копить и копить.
schema.rb перегенерится после каждой миграциии и это источник постоянных конфликтов мержей. Поэтому в нашем проекте я его вообще пока сунул в gitignore. Пока не придумал, как его правильно готовить, без головняков на ровном месте. Скорее всего будем после релиза его генерить на проде в какой-нибудь schema.rb.prod, а потом при разворачивании девелоперских и тестовых сборках, переименовывать в schema.rb и стартовать с него.
В доктрине миграции — это служебный код, который, после срабатывания миграции, можно безболезненно удалить (и написать delete на табличку schema_migrations, чтобы вычищались неактуальные версии миграций). Был бы дамп с достаточно свежей версией. Нет дампа — тоже не беда. Можно сгенерить нулевую миграцию относительно пустой базы. И начать историю с чистого листа.
Про отличия ActiveRecord от DataMapper я не буду распространяться, кроме того, что для сложных задач, второй безусловно предпочтительнее.
Это, конечно, не всё, что я имею сказать по этому поводу, но на этом уже можно остановиться…
Что же касается веб-панелей, то я просто тащусь от симфонийской: symfony.com/blog/new-in-symfony-2-8-redesigned-web-debug-toolbar
Потому что в ней не только информации в разы больше, без всяких вмешательств в код, но есть ещё и профилировщик встроенный (которому ещё можно задавать дополнительные точки фиксации). Причём всё это с историей и независимыми репортами на каждый запрос (включая AJAX), а не так, что эксепшены в соседних окнах чистят сессию друг другу.
Буквально недавно пересел с Symfony2 на Rails4.
* unless скорее порадовал
* byebug и REHL очень порадовал (потому что app-сервер в дебаг-режиме еле ползает, впрочем как и php5.5-fpm + Symfony2).
* жизнь без интерфейсов и type hinting — боль и тонны загадочного кода
* всякие динамические акссессоры и «вопросительные» методы где-то радуют, а где-то бесят. Вообще не кажется удобным, что каждый объект обладает невообразимой тучей методов и свойств, на все случаи жизни. Причём часть из них IDE не находит, хотя и поскрипывает по паре секунд на каждый запрос автокомплита.
* Жизнь без DI кажется ненадёжной и иллюзорной.
* RVM штука классная, но на фоне развития Docker-контейнеров уже не смотрится killer future.
* bundler по сравнению с Composer слабоват. Может я ещё не всё про него узнал
* конкретно Rails скорее разочаровал. До этого подходил к нему серьёзно ещё на второй версии. На фоне прогресса Symfony с первой до третьей версии, изменения в рельсах за это время ничтожны (включая и пятую версию тоже).
Но больше всего угнетает ActiveRecord и миграции. Раньше даже не осознавал, насколько это ловко сделано в Doctrine[Migrations] и сколько боли доставляет отсутствие «полной» конфигурации объектного мэппинга в рельсах.