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

в 15:13, , рубрики: 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 — отправит запрос и покажет ответ сервера. То есть вы можете не писать ни строчки кода, но протестировать работу веб-сервиса на любых входных данных.

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

Ну и напоследок — все исходные коды можете найти здесь. Местами код ужасен, местами очень ужасен, многое из того, что есть в нашей библиотеке кроме мобильного сервиса — нафиг никому не надо, но если будет что вдруг предложить — pull-request вам в помощь.

Спасибо за внимание

Автор: Anexroid

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js