Архитектура кода новой версии
справочного API      . Или куда мы
           дели MVC?
          Сергей Коржнев
               2ГИС
Кто такой? С какого района?
Почему я такой дерзкий?
● Архитектор и идейный вдохновитель
  новой версии справочного API

● До этого приложился к
  картографическому API (javascript-
  библиотека)

● Также был замечен в рядах
  разработчиков Флампа
Справочное API? Не, не слышал.
REST API

http://catalog.api.2gis.ru/search
   ?what=музей
   &where=Москва
   &version=1.3
   &key=1234567890
   &output=json
Справочное API? Не, не слышал.
{
    "api_version": "1.3",
    "response_code": "200",
    "total": "265",
    "result": [
        {
                 "id": "4504127908471392",
                 "lon": "37.6798458645247",
                 "lat": "55.6172926242175",
                 // ...
          },
          // ...
    ]
}
Справочное API? Не, не слышал.
О чем доклад?
● Почему простой MVC не подходит для
  построения развесистого server-side API?

● Как сделать хорошо?

● Наш опыт
Как все начиналось?

     ... шел 2009 год, человечество еще не
     ...
Маленькие
Партнеры

    maps.2gis.ru




                   Внешние партнеры
Внутренние и внешние партнеры
Единое API для всех. Фокусируемся.
Радостные пользователи
● Новые фичи

● Консистентность интерфейсов
Отказ от текущей версии
Технические долги
Единая реализация
Почему простой MVC
не подходит для построения
развесистого server-side API?
Вопросы к Представлению?
● Тривиальные форматы JSON, JSONP,
  XML

● Yii-представление больше для HTML.

● Как, блин, рефакторить?
Вопросы к Контроллеру?
● Как его тестировать?

● Как быть когда фильтров и
  параметров много?

● Как быть нестандартным роутингом?
Когда много кода
Инструкция как сделать хорошо

Шаг 1 - Распиливаем Модель

Шаг 2 - Разводим зоопарк классов

Шаг 3 - Анализируем результат
Model
Domain в extension'ах
● CApplicationComponent

● Yii::app()->geoCoder
Разруливание зависимостей
return array(
   'components' => array(
        'geoCoder' => array(
           'class' => 'ext.geoCoder.ExtGeoCoder',
           'dbConnection' => 'geoDB',
       ),
      'geoDB' => array( /* ... */),
   ),
);
Инструкция как сделать хорошо

Шаг 1 - Распиливаем Модель

Шаг 2 - Разводим зоопарк классов

Шаг 3 - Анализируем результаты
ServiceManager

$result = ServiceManager::run($_REQUEST);
echo $this->convert($result, 'JSON');
Запрос
GeoSearchRequest extends RequestModel {
  public $what;
  public $is_cool_place;

    public function rules() {
      array('WhatValidator', 'min' => 2, 'max' =>50),
      array('BooleanValidator',
             'param' => 'is_cool_place',
             'required' => false),
    }
}
Валидатор
class WhatValidator extends Validator {
    public function run(RequestModel $model) {
      $this->checkRange(
         $model,
         'what',
         $model->minLength,
         $model->maxLength
      );
   }
}
Сервис
GeoService extends DGService {
  private $_request;

  public function search() {
    $data = Yii::app()->geo->search($this->_request-
>what, $this->_request->is_cool_place);
    return $this->formatSearch($data)
  }

    private function formatSearch(array $data) {
       $data['total'] = count($data);
       return $data;
    }
}
Структура директорий
app/
  services/
     GeoService.php
  validators/
     WhatValidator.php
  requests/
     geo/
        GeoSearchRequest.php
Инструкция как сделать хорошо

Шаг 1 - Распиливаем Модель

Шаг 2 - Разводим зоопарк классов

Шаг 3 - Анализируем результаты
Что получилось?

До                 После
Filters            Request, Validators

Controller, View   Service
Request, Validator
● Конфигурирование вместо
  программирования

● Строгость и безопасность

● Устранение дублирования кода
Service
● Чистый запрос

● Упрощение декомпозиции методов

● Unit-тесты
Chuck Norris approved
Profit
●   Четкие обязанности компонентов
●   Все на своих местах
●   Консистентный интерфейс
●   Единообразие кода
●   Скорость разработки
●   Unit-тесты
Итого
● +1 велосипед

● Заточили архитектуру под свои задачи

● Готовы к наращиванию
  функциональности API
Вопросы?

Архитектура кода нового 2ГИС Web API или куда мы дели MVC