RESTful Дизайн сервера в Yii - PullRequest
2 голосов
/ 21 июня 2011

Привет, я трахал сеть в поисках как можно большего количества информации о создании спокойного сервера в среде Yii.

Все примеры, которые я нашел до сих пор, имели дело с написанием успокаивающего приложения, которое имеет дело с одной моделью (тема или сообщения IE)

Суть моего вопроса в том, как мне поступитьс написанием спокойного сервера, который имеет дело со многими типами моделей, т. е. с клиентом, брендом, проектом, задачей?

Для каждого объекта модели должны быть реализованы операции CRUD, например, для создания нового бренда система требуетИдентификатор клиента, как и другие операции CRUD.

Должен ли каждый объект модели иметь свой собственный сервер RESTFUl или должен существовать контроллер, который направляет запросы RESTFUL соответствующему контроллеру Rest для объекта модели?Если существует один Сервер, который динамически решает, с какой моделью работать, например, с коммутатором (лично не заинтересованным в этой идее)

Любой совет о том, как добиться такой архитектуры покоя, был бы действительно великолепен

Я думаю, также стоит отметить, что сервер, который я создаю, будет работать с sproutcore на внешнем интерфейсе и будет возвращать только JSON, поэтому никакого определения формата не потребуется.

Ответы [ 3 ]

10 голосов
/ 30 июня 2011

Я занимаюсь разработкой приложения RESTful в Yii. Пока все в порядке.

  • Модели. У меня есть 2 вида моделей:

    1. Управляется через интерфейс REST (т. Е. Создан / удален и т. Д.). Я назвал их resources и поместил в отдельный каталог, но технически это модели, расширяющие CActiveRecord.
    2. Внутренние модели, используемые приложением, но не представленные миру. Кроме того, классы абстрактных моделей, из которых расширяются другие модели или ресурсы.

    Экземпляр ресурса может быть создан из представления XML, отправленного клиентом REST, и может быть преобразован в представление XML. Вы можете определить базовый класс AbstractResource, который будет заниматься этим и переопределять методы конструирования / преобразования в дочерних ресурсах, если это необходимо.

  • Существует один контроллер для одного ресурса. Контроллеры обычно имеют четыре действия CRUD и, возможно, действие List. Последний используется для поисковых операций. Рекомендуется использовать действия на основе классов вместо встроенных действий, чтобы вы могли повторно использовать свои действия в различных контроллерах. Например, все мои контроллеры используют ListAction для поиска.

  • У меня есть базовый контроллер, который отправляет все как application/xml. Также он имеет дело с кодами состояния HTTP и обрабатывает все ошибки .

  • Весь ввод XML от клиентов проверяется с использованием схем Relax NG . Вам понадобится валидатор JSON.

  • TDD камни! Я тщательно протестировал почти все. Это очень помогает при рефакторинге. Используйте TDD. Напишите юнит-тесты для всех ваших моделей, ресурсов и компонентов приложения. Кроме того, написание функциональных тестов проще, потому что у вас нет HTML / CSS / и т.д. Вам просто нужно отправить HTTP-запрос и проверить возвращаемые заголовки, код и контент. Я использовал расширение php_curl, и оно прекрасно работает. Поскольку вы, вероятно, будете выполнять PUT, DELETE и другие экзотические запросы, вам придется вручную составлять каждый HTTP-запрос. В моем случае каждый запрос также должен был быть подписан (это включает вычисление контрольных сумм, хэшей и т. Д.), Поэтому практически невозможно протестировать мое приложение вручную.

Я также рекомендую эту превосходную книгу: RESTful Web Services .

2 голосов
/ 03 марта 2012

Я прохожу подобное упражнение здесь со своим проектом.

Я пытаюсь найти лучший способ заставить все это работать элегантным и масштабируемым образом. На данный момент вот что у меня есть:

/controllers/apiController
/controllers/api/v1/resourceaController <extends apiController>
/controllers/api/v1/resourcebController <extends apiController>
/controllers/api/v1/resourcecController <extends apiController>

Решение, которое я создаю, имеет правила URL, перенаправляющие пользователей прямо к соответствующей функции CRUD в apiController на основе используемого метода:

// REST API routes
array('api/list', 'pattern' => 'api/v<version:\d+>/<resource:\w+>', 'verb'=>'GET'),
array('api/create', 'pattern' => 'api/v<version:\d+>/<resource:\w+>', 'verb'=>'POST'),
array('api/view', 'pattern' => 'api/v<version:\d+>/<resource:\w+>/<resource_id:\d+>', 'verb'=>'GET'),
array('api/update', 'pattern' => 'api/v<version:\d+>/<resource:\w+>/<resource_id:\d+>', 'verb'=>'PUT'),
array('api/delete', 'pattern' => 'api/v<version:\d+>/<resource:\w+>/<resource_id:\d+>', 'verb'=>'DELETE'),
array('api/list', 'pattern' => 'api/v<version:\d+>/<resource:\w+>/<resource_id:\d+>/<association:\w+>', 'verb'=>'GET'),
array('api/create', 'pattern' => 'api/v<version:\d+>/<resource:\w+>/<resource_id:\d+>/<association:\w+>', 'verb'=>'POST'),
array('api/view', 'pattern' => 'api/v<version:\d+>/<resource:\w+>/<resource_id:\d+>/<association:\w+>/<association_id:\d+>', 'verb'=>'GET'),
array('api/update', 'pattern' => 'api/v<version:\d+>/<resource:\w+>/<resource_id:\d+>/<association:\w+>/<association_id:\d+>', 'verb'=>'PUT'),
array('api/delete', 'pattern' => 'api/v<version:\d+>/<resource:\w+>/<resource_id:\d+>/<association:\w+>/<association_id:\d+>', 'verb'=>'DELETE'),

Функция, которая принимает вызов, попытается создать экземпляр контроллера ресурсов на основе $ _GET ['resource'] и вызвать функцию, хранящуюся в $ _GET ['association'].

Я думаю, что это делает его достаточно хорошо масштабируемым, поскольку у нас могут появиться новые версии API, и все, что нам нужно сделать, это создать что-то вроде / api / v2, / api / v2 и поместить все необходимые ресурсы контроллеры там.

2 голосов
/ 23 июня 2011

Запустите этот учебник .Просто продублируйте действия контроллера.Отредактируйте второй набор действий для взаимодействия с новой моделью.Например, учебник требует создания следующих действий в контроллере:

public function actionList()
{
}
public function actionView()
{
}
public function actionCreate()
{
}
public function actionUpdate()
{
}
public function actionDelete()
{
}

Вы должны создать альтернативные действия для своей второй модели.Что-то вроде:

public function actionListB()
{
}
public function actionViewB()
{
}
public function actionCreateB()
{
}
public function actionUpdateB()
{
}
public function actionDeleteB()
{
}

Если вам нужна дополнительная информация или разъяснения, пожалуйста, оставьте комментарий.Удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...