Работя върху уеб приложение, което ще използва широко 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 обекти. От страната на сървъра има смисъл да се направи OO стил $book->setTitle("foo")
повикване, но book.setTitle(1234, "foo")
от страна на клиента има смисъл (където 1234 е ID на книгата) поради липсата на състояние. Моето решение за това би било гореспоменатия прокси клас да бъде отговорен за превръщането по някакъв начин на book.setTitle(1234, "foo")
в:
$book = new Book();
$book->load(1234);
return $book->setTitle($title);
Чувствам, че този проблем трябва да е бил разглеждан или обсъждан преди... но не намирам много ресурси онлайн. Това изглежда ли като разумно решение?