Я работаю над веб-приложением, которое будет широко использовать методы AJAX для взаимодействия клиент/сервер... JSON-RPC. Zend Framework используется на стороне сервера, и он предлагает хороший JSON-RPC-сервер, который я бы хотел использовать.
Моя цель - архивировать поддерживаемую систему, которая предоставляет большой набор функциональных возможностей на стороне сервера для клиентской стороны (javascript) без ненужного дублирования кода. Я видел многочисленные сообщения в блогах и руководства по использованию сервера ZF JSON-RPC (здесь здесь и здесь), но все они были направлены на то, чтобы разоблачить небольшой, общедоступный API. Дублирование кода является обычным явлением, например, одно сообщение в блоге раскрывает следующий метод:
public static function setTitle($bookId, $title) {
$book = new Nickel_Model_Book($bookId);
$book->setTitle($title);
$book->update();
return true;
}
Мне не нравится тот факт, что есть два метода setTitle. Если сигнатура метода для одного изменяется, другая должна храниться в синхронизации... кажется кошмаром на ноу-хау, если ваш API обширен. Мне кажется, что должен быть один класс Book с одним методом setTitle.
Моя первоначальная мысль добавляет аннотацию docblock @export к методам/классам, которые я хочу опубликовать. Когда я решаю разоблачить метод setTitle, я просто добавляю аннотацию, а не новый метод.
Одна потенциальная проблема, которую я вижу, связана с сохранением объекта. На стороне сервера, для setTitle имеет смысл установить свойство title объекта... но не сохранять его в базе данных до тех пор, пока не будет вызван update(). Клиентская сторона, вызывающая setTitle, должна немедленно влиять на базу данных. Одним из возможных решений является изменение всех аксессуаров, так что они берут необязательный второй параметр, означающий модификацию, немедленно обновлять базу данных:
function setTitle($title, $persist = false) {
$this->title = $title;
if ($persist) $this->update();
}
Какой-то прокси-класс может гарантировать, что флаг $persist установлен для всех клиентских RPC-вызовов.
Другой проблемой является сериализация объектов PHP. На стороне сервера имеет смысл делать вызов $book->setTitle("foo") OO-стиля, но клиентская сторона book.setTitle(1234, "foo") имеет смысл (где 1234 - идентификатор книги) из-за отсутствия состояния. Моим решением для этого было бы, чтобы вышеупомянутый класс-прокси отвечал за то, что он превратил book.setTitle(1234, "foo") в:
$book = new Book();
$book->load(1234);
return $book->setTitle($title);
Я чувствую, что эта проблема, должно быть, обсуждалась или обсуждалась раньше... но я не нахожу много ресурсов в Интернете. Это похоже на разумное решение?
