У Битрикса есть официальная обёртка для REST API — класс CRest, который лежит в каждом примере приложения и который все копируют к себе в проект. Он умещается в один файл и работает — ровно до того момента, пока приложение не выходит в реальную эксплуатацию с несколькими порталами и фоновыми воркерами.Один баг стокового CRest однажды стоил мне шести суток простоя приложения, и причина была в одной строке: file_put_contents без блокировки. При обрыве записи settings.json оставался обрезанным, парсинг JSON падал, и приложение считало себя неустановленным — переставало отвечать на события и затирало валидные токены.Я переписал CRest с нуля под то, как приложения Bitrix24 работают на самом деле:— атомарная запись через rename() вместо file_put_contents — читатель видит либо старый файл целиком, либо новый, обрезка невозможна физически; — гонкоустойчивый refresh: одноразовый refresh_token больше не сжигается дважды, когда два воркера одновременно ловят протухший токен; — ключ портала — member_id, а не домен, поэтому переезд портала на другой домен больше не теряет токены; — drop-in совместимость со стоковым CRest: меняется одна строка use, весь остальной код остаётся как есть.Ноль зависимостей, PHP 8.1, работает на любом шареде и коробке — в отличие от официального b24phpsdk с его symfony-стеком. Разбираю каждую граблю с кодом, показываю, чем это чинится, и честно очерчиваю нишу: типизированные обёртки по методам API — territory официального SDK, у меня их осознанно нет.Исходный код открыт. Читать далее