При написании апи в итоге пришел к некоему своему пониманию его построения, проведения границ и разделения ответственности
Сегодня узнал, что все что я «придумал» называется ADR и существует уже давно (естественно): https://github.com/pmjones/adr
Еще недавно узнал про фреймворк Slim, в который идеально вписывается ADR (https://www.slimframework.com/docs/v3/cookbook/action-domain-responder.html) и он очень похож на Express в мире джаваскриптизёров. Крайнее рекомендую его посмотреть, он очень минималистичен и выглядит приятно
А вообще пост скорее о том, что информации огромное количество, есть проблемы с ее категоризацией и обучением других людей, что в итоге приводит к тому, что я, как наверняка и многие другие, изобретают колесо. А может быть проблема просто в том, что я не всегда могу выразить концепцию словами и поэтому не могу загуглить существующие решения🤔🤔🤔
О разработке, работе руками и сношении с машиной
-
ADR и информационный шум в разработке
-
Подготовка к собеседованиям
Готовлюсь к смене работы, потихонечку хожу по собеседованиям
Спрашивают иногда всякие мелочи по языку, какие-то неочевидные, но известные вещи
По счастливой случайности наткнулся на тред на реддите, где у человека ровно та же ситуация
Читать можно всё, в любом порядке, просто открываете ссылку из любого коммента и внимаете
Читать лучше даже то, что уже известно, повторение — мать учения)
https://www.reddit.com/r/PHPhelp/comments/z9q587/starting_new_job_need_to_hone_my_php_skills/
-
Спред-оператор в конструкторе PHP
Сегодня я узнал, что, оказывается, в конструктор классов можно передавать данные через оператор
...Например, у меня есть классMailSettings, у него простейший конструктор:public function __construct(
private readonly string $senderEmail,
private readonly string $senderName,
private readonly string $server,
private readonly string $port,
private readonly string $password,
) {}В нём хранятся настройки, которые я тяну из файла, получается примерно так:
new MailSettings(
senderEmail: $decodedJson['senderEmail']
...
);Но что-то мне взбрело в голову попробовать сделать
new MailSettings(...$decodedJson)… и оно сработало!
Не помню, чтобы где-то это видел, но штука крайне полезная
-
Дебаг тестов из PHPStorm
Я очень долго откладывал момент, но сегодня мне особенно нечего было делать и я решился — пора научиться запускать тесты (и не только) с дебаггером из PHPStorm
Как это всегда оказывается — сделать это было проще простого:
1. Добавляем докер-контейнер с пхп в конфиг шторма
2. Указываем где в контейнере лежит исполнительный файл codeception
3. В конфиг контейнера прописываем установку xdebug
4. ГотовоЯ понятия не имею почему я так долго к этому шёл, это одна из лучших вещей, которые я делал, которые лежат на поверхности
Ставь лайк, если ты ленился настраивать дебаггер и пользовался "экспертным логированием" 🤡🤡🤡
-
RBAC и вытекающие из него приколы
На работе мы уже 2 месяца разрабатываем ряд приложений, отвечающих определённым бизнес-процессам заказчика. В каждом из них существует довольно строгое разделение по ролям и разрешениям пользователей. Кто-то видит всё, кто-то только часть, а кто-то видит всё, но получить полную информацию может только у части сущностей. Соответственно, на фронте надо условно рисовать кнопки, основываясь на том, что пользователю можно делать.
Так как важнее было выкатить простейший работоспособный продукт, разработку этой системы было принято немного отложить, пока заказчик сам не начнёт явно указывать на отсутствие разделения по ролям. И вот на этой неделе этот момент настал — поступило сообщение от тестировщиков со стороны заказчика, что пользователи, которые видеть должны только свои сущности, видят все. Долго думал как это всё реализовать и по итогу получилась система из 2.5 шагов для получения данных.
Первый шаг — план минимум. Уровень — контроллер. На контроллер вешается условие — «пользователь должен обладать как минимум одним из следующих разрешений, чтобы запрос прошёл дальше»
Второй шаг — уточнение плана минимум. Уровень — контроллер. У пользователя есть разрешение на просмотр своих документов, но точно ли это его документ?
2.5 шаг — то же самое, что и второй шаг, но действия происходят на уровне классаDataHandler. Пример — поиск документов. У пользователя есть разрешение на просмотр своих документов, значит выборка должна быть изначально сужена до документов, которые привязаны к пользователю.И на этом моменте получилась интересная концепция — инъекция объектов
ActiveQuery(скорее, фабрика, конечно). Я понимаю, что это довольно очевидная идея, но я привык, что черезDIподключаются сервисы типа смс, email, кассы, платёжки и тд, а вот что бы у меня был сервис, который мне возвращает сконфигурированные объектыActiveQuery— это что-то новенькое. По итогу такой сервис мне вернёт, например, объектDocumentQuery, где изначально будет вбит текущий пользователь как создатель документа, так на большее у пользователя прав нет.С фронтом всё оказалось гораздо проще. Так как на бэке и так повсеместно происходят проверки прав, ничего не мешает просто при авторизации отдавать список всех доступных пользователю разрешений и уже на основе их рисовать кнопки. Подход, очевидно, не идеален, но он максимально прост и не требует каждый раз делать запрос на бэк при рендере страницы, когда нужно понять — можно рисовать кнопку или нет.
-
Обновлённый код после рефакторинга
А вот как сейчас выглядит обновлённый код — гораздо яснее цель и намерения, чем когда всё называлось
Form
-
От Form к DataHandler: рефакторинг с помощью реддита
У нас новый бэкендер появился. Первым же его проектом стало создание апи для сайта. Ничего сложного, просто надо выдать весь контент, который в админке заполняется. А так как у меня уже за последние месяцы чуть не свой мета-фреймворк для
Yii2нарисовался, то было принято решение его и использовать, ввиду удобства.
Среди всего прочего мне пришлось ему объяснять что такоеFormиResultи для чего их используют. И если сResultвсё понятно, то что такоеForm? Это как-то связано с html-формой? Если нет, то почему так называется? Почему функционал никак не связано с сабмитами и прочим? Пока я ему всё это объяснял меня осенило — я говнокодер. Я намешал всё в одну кучу и в следствии этого назвал как попало. Если кратко, то классForm— это абстрактный класс, который проводит валидацию данных и потом передаёт управление дочернему классу, при этом дочерний класс ещё должен определить правила валидации (те, что были в одном из предыдущих постов). Херня, если честно.
По интересному совпадению я на днях смотрел девлог разработчика инди-игр. Он рассказывал про создание своей системы частиц и как он к ней прикрутилEntity Component System. Тут пазл сошёлся — зачем я в самом классеFormпровожу валидацию, когда это всё можно делегировать? Принялся за работу, переименовал классFormвDataHandler, чем он по сути и являлся всегда, добавил новый тип атрибутов —DataTransformer. Теперь, на дочерний класс достаточно навесить атрибутValidated, которому при вызове методаDataHandler::run()будут переданы данные для валидации.
Таким образом, мы получаем легко расширяемый класс с гибким функционалом, который можно гнуть как нам надо в любой ситуации.
Теперь не надо называть дочерние классыReplacementCreationForm, для этого сейчас лучше всего подходит императивная форма —CreateReplacement, или вместоPermissionListCollectorтеперь будетListPermissions. Красота.
Ко всему этому я пришёл не только благодаря новому бэкендеру. Он этот процесс запустил, но больше всего работы проделали ребята с реддита. Я там задал вопрос — как мне лучше назвать этот класс, который сейчас зовётсяForm? Некоторые начали выяснять что он конкретно делает, некоторые начали говорить, что я оскорбляю богов SOLIDа. Всё это в итоге заставило мой мозг крутить шестерёнки и думать — а чем же и правда занимается этот класс? Почему он так спроектирован? Один из комментаторов открыл мне глаза — это «шаблон»ApplicationService(Action в Laravel), который делает ровно то, что мне нужно.Вывод очевиден — спрашивайте и выслушивайте точки зрения других программистов, даже незнакомых, даже скорее желательно незнакомых. Не бойтесь безжалостно рефакторить и переделывать код. Черпайте идеи из совершенно несвязанных с вашей работой сфер. Всем причастным спасибо.
P.S. ссылка на пост на реддите, где можно почитать все обсуждения — https://www.reddit.com/r/PHPhelp/comments/ys3x91/help_with_class_naming/?utm_source=share&utm_medium=ios_app&utm_name=iossmf
-
http.cat для HTTP-кодов
Лучший способ запомнить значение всех http-кодов: https://http.cat/
-
-
Fullstack-подработка за выходные
В прошлую пятницу почти в конце дня мне от проектного менеджера пришло предложение запилить небольшое приложение за доп плату, но оно ни жить, ни быть должно быть готово к понедельнику
Быстро осмотрев прототип было принято решение почти нахаляву получить денег и до конца рабочего дня (+- 3 часа) бэкенд был готов. Наличие готовых инструментов и базы приложения с полноценной поддержкой апи из прошлых постов повышают продуктивность в разы.
А вот дальше сложнее — надо делать фронт. Наши фронтендеры и так по уши увязли в работе и наравне со мной в выходные работали в поте лица. Пилить фронт на голом html через php — самоубийство. Во-первых, потому что вся подготовленная мной инфраструктура для подобных проектов уже была нацелена на использование по апи, а во-вторых потому что слишком много динамики. До того как стать чисто бэкендером я год работал на Vue. Прекрасный фреймворк. А потом увидел нечто ещё более крутое — Nuxt. Год назад, когда я только переходил в текущую компанию, для меня это было даже как-то обидно — нифига себе какую штуку выстроили, я сам такое же могу и может даже лучше. Да и вообще свой реактивный фреймворк сделаю. И так далее. Работая фулл-стеком я на всё глядел как на испытание, стараясь доказать хз кому, что я могу круче сделать.
Однако, теперь, работая бэкендером я был счастлив вернуться к Nuxt. Простой как кирпич, удобный, понятный, особенно учитывая, что всё это же самое можно сказать про голый Vue. И вишенкой на торте стал Vuetify. Я представить не могу как бы я без него вообще хоть что-нибудь сделал. Я не особо люблю material ui, я больше по флэт-дизайну, но набор компонентов и их функциональность и простота использования меня просто поразили. В итоге фронт был готов к 03:00 и я довольный ушёл спать. Может стоило посмотреть в сторону Astro, но это в другой раз, с Nuxt я был хотя бы немного знаком.
Но не всё так просто. В понедельник человека, который должен был всё это проверять не было на работе — дали отпуск. Я должен был наверное, почувствовать что-то неладное, но работы выше крыши и я просто забил. Во вторник оказалось, что срок на этот проект давался до конца следующей недели. Проектный менеджер пожал плечами, «я думал до конца этой недели». Ладно, главное, что за это заплатят и что я получил возможность с огромным удовольствием посидеть снова над fullstack приложением, особенно ночью. Но и это ещё не всё — к концу недели оказать, что надо сделать ещё правок на 10 часов. Приехали.
Я в который раз от заказчиков слышу чуть ли не клятвы на крови о том, что больше функционала не потребуется, но они каждый раз что-то забывают и вносят правки в самом конце. Каждый раз обжигаюсь, но каждый раз зачем-то верю. Не самый умный поступок, что ещё сказать.
Вывод? Нет вывода, есть только слова благодарности людям, которые делают сумасшедше упрощённые продукты для таких как я, кому нисколько не хочется разбираться как это всё работает, но надо чтобы как можно скорее работало.
P.S. Обязательные слова о том, что в реакте такого нет, там всё сложно и вообще они слишком усложнили фреймворк. После этого идёт обязательное горение жёпы от @artemmarenkoff
