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