В нашем случае этим фреймворком является Yii, а одной из самых популярных проблем была одновременная разработка web-сервиса для приложений iOS/Android.
Сначала, как и всегда, просто разработчики договаривались между собой что и как, но если разработчик вдруг менялся — начинались проблемы. Далее — описание входных/выходных данных в wiki. При большом количестве мелких изменений возникала проблема синхронизации кода и форматов, описанных в wiki.
Как мы решили проблему — ниже.
Разработка контроллера web-сервиса
Как правило, мобильный сервис — это отдельный модуль проекта. Сделали базовый модуль и базовый контроллер для работы с web-сервисом.
Ключевые вещи — ниже.
class VMJsonServiceController extends CController { public $documentationMode = false; protected $request = null; ... public function init() { if ($this->documentationMode) { return; } if (Yii::app()->request->isPostRequest) { $json = CJSON::decode(file_get_contents("php://input"), false); if (isset($json->request)) { $this->request = $json->request; } else { $this->respondWithError(VMServiceResponseCode::SERVICE_ERROR, 'There is no request node'); } } else { ... } } ... public function checkInputParameters($params = array()) { if ($this->documentationMode) { $exception = new VMDocumentationException(); $exception->parameters = VMObjectUtils::fromArray($params); throw $exception; } $this->checkObjectParameter($params, $this->request); } ... }
Самая «соль» заключается именно в параметре $documentationMode
, но об этом позже.
Теперь рассмотрим пример контроллера уже с реального проекта, а не из общей библиотеки.
class UsersController extends VMJsonServiceController { ... public function actionSignUp() { $this->checkInputParameters(array( 'user' => array( 'email' => 'test@test.com', 'password' => '12345', 'phone' => array('optional', 'value' => '+7 999 998 76 54', 'photos' => array('array', 'value' => array( 'file' => base64_encode('Image'), ) ) )); $email = $this->request->user->email; ... } ... }
Метод checkInputParameters проверяет, что данные пришли в нужном для этого метода формате (email и password — обязательные, phone — необязательный, а photos — массив данных. Далее мы уверены, что все необходимые данные у нас есть и с ними можно работать.
Теперь, собственно, о чем шла речь в начале статьи — о документации. В принципе, массив в методе checkInputPаrameters — и есть формат входных данных, и, собственно, на основе него мы и генерируем документацию, но постоянно генерировать её ручками — неинтересно и долго. Поэтому, заставим модуль генерировать документацию о себе самому.
1. Делаем еще один контроллер
class VMDocumentationController extends CController { ... //Полный код можете посмотреть в репозитории, здесь покажу лишь один метод //На вход он принимает объект "контроллер" и название метода private function getDefinition($class, $method) { try { $class->{$method}(); } catch (VMDocumentationException $e) { return (object) array( 'parameters' => $e->parameters ); } } ... }
2. Правим код базового модуля
class VMJsonServiceModule extends CWebModule { public function init() { ... $this->controllerMap = array( 'documentation' => array( 'class' => 'VMDocumentationController' ) ); } }
Что нам это дает? А то, что по одному и тому же url программист iOS/Android имеет документацию для любого проекта, меняется только baseUrl.
Как выглядит документация?
Пара скриншотов ниже.
В верхнем навбаре — список всех контроллеров модулей, в левом — список всех экшнов контроллера. Необязательные параметры можно удалить из запроса, кнопка Call — отправит запрос и покажет ответ сервера. То есть вы можете не писать ни строчки кода, но протестировать работу веб-сервиса на любых входных данных.
Ну и напоследок — все исходные коды можете найти здесь. Местами код ужасен, местами очень ужасен, многое из того, что есть в нашей библиотеке кроме мобильного сервиса — нафиг никому не надо, но если будет что вдруг предложить — pull-request вам в помощь.
Спасибо за внимание
ссылка на оригинал статьи http://habrahabr.ru/post/224053/
Добавить комментарий