Построение и тестирование REST API в Yii2

Вебинар-скринкаст о сравнении протоколов удалённого вызова процедур RPC, доступа к объектам SOAP и архитектуры REST для реализации API для работы с сайтом. Рассмотрели написание RESTFul API для проекта на Yii2 Framework и его тестирование с использованием Codeception:

Открыть на YouTube | Исходники примера

Приглашаю на следующие видеоуроки. Анонс и ссылку на эфир, как обычно, пришлю в отдельной рассылке по вебинарам:

И задавайте вопросы в комментариях. Заранее спасибо и до встречи в эфире!

Комментарии

 

Леша

Спасибо Дим. Очень кстати)))

Ответить

 

Ержан Шаймерденов

Спасибо, очень доступно и познавательно!

Ответить

 

Михаил

Дмитрий спасибо за выложенное видео, но 6 часов видео - это многовато! мне 3 дня езды на работу смотреть )))

Ответить

 

KOVALSKY

Ставим на ютюбе скорость плеера 1.5x и все становится чуть быстрее, но не менее понятно ;)

Ответить

 

Max Eyed

Спасибо, Дмитрий. Просто отлично!

Дурацкий вопрос: а как в редакторе импортировать классы без вызова контекстного меню?
Как, например, вот тут: https://youtu.be/jDj_JggZXsU?t=4h50m42s

Ответить

 

Дмитрий Елисеев

Поставить курсор после класса и нажать Ctrl + Пробел.

Ответить

 

Max Eyed

У меня на такое вместо импорта вставляется yii\filters\auth\ перед классом.

Ответить

 

Дмитрий Елисеев

Settings - Editor - General - Autoimport - Enable auto-import in namespace scope.

Ответить

 

Max Eyed

Включено!

Ответить

 

Денис Бондарь

Alt + Enter на классе и выбираете Import. Без контекстного меню, кажется, это не получится сделать.

Ответить

 

slo_nik

Добрый день.
Благодарю за ссылку, буду пересматривать и пробовать реализовать у себя. Вопросы, наверняка, будут после.

Ответить

 

ТимЛид

Как можно было элементарную тему растянуть на 6 часов?? Полнейший бред... читайте официальную доку, не в обиду автору.

Ответить

 

slo_nik

Сделайте лучше!
А мы посмотрим и оценим, насколько Ваш комментарий соответствует действительности.

Ответить

 

slo_nik

Добрый вечер, Дмитрий.
Пытаюсь пересматривать, но что-то постоянно отвлекает))) Ну не в этом дело.
Такой вопрос появился. По поводу повторного использования запроса(идемпотентность, если правильно запомнил).
Вы сказали, что запрос методом DELETE подпадает под это определение, что сколько бы не отправляли запрос на удаление несуществующего поста, всегда вернётся список остальных постов.
А правильно ли это? Может в этом случае возвращать ошибку, а не список постов?

p.s. приблизительно на 1:27 минуте.

Ответить

 

Дмитрий Елисеев

Чаще DELETE будет возвращать статус 204 No Content.

Ответить

 

Дмитрий

Привет теска, подскажи почему в API при генерации тестов не добавился метод haveFixtures?
конфиг норм, все перерыл уже

class_name: FunctionalTester
modules:
    enabled:
        - REST:
            depends: PhpBrowser
            url: 'http://api.link.yii/index-test.php'
            part: [json]
        - Yii2:
            part: [orm, fixtures] # тут главное указано что должен подгружать и методы фикстур
            entryScript: index-test.php

Codeception ставил глобально и переменную PATH поправил чтобы команда всегда была доступна.

Ответить

 

Дмитрий Елисеев

Замените FunctionalTester на ApiTester

Ответить

 

Дмитрий

не в этом дело, я и так уже пробовал... в общем нашел уже причину блин все делал по учебнику версия codeception была 2.1.11 обновил до 2.2.9 - все норм сгенерил с тем же конфигом

Ответить

 

Олег

Дмитрий, чуть-чуть оффтопа)) Подскажите, пожалуйста, как добавить зависимость в composer.json на примере https://github.com/par0noid/ts3admin.class

Ответить

 

Дмитрий Елисеев
composer require par0noid/ts3admin
Ответить

 

Олег

Благодарю, а я его пробовал omposer require par0noid/ts3admin.class

