Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Wamba Open JSON API
Разработка и  сопровождение API
в большом проекте
Сегодня в программе:
●

Авто-документация. Генерация HTTP-роутинга.

●

Архитектура основных компонентов API.

●

Гибкое п...
Часть 1.
Документация.
Документация. Поиск решения
Документация может вестись отдельно, но тогда она быстро
устаревает.
Для открытого API важнее ...
Документация в коде. Поиск решения.
NelmioApiDocBundle
<?php
/**
* @ApiDoc(
*

description="CreateanewObject",

*

input="...
Документация в коде. Поиск решения.
Restler-API-Explorer
<?php
require_once '../../../vendor/restler.php';
use LuracastRes...
Документация в коде. Решение: ООП!
/**
* Возращаем список пользователей
* @http_method get

● Генерируется
автоматически I...
Генерация документации. Apigen
cd $PROJECT_HOME; make doc
apigen ...
PhpDoc + Apigen + Apigee = WebConsole
PhpDoc + Apigen + Apigee = WebConsole
Генерация HTTP-роутинга. Apigen.
class ServiceUser {

...
$this->map['GET']['/users/:anketaId/']

/**
* ...

=function(){
...
Часть 2.
Архитектура основных компонентов.
Архитектура. Обзор
•

HTTP-роутер
Архитектура. Обзор
•
•

HTTP-роутер
Брокер фильтров

public function getUserDetails(
FiltersBrokerAuthorized $fb,
RequestU...
Архитектура. Обзор
•
•
•

HTTP-роутер
Брокер фильтров
Сервис
Архитектура. Обзор
•
•
•
•

HTTP-роутер
Брокер фильтров
Сервис
Запрос
Архитектура. Обзор
•
•
•
•
•

HTTP-роутер
Брокер фильтров
Сервис
Запрос
Ответ
Архитектура. Брокер Фильтров (FiltersBroker)
Проверяет доступ к сервису.
class FiltersBrokerAuthorized {

● Настоящее пред...
Архитектура. Сервис (Service)
Бизнес-слой
class ServiceUser {
public function getUserDetails(

Защищен брокером

FiltersBr...
Архитектура. Запрос (Request)
Описание полей входных данных
/**
* Идентификатор пользователя
* @api
* @var int
* @example ...
Архитектура. Запрос (Request)
Контроль типа через методы-аксессоры
/**
* @return int
*/
public function getUserId() { retu...
Архитектура. Запрос (Request)
Методы-помощники.
/**
* Метод-помощник.
* Возращает объект анкеты по установленному значению...
Архитектура. Ответ (Response)
Описание полей ответа
/**
* Идентификатор пользователя
* @api
* @var User
* @example #object...
Архитектура. Ответ (Response)
Контроль выходных данных через методы-аксессоры
public function getUser() {
if (!($this->use...
Архитектура. Ответ (Response)
Сам себя превращает в JSON
class ResponseUserDetails implements JsonSerializable
{
public fu...
Часть 3.
Гибкое построение форм на клиенте: FormBuilder.
Формы: FormBuilder. Цели
•

Минимизировать ошибки на клиенте

•

Иметь возможность модифицировать формы без релиза

•

Сок...
Формы: FormBuilder. Пример.
{
"formBuilder": {
"blocks": [{
"name": "Авторизация",
"fields": [{
"name": "Электронная почта...
Часть 4.
Тестирование.
Функциональное тестирование. Behat
Scenario: Возвращает форму авторизации.
When I am on "/login/builder/?lang_id=ru"
Then ...
Функциональное тестирование. Behat
Behat = Cucumber на PHP
Весь сложный код тестирования прячется за простым
выражением
Ра...
Функциональное тестирование. Behat
●

Тестирование на естественном языке

●

Проверка системы в продакшн с данными

●

Отп...
Unit-тестирование. PHPUnit
•

Проверка мелких узлов системы без данных

•

Удаление зависимостей в коде

•

Помогает делат...
Часть 5.
Версионность.
Версионность. Внешняя
Доступ к API: http://<домен-партнера>/mobile/api/v5.1.0/...

v5.1.0..1..2..
Мажорная версия API

Вер...
Версионность. Внутренняя
•

Нет подверсий API

•

Подверсии у стуктур данных

•

•

Переход на подверсию API связан с изуч...
Подверсии структур. Пример.
Анкета версия 1

Анкета версия 2

{

{
"name": "Прекрасный принц",

"name": "Прекрасный принц"...
Резюме:
•

Генерация документации и HTTP-роутинга из phpdoc - Apigen

•

Генерация web-console разработчика - Apigee

•

Г...
Руководитель группы разработки мобильных сервисов Wamba

Каторгин Виталий (v.katorgin@wamba.com)
Спасибо за внимание!
Виталий Каторгин, Wamba
Upcoming SlideShare
Loading in …5
×

Виталий Каторгин, Wamba

1,382 views

Published on

HighLoad++ 2013

  • Be the first to comment

  • Be the first to like this

Виталий Каторгин, Wamba

  1. 1. Wamba Open JSON API Разработка и  сопровождение API в большом проекте
  2. 2. Сегодня в программе: ● Авто-документация. Генерация HTTP-роутинга. ● Архитектура основных компонентов API. ● Гибкое построение форм на клиенте: FormBuilder. ● Тестирование. ● Версионность.
  3. 3. Часть 1. Документация.
  4. 4. Документация. Поиск решения Документация может вестись отдельно, но тогда она быстро устаревает. Для открытого API важнее актуальность документации. Решение: документация должна быть в коде (phpdoc).
  5. 5. Документация в коде. Поиск решения. NelmioApiDocBundle <?php /** * @ApiDoc( * description="CreateanewObject", * input="YourType", * output="YourClass" • Используется нестандратный phpdoc (99% не поддерживается IDE) *) */ public function postAction() { } • Названия классов вшиты в строки (автоматический рефакториг затруднен)
  6. 6. Документация в коде. Поиск решения. Restler-API-Explorer <?php require_once '../../../vendor/restler.php'; use LuracastRestlerRestler; $r = new Restler(); $r->addAPIClass('Say'); $r->handle(); • Название классов API задается динамически (рефакторинг)
  7. 7. Документация в коде. Решение: ООП! /** * Возращаем список пользователей * @http_method get ● Генерируется автоматически IDE (PHPStorm) * @uri /users/:userId/ * @param FiltersBrokerAuthorized $fb * @param RequestUserDetails $req * @param ResponseUserDetails $rsp * @return ResponseUserDetails */ public function getUserDetails( FiltersBrokerAuthorized $fb, RequestUserDetails $req, ResponseUserDetails $rsp) { ... ● Имена классов (при сборке документации) берутся из типов атрибутов.
  8. 8. Генерация документации. Apigen cd $PROJECT_HOME; make doc apigen ...
  9. 9. PhpDoc + Apigen + Apigee = WebConsole
  10. 10. PhpDoc + Apigen + Apigee = WebConsole
  11. 11. Генерация HTTP-роутинга. Apigen. class ServiceUser { ... $this->map['GET']['/users/:anketaId/'] /** * ... =function(){ * @http_method get return (new ServiceUser()) * @uri /users/:anketaId/ ->getUserDetails( * ... new FiltersBrokerAuthorized(), */ public function getUserDetails( new RequestUserDetails(), FiltersBrokerAuthorized $fb, new ResponseUserDetails() RequestUserDetails $req, ResponseUserDetails $rsp ) { ... }; ...
  12. 12. Часть 2. Архитектура основных компонентов.
  13. 13. Архитектура. Обзор • HTTP-роутер
  14. 14. Архитектура. Обзор • • HTTP-роутер Брокер фильтров public function getUserDetails( FiltersBrokerAuthorized $fb, RequestUserDetails $req, ResponseUserDetails $rsp }
  15. 15. Архитектура. Обзор • • • HTTP-роутер Брокер фильтров Сервис
  16. 16. Архитектура. Обзор • • • • HTTP-роутер Брокер фильтров Сервис Запрос
  17. 17. Архитектура. Обзор • • • • • HTTP-роутер Брокер фильтров Сервис Запрос Ответ
  18. 18. Архитектура. Брокер Фильтров (FiltersBroker) Проверяет доступ к сервису. class FiltersBrokerAuthorized { ● Настоящее предсобытие без “магических” конфигов. public function __construct() { if (!Profile::isAuthrorized()) { throw new AccessDeniedException(); } ... } } ● Передается в сервис как аттрибут (не потеряется).
  19. 19. Архитектура. Сервис (Service) Бизнес-слой class ServiceUser { public function getUserDetails( Защищен брокером FiltersBrokerAuthorized $fb, RequestUserDetails $req, Работает с конкретной структурой входных данных ResponseUserDetails $rsp ) { Отдает ответ в соотвествии с конкретной структурой // бизнес-логика. Использует только объекты API // Весь код работы со сторонними библиотеками спрятан в DAO слой } }
  20. 20. Архитектура. Запрос (Request) Описание полей входных данных /** * Идентификатор пользователя * @api * @var int * @example 12234 */ protected $userId;
  21. 21. Архитектура. Запрос (Request) Контроль типа через методы-аксессоры /** * @return int */ public function getUserId() { return (int)$userId; } /** * Применяется при unit-тестировании * @return void */ public function setUserId($userId) { $this->userId = (int)$userId; }
  22. 22. Архитектура. Запрос (Request) Методы-помощники. /** * Метод-помощник. * Возращает объект анкеты по установленному значению userId * @return User; */ public function getUser() { }
  23. 23. Архитектура. Ответ (Response) Описание полей ответа /** * Идентификатор пользователя * @api * @var User * @example #object# */ protected $user;
  24. 24. Архитектура. Ответ (Response) Контроль выходных данных через методы-аксессоры public function getUser() { if (!($this->user instanceof User::getClass())) { throw new InvalidTypeException(); } return $this->user; }
  25. 25. Архитектура. Ответ (Response) Сам себя превращает в JSON class ResponseUserDetails implements JsonSerializable { public function jsonSerialize() { return [ 'user' => $this->getUser(), ]; } }
  26. 26. Часть 3. Гибкое построение форм на клиенте: FormBuilder.
  27. 27. Формы: FormBuilder. Цели • Минимизировать ошибки на клиенте • Иметь возможность модифицировать формы без релиза • Сократить время разработки экрана-формы
  28. 28. Формы: FormBuilder. Пример. { "formBuilder": { "blocks": [{ "name": "Авторизация", "fields": [{ "name": "Электронная почта или логин", "inputType": "Text", }, { "name": "Пароль", "inputType": "Password", ...
  29. 29. Часть 4. Тестирование.
  30. 30. Функциональное тестирование. Behat Scenario: Возвращает форму авторизации. When I am on "/login/builder/?lang_id=ru" Then I should see FormBuilder: | block | field | type | enable | | login | login | Text | true | | password | Password | true | |
  31. 31. Функциональное тестирование. Behat Behat = Cucumber на PHP Весь сложный код тестирования прячется за простым выражением Расширяем до +∞ • • • /** * @Then /^I should see FormBuilder:$/ */ public function iShouldSeeFormBuilder(Table $table) { ... }
  32. 32. Функциональное тестирование. Behat ● Тестирование на естественном языке ● Проверка системы в продакшн с данными ● Отправная точка для unit-тестирования
  33. 33. Unit-тестирование. PHPUnit • Проверка мелких узлов системы без данных • Удаление зависимостей в коде • Помогает делать код более простым Рецепт: Отключите автозагрузку сторонних библиотек при unitтестировании.
  34. 34. Часть 5. Версионность.
  35. 35. Версионность. Внешняя Доступ к API: http://<домен-партнера>/mobile/api/v5.1.0/... v5.1.0..1..2.. Мажорная версия API Версия релиза клиента Идентификатор платформы (iOS, Android)
  36. 36. Версионность. Внутренняя • Нет подверсий API • Подверсии у стуктур данных • • Переход на подверсию API связан с изучением changelog, неодобряется бизнесом Переход на подверсию структуры быстр и касается только какого-то кокретного вызова API
  37. 37. Подверсии структур. Пример. Анкета версия 1 Анкета версия 2 { { "name": "Прекрасный принц", "name": "Прекрасный принц", "photo": "photo250x250.jpg" "photo": { } "square250": "photo250x250.jpg", "square600": "photo600x600.jpg", "large": "photoLarge.jpg" } }
  38. 38. Резюме: • Генерация документации и HTTP-роутинга из phpdoc - Apigen • Генерация web-console разработчика - Apigee • Гибкий подход к формам на клиенте - FormBuilder • Тестирование - Behat, PHPUnit • Версионность: внешняя и внутренняя у структур.
  39. 39. Руководитель группы разработки мобильных сервисов Wamba Каторгин Виталий (v.katorgin@wamba.com) Спасибо за внимание!

×