Автодокументация мобильных веб-сервисов на примере Yii

от автора

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

В нашем случае этим фреймворком является 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *