Разработка Web-приложения с использованием AJAX + REST
Здравствуйте!
Назрела необходимость глубокого рефакторинга одного довольно сложного web-приложения. Сейчас оно сделано на PHP с использованием парадигмы MVC. Модели толстые, контроллеры тонкие, так что рефакторинг должен пройти относительно легко.
У приложения, помимо прочего, есть JSON REST API, с которым взаимодействуют внешние службы. API пока не покрывает всего функционала, но в дальнейшем планируется набор методов расширять и в идеале наборы функций UI и REST API должны совпадать на 100%, в связи с чем возникла мысль переделать приложение на AJAX, который будет взаимодействовать с этим API, чтобы избежать возможного дублирования.
Я довольно много слышал о таких web-приложениях, и, на мой взгляд, такой подход выглядит очень перспективным.
Хочу попросить помощи у Хабрасообщества — может быть, вы слышали о готовых фреймворках (или компонентах), описаних, common problems, best practices, etc… Если так, поделитесь, пожалуйста, информацией. Буду очень признателен.
Могу поделиться своим опытом в этом плане, возможно это окажется вам полезно. Мы делали REST API для мобильных клентов (iOS, Android) и допустили ужасную ошибку, сделав в первой версии приложения с API, изначально предназначенным для AJAX. Как оказалось, особенность внешних клиентов заключается в том, что мы не имеем над ними никакого контроля: однажды запущенное приложение будет посылать такие и только такие запросы, которые в него заложены, а с размножением версий ситуация только осложняется. Поэтому API вынуждено оставаться совместимым, что оказалось очень нежелательно и некрасиво при внесении изменений в логику и структуру сервиса. Дальше — хуже. Поскольку вызовы API были сделаны «гибкими», по принципу «мало команд — больше настроек», во многие заранее на стороне клиента передавались параметры выдачи (фильтры, количество элементов на странице и т.д.). После деплоя приложений этими параметрами стало невозможно управлять. Сейчас, в новой версии, эти ошибки учтены с помощью дополнительной прослойки, реализующей принцип «много команд, минимум настроек»: для каждой версии API (отдельно для сайта и версий внешних клиентов) существуют разные обёртки, с подстановкой заранее подготовленных фильтров, проверок и формата выдачи. Это позволяет контролировать менять логику поведения внешних клиентов на сервере, огранизовать серсионность и совместимость.
Не очень понятно про «мало команд — больше настроек». И почему в клиенте нельзя менять настройки? Из-за хардокда в духе «количество элемента на странице»?
Речь о внешних клиентах — мобильных приложениях. Чтобы их изменить, нужно заставить всех пользователей скачать апдейт. Поэтому тут хорошо работает схема, когда настройки хранятся на сервере, в отдельном адаптере.
Использовал django на сервере и backbone.js на клиенте, для веб-приложения. Тонкий сервер — доступ к моделям REST, аутентификация и авторизация; толстый клиент — отрисовка интерфейса + запросы к REST API.
В моем случае плюсы — логика не дублируется на сервере и на клиенте, код получается чище. Из минусов — много кода на клиенте, а js все таки менее «зрелый» для такого использования и многие удобные в джанго вещи пришлось реализовывать на клиенте
Преимущество и отличие веба в том, что в любое время можно модифицировать и залатать толстый клиент, мы не учли этой разницы, поэтому тогда и напоролись на пробемы.
Restful на PHP это очень грустно. Особенно когда начинаешь его интегрировать с чем либо типа backbone и понимаешь, что приходится писать много странного кода.
Открытый Rest api это обязательно поддержка deprecated функций. И очень большая радость если клиенты перестают пользоваться каким-то из старых вызовов.
Есть еще некоторое отличие ajax api и restful api, недавно была неплохая статья с некоторыми ошибками.
А можно как-то более развернете аргументировать?
PHP и какой либо другой язык вообще-то ни как с RESful не связаны. Как разработчик реализует работу по HTTP, так в итоге оно и будет работать.
Это просто опыт. Вы видели Zend Rest Server?
PHP как язык имеет множество проблем (не буду повторяться, неделя хейтерства PHP уже закончилась), и большую часть этих проблем решили с помощью кода. Но для RESTfull я еще не видел фреймворка который бы меня устроил.
Zend попытка затащить в PHP подходы из Java. Я не считаю это правильным.
Хотелось бы все же как-то более конструктивных кейсов. Не фрейворка. Ни PHP библиотеки. А конкретно тупо PHP как языка как такового в контексте разработки RESTful серверных приложений. Я не прощу множество. Хотя бы одну.
Учитывая, что RESTful это все лишь подход с очень сильным упором на HTTP я даже гипотетически не могу вообразить проблему которая может возникнуть в языке. HTTP тупо текстовой по сути протокол, а с текстом в PHP получается работать довольно неплохо (в противовес тому же erlang).
Stdit, все равно про настройки не понял. На клиенте (клиенте вообще, а не обязательно мобильном) я знаю два распространенных варианта: 1) хардкодинг параметров в код клиента, соответственно изменить настройки можно только изменил код; 2) настройки клиента записаны в файл или базу откуда берутся при запуске приложения. Так что мешаешь хранить много настроек по варианту 2? Апдейт кода уже не требуется. Кроме того настройки можно вообще хранить в удаленной базе, по сути на сервере. Поэтому без конкретного примера не понятно, почему нужно стремится к минимизации количества настроек и увеличение количества команд. Даже более. Что понимаем под «настройка», а что есть «команда» в контексте REST?
В принципе не важно, как хранить, важно где хранить. Если на сервере — то проблем не будет. Представим ситуацию: клиент запрашивает команду getEvents, и передаёт в неё типы событий, которые ему надо отобразить пользователю, и размер страницы. Далее принимается непредусмотренное решение не показывать пользователю какие-то события, или показывать дополнительно новый тип, а так же уменьшить размер страницы на 10 элементов из-за проблем скорости. Если фильтр хранить на клиенте, то без костылей не обойтись. А если для разных мест, где используетя список событий, вызываются разные команды, то нет проблем с модификацией нужного места. Другими словами, клиент должен быть максимально удалён от логики, и быть только представлением данных. Плюс это помогает решить проблему с избыточностью данных, когда ответ универсальной команды слишком обощённый, и делает более гибким http кеширование.
Возможно я использую неверную терминологию, команда это обращение к api, а настройки — это параметры вызова, их формат и способ их хранения и передачи в вызов.
Предлагаю зайти от getEvents и пейджинга. Что мешает на клиенте в файле конфигурации хранить page, per_page и делать вызов в духе: /getEvents?page=1&per_page=5? per_page хранить в настройках программы, page понятное дело считается в рантайме.
P.S. Хотя в контексте RESTful и пейджинга я все же ратую за использование более правильного, с точки зрения идеологии, подхода. Работа через *Range заголовки. Благо согласно RFC 2616 unit может быть и свой, а не только bytes.
Мешает то, что надо лезть в клиент. То есть, заранее должна быть предусмотрена возможность заменить клиенту файл конфигурации командой с сервера (которую ещё не понятно как передать). На практике это похоже на управление толпой луноходов с Земли. А ещё бывают партнёрские и пользовательские клиенты которые тоже очень хочется контролировать. По поводу использования range заголовков для постранички, не могли бы вы пост для хабра написать? С удовольствием прочту.
Хм, про range… Больше получится заметка, а не статья. Хотя почему бы и нет, по RESTful в рунете инфы не так много. Пожалуй зарелизю движок и займусь статьей.
Наверняка есть и другие тезисы RESTful, можно описать их полностью. К тому же, дискуссия представляет не меньший интерес, чем сам пост, чтобы понять, что стоит использовать, что нет и какие бывают неожиданности.