API platform это полнофункциональный REST API, который вы получите за считанные минуты.Вот неполный список фич: - Генерация CRUD - Поддержка GraphQL - Машиночитаемая документация API в форматах Hydra и Swagger/Open API, гененрится из метаданных PHPDoc, Serializer, Validator и Doctrine ORM / MongoDB ODM - Хорошая удобочитаемая документация, созданная с использованием пользовательского интерфейса Swagger (включая песочницу) и / или ReDoc - Пагинация - Куча фильтров - Проверка с использованием компонента Symfony Validator (с поддержкой групп) - Расширенные правила аутентификации и авторизации - Расширенная сериализация благодаря компоненту Symfony Serializer (поддержка групп, встраивание отношений, максимальная глубина...) - Поддержка JWT и OAuth- Файлы и \DateTime, сериализация и десериализация - Все полностью настраивается благодаря мощной системе событий и сильному ООП. Сразу отмечу, что в Symfony можно создавать API через контроллер и так же настроить валидацию и доступы через атрибуты  Но если можно не писать код, а использовать уже проверенный, почему бы не пойти такой дорогой?  После изучения этого материала ты узнаешь: Как с помощью API platform создать CRUD и получить документацию swagger. Добавим операцию регистрации пользователя и аутентификацию через токен. Добавим доступы к операциям и позволим менять пароль через API только себе. Создадим сущность пользователя И теперь, давай добавим просто атрибут  у этой сущности Вот и всё готово! Мы создали полноценное REST Api. Заходи по ссылке http://localhost/api И видим, что у нас появились методы для CRUD. По сути, мы написали одну строчку кода, добавив один атрибут, и уже имеем такой мощный функционал. Отлично, движемся дальше. Для этого нам необходимо добавить поле токен к сущности пользователя добавим поле token В самой сущности, добавим поле plainPassword, которой добавим атрибут  Далее нам необходимо реализовать процессор состояний, который будет содержать логику хэширования пароля и добавления ролей пользователю по умолчанию. Смотри документацию про Процессоры состояний После чего мы сможем использовать этот процессор в операциях для создания пользователя и изменения пароля. Поехали Регистрируем его в конфиге services.yaml Сам процессор будет выглядеть так.  Пришло время, связать наш ресурс API с логикой, описанной в процессоре. Для этого добавим атрибут operations к сущности User и пропишем все необходимые операции в виде методов API. Обрати внимание, я указал созданный нами процессор UserPasswordHasherProcessor в операциях Post() и Patch(). А так же, в операции пост добавил параметр uriTemplate со значением /registration, что изменит uri у этого метода с /api/users на /api/registration. Отлично, давай посмотрим на то, как сейчас выглядит swagger. И видим, то что раньше у нас были поля в разделе Example value, а сейчас пусто.  Все нормально!  Так как я переопределил, каждый метод в параметре operations, API Platform не понимает, какие поля ему нужно использовать для каждого метода как входные параметры, и какие поля будут отображены после успешной работы метода. Пришло время настроить сериализацию и нормализацию данных. Смотри документацию про Сериализацию Для этого в атрибуте ApiResource в сущности User опишем параметры normalizationContext для чтения данных из сущности, и denormalizationContext для записи данных в сущность. А дальше, назначим эти группы для полей в сущности User. Так, чтобы для создания пользователя мы запрашивали только логин и пароль, а возвращали токен.  Посмотрим, как теперь выглядит в Swagger Example value в методе /api/registration. Обновим страничку с описанием и видим что, все так как и запланировали. И в ответе мы видим, что будет возращен токен Ты не поверишь, но метод регистрации уже работает! Можно уже сейчас нажать кнопку execute и все сработает! Опа, ошибка вывалилась! Ну конечно! А ты настроил соединение с БД и выполнил миграцию данных? Пришло время настроить подключение и заполнить БД. Создадим миграцию И выполним её Заполняем данные в Swagger Example value в методе /api/registration и нажимаем execute Это же amazing какой-то! Кстати, метод Patch тоже работает. И в нем так же можно изменить два поля И в ответ вернется значение поля token. Только токен не будет генерироваться вновь, так как в UserPasswordHasherProcessor, есть такое условие: В swagger, сверху есть такая кнопка Authorize, нажав на которую, мы видим...пустое окно. Сейчас мы настроим наше API чтобы он мог авторизовывать пользователя через токен, а в swagger мы могли использовать этот токен. Начнем с настройки API Platform. Добавим такой конфиг config/packages/api_platform.yaml И теперь нажав на кнопку Authorize, появится форма, с полем AUTH-TOKEN куда можно вставить токен нашего пользователя. Значение которого можно вытащить из таблицы user. Но пока, авторизацию не реализована у нас в API, и хоть swagger радостно сообщит, что авторизовался, и будет честно слать токен в заголовке, API его не воспримет. Давай реализуем необходимый аутентификатор, и все настроим. Выполним команду и выберем вариант 0 Empty authenticator и дадим название ApiTokenAuthenticator Теперь, реализуем в нем все необходимые методы:  Настроим UserProvider на работу с полем token и настроим firewall Вот теперь, наш API готов к авторизации пользователя. Только в текущий момент, все что мы сделали абсолютно бесполезно, так как у нас не настроены доступы. Давай представим, а как бы хотелось пользоваться текущим API. Метод POST /api/registration должен быть доступен всем, чтобы пользователи свободно регистрировались. Должен быть метод POST /api/login тоже должен быть доступен всем, и в ответ давать свежий токен для авторизации Методы GET /api/users и /api/users/{id} доступно только залогиненым пользователям Методы PATCH /api/users/{id} можно менять пароль только себе, доступно только залогиненым пользователям Методы DELETE /api/users/{id} можно удалить только себя, доступно только залогиненым пользователям Первый пункт, уже реализован. Для пункта 2, давай сделаем процессор для метода login и добавим его в операции. Так же добавим метод findOneByLogin в UserRepository для нахождения пользователя по email Теперь добавим логику для процессора.  Если служба автозапуска и автоконфигурации включена (они включены по умолчанию), то все готово! В противном случае, если вы используете пользовательскую конфигурацию внедрения зависимостей, вам необходимо зарегистрировать соответствующую службу и добавить тег api_platform.state_processor. Осталось создать новый метод для логина и настроить все доступы, как описано в пунктах 3-5 Для удовлетворения требований пункта 2, переходим к сущности User и добавим операцию для метода POST /api/login  Если взглянуть на swagger, то появился новый метод, который уже работает. Теперь для пункта 3, наших требований, добавим параметр security для операций Get() и GetCollection()  Теперь, если вызвать эти операции через swagger, без установленного токена, получим ошибку 403 Доступ запрещен И теперь, самое интересное - пункты 4 и 5.  Доступными переменными являются: user: текущий объект, вошедший в систему  object: текущий класс ресурсов во время денормализации, текущий ресурс во время нормализации или коллекция ресурсов  previous_object: (только после securityPostDenormalize) клон объекта, до внесения изменений - это значение равно null для операций создания нового объекта  request (только на уровне ресурсов): текущий запрос Проверки контроля доступа в атрибуте безопасности всегда выполняются перед этапом денормализации. Это означает, что для запросов PUT или PATCH объект содержит не значение, отправленное пользователем, а значения, хранящиеся в данный момент на уровне сохраняемости (persistence layer). И ещё один момент - для операции Patch() сейчас отображаются поля А хотелось бы настроить поля так, чтобы менять можно было только пароль. И в результат, выдавать не token, а например email. Для таких целей, можно настроить группы на уровне операции и добавить их на соответствующие поля в сущности.  Вот так, у нас получился гибкий функционал. И, обрати внимание как мало кода было написано! В следующих материалах, расскажу про другие фичи этой библиотеки. Надеюсь всё было понятно и полезно, и данный материал поможет создавать классные сервисы быстро и безопасно. Вы можете найти код из этого материала на GitHub.   Перевод документации на русский тут  Буду рад вашим добрым советам, замечаниям и здоровой критики.  Отличного дня!