Ответить

 

Stevan

Дмитрий, you should consider making webinars and tutorials on English also, There is really a lack of Yii2 content in English language compared to other frameworks,

Ответить

 

slo_nik

Stevan, а может Вам подучить русский язык? )))

Ответить

 

Stevan

То за мене вероватно не би био неки проблем, али би онима који нису Словени могло да одузме мало више времена. Вероватно би научли таман за Руске туторијале за Yii3 :)

Ответить

 

slo_nik

Дмитирй, ещё раз благодарю за интересный вебинар.
Досмотрел почти до конца, чуть-чуть осталось)))
Такой вопрос.
Всё работает, тестируется и так далее.
При обновлении профиля сделал специально ошибку в имени атрибута(description)
В ProfileController есть такая проверка

        if ($model->save() === false && $model->hasErrors()) {
            throw new ServerErrorHttpException('Failed to update the object for unknown reason.');
        }

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

Ответить

 

Дмитрий Елисеев

Метод $model->load($post) загрузит только атрибуты из rules(), а остальные пропустит.

Ответить

 

slo_nik

Получается, что ошибка вернётся только в том случае, если не сохранится модель.
А если ошибка в имени атрибута, или что-либо похожее, то никакой ошибки не будет?
Не стоит заморачиваться с настройками реакции на такие ошибки?

Ответить

 

Дмитрий Елисеев

Обычно не заморачиваются.

Ответить

 

slo_nik

Дмитрий, а как разделить тестовые базы для restful и основного сайта?
Файлы test.php и test-local.php в api/config я настроил, прописал там тестовую базу.
Но если выполнить в консоли php yii_test migrate, то настройки будут браться из common/test.php и test-local.php

Ответить

 

Дмитрий Елисеев

Сделайте ещё один файл yii_test_api с подгрузкой api/config/test-local.php.

Ответить

 

Slo_nik Дмитрий

Благодарю, попробую. Я пытался продублировать yii_test в api директории, но ничего не получилось. Буду пытаться сделать как Вы советуете
И вот ещё такой вопрос.
На вебинаре не рассмтривался вопрос регистрации. Если делать регистрацию, то что в таком случае возвращать пользователю? Ссылку на подтверждение e-mail или сразу авторизировать и возвращать токен?
Как обычно делают регистрацию для api?

Ответить

 

Дмитрий Елисеев

Если нужно подтверждать - то отправьте письмо со ссылкой и верните 200 OK.

Ответить

 

Александр Сахнов

Спасибо

Ответить

 

Вячеслав

Вопрос конечно не по теме, но

как с помощью git checkout перейти на один коммит вверх

откатиться вниз git checkout head~1

это для того чтобы слить с github исходники и сначала до конца пройтись по всем коммитам

Заранее спасибо

Ответить

 

Дмитрий Елисеев

В Git комит хранит ссылку только на предыдущий. Если из коммита начинаются несколько веток, то верхних будет два. Поэтому можно так:

git checkout master && git checkout HEAD~15
git checkout master && git checkout HEAD~14
git checkout master && git checkout HEAD~13
...
Ответить

 

Дмитрий

Приветствую. Заметил одну неприятную вещь: связи по with не возвращаются. Т.е. при запросе

Post::find()->with(['user']); - получаем только посты:
{
    "id": 1,
    "user_id": 1,
    "title": "title 1",
    "content": "post 1 ",
    "_links": {
        "self": {
            "href": "http://api.rest-api/v1/posts/1"
        }
    }
}, 

а вот с ?expand=author, получаем автора.
как можно решить эту проблему? Заранее благодарю.

Ответить

 

Дмитрий

причем, в запросе связь участвует, (при "левой" связи - ошибка), а в самом ответе связи нет

Ответить

 

Дмитрий Елисеев
public function fields()
{
    return array_merge(parent::fields(), [
        'author' => 'user',
    ]);
}
Ответить

 

Алко

Дмитрий, а подскажите, каким способом грузить через api картинку?

Ответить

 

Дмитрий Елисеев

У VK сделано так.

Ответить

 

Андрей

Большое спасибо за вебинар. Но после его просмотра возникло 2 вопроса:

1. В теоретической части упоминалась схема аутентификации с двумя токенами. Но в реализации используется схема с единственным токеном. Не очень понятно, как именно реализуется схема с двумя токенами. Правильно я понимаю, что для доступа используется только "короткий" токен? А при его истечении необходимо отправить на сервер отдельный запрос, в котором передаётся "длительный" токен и возвращается новый "короткий"? А после истечения "длительного" требуется новый ввод логина / пароля? И что мы получаем после проверки пароля - только "длительный" токен, или оба сразу?

2. Получившийся API очень сильно завязан на ActiveRecord Yii2. Но в последних статьях Вы описываете "слоистую" архитектуру, в которой контроллер вообще ничего не знает об AR. Возможно ли совместить сервисный слой и встроенные в Yii2 средства REST?

Ответить

 

Дмитрий Елисеев

1. Да, правильно. При логине приходит оба токена: текущий и восстановительный.

2. Возможно, если запрашивать данные из репозитория и вручную формировать массив для JSON.

Ответить

 

Дмитрий Елисеев

Можно воспользоваться готовым модулем yii2-oauth2-server для OAuth2 аутентификации.

Ответить

 

Андрей

Большое спасибо.

Ответить

 

Максат Жанат

Здравствуйте, как запустить правильно ваш проект на локалке , вместе со всеми мирациями?
Я новичок :) Или нужно начинать с composera ?

Ответить

 

Дмитрий Елисеев

Клонируете репозиторий:

git clone git@github.com:ElisDN/yii2-demo-rest-api project
cd project

Подтягиваете зависимости:

composer global require "fxp/composer-asset-plugin:^1.3.1"
composer install

Инициализируете локальную Development конфигурацию:

php init

Прописываете настройки БД в common/config/main-local.php и test-local.php

Применяете миграции:

php yii migrate
php yii_test migrate

В отдельных окнах терминалов запускаете серверы:

php -S 127.0.0.1:8090 -t frontend/web
php -S 127.0.0.1:8080 -t api/web

Получаете сайт по адресу 127.0.0.1:8090 и API по 127.0.0.1:8080.

Запускаете тесты:

vendor/bin/codecept run -- -c api
Ответить

 

Максат Жанат

Cпасибо огромное)

Ответить

 

Сергей

Было бы хорошо рассмотреть такие вещи:
если приходит фотка(или несколько файлов) в POST /post
Как переопределить метод create что бы сохранить эти файлы и вернуть готовый JSON со ссылками на сохраненные файлы(фотки) при статусе 201.

Я делал через afterAction, но неуверен или это правильно.

Ответить

 

Паша

Здравствуйте, у меня возникла проблема с фикстурами при тестировании API. Дело в том что из самой функции теста, при обращении к БД, видно что фикстуры юзеров подгрузились, но когда я возвращаю ответ из тестового хоста API в виде массива юзеров, видно что фикстуры не загружались, а в БД старые данные. Уже 2 дня мучаюсь и не понимаю почему так происходит... или так и должно быть, а я просто что то не так делаю? Использую постгресс для тестов.

Ответить

 

Дмитрий Елисеев

Проверьте, что установлено cleanup: false в codeception.yml

Ответить

 

Паша

Помогло, спасибо большое))

Ответить

 

Сидредин Агаширинов

Здравствуйте, Дмитрий! У меня такой вопрос: почему в исходниках к данному вебинару нет файлов index.php ни в папке frontend, ни в папке api? Хотя на видео эти файлы видны. Насчет наличия других файлов я пока не смотрел.

Ответить

 

Дмитрий Елисеев

Потому что эти файлы разворачиваются при выполнении команды php init.

Ответить

 

Сидредин Агаширинов

Понятно. Спасибо большое!

Ответить

 

Юрий

Дмитрий, подскажите, а можно ли реализовать REST API в модуле, не создавая отдельный экземпляр приложения?

У меня структура похожая немного на https://github.com/ElisDN/seokeys
Хотелось сделать модуль с REST API по урлу site.ru/api/controller...

Ответить

 

Дмитрий Елисеев

Да, можно создать модуль api и проследить, чтобы он всегда выдавал JSON/XML вместо HTML.

Ответить

Оставить комментарий

Войти | Завести аккаунт


(никто не увидит)



Можно использовать теги <p> <ul> <li> <b> <i> <a> <pre>