?

Log in

No account? Create an account
Main

REST приложения

Попытался разобраться в том, что такое REST-приложение (Representational State Transfer), поскольку это название последнее время часто мелькает. Что-то просветление наступило не до конца.

Изложу тут для памяти как я это понял, буду благодарен, за комментарии по существу.

Cмысл понятия REST, в организации вызовов API в виде обращения к ресурсу (example.com/user/list), где ресурс представлен четким и ясным URI. Работа по протоколу HTTP, обращение к ресурсам стандартными методами HTTP: GET, PUT, POST, DELETE. Эти методы некоторым образом эквивалентны стандартным CRUD операциям с Базой данных:

GET = Read
PUT= Update
POST = Create
DELETE = Delete

Важно отличие от RPC (Remote Procedure Call): вместо вызовов процедур у нас URI. Мы вызываем процедуру посредством правильного URI, а дальше просто передаем данные.

В ответ пользователь должен получать страницу отображающую некоторый результат, и предоставляющую возможность дальнейшей навигации.

Вот что я не понял, так это что такое чистый и канонический REST, потому, что обычно идет ремарка, что "Смотрите не спутайте чистый REST, и приложения, где через REST гоняется XML". И дальше обычно идет речь о Relaxed REST. Однако если этот XML содержит в себе команды на подобие RPC, то понятно почему, это не REST -- мы используем вместо API через URI все тот же старый вызов функций. А если там гоняются данные, или модные микроформаты? Короче в этом месте я недопонял.

По запросу GET приложение читает данные и отдает их в любом удобном виде -- HTML, XHTML, XML, микроформат.

Запросы POST (добавление) и PUT (обновление) могут содержать данные для записи в БД, например в XML.

Такое взаимодействие позволяет организовать как веб-сервис, так и обычный сайт. Более того такая организация URI, отлично ложится на популярную схему построения URI в MVC фреймворках (modul/action/param1/val1/param2/val2), как бы раскрывает этот подход на уровни URI. См. также постиннг Макса Лапшина.

Из имеющихся трудностей следует отметить, что в стандартной комплектации LAMP не умеет обрабатывать PUT и DELETE запросы и тут требуются доработки, которых я не знаю (обычно пишут: Вам надо сконфигурировать веб-сервер, но подозреваю, что только этим дело не обойдется).

Поэтому в нынешнем php-приложении POST работает, как PUT, POST и DELETE -- за троих то есть. Иногда роль DELETE играет GET, но это не очень правильно -- GET не должен менять состояние системы (хотя и тут есть нюансы -- счетчик статистики например, или параметры сессии).

Опять же авторизация -- нужно ли ее загонять в четкий REST или нет?

Материалы по теме

  1. Очень краткая статья в Википедии
  2. Просто, очень понятно и подробно: Designing RESTful Web Applications. Слайды Ben Ramsey с php | works, Atlanta, Sept 2007
  3. Микроформаты
  4. Блог под руководством Максима Россомахина о микроформатах

Comments

Смотри, прося не сводить REST к XML-RPC, имеют ввиду вот что:
можешь написать такой код:

class Car {
  open_windows();
  close_windows();
  start_engine();
  shut_engine();
}


а можно:


class Car {
  execute_command(command_code) {
    switch(command_code) {
       ...
    }
  }
}


Вот идеологи REST-а просят не превращать первый случай во второй: т.е. скажем запрос немодифицирующий должен быть только GET-ом и иметь чётко конкретный урл. Никаких ?action=filter&filter_params=.... быть не должно.

Т.е. фильтр тоже должен идти параметром в виде

topic/list/filtered/yes/filter-param1/val1/filter-param2/val2

?
Не, не обязательно. Параметры метода могут задаваться обычным образом. Просто урл не должен быть шлюзом к разным методам объекта: разные методы — разные урлы.
Ага. Got it.
Спасибо.
А в случае с SOAP и XML-RPC, урл является шлюзом ко всем функциям сразу. В REST-е это недопустимо, что вполне правильно.

Да, это я тоже вроде уяснил.
А что касается методов PUT и DELETE, то в рельсах для этого есть иммитация: _method => :put, для того, что бы браузер умел такое передавать.
да, это мысль.

Такое взаимодействие позволяет организовать как веб-сервис, так и обычный сайт. Более того такая организация URI, отлично ложится на популярную схему построения URI в MVC фреймворках (modul/action/param1/val1/param2/val2), как бы раскрывает этот подход на уровни URI. См. также постиннг Макса Лапшина.

Как раз не ложится, поскольку action - это verb. /posts/list - не есть правильно с точки зрения REST, а /posts/add - так вообще ересь. /posts/ для листинга постов, POST на /posts/ для создания поста - это есть правильно. Иначе говоря, verb должен определятся лишь методом вызова, а не кодироваться в урле.
СПАСИБО!
Т.е. существительное тут определяет модель (класс модели), а действие определяется типом запроса.

Интересно любое ли реальное приложение можно на таком базисе разложить?
Конечно, нет. Не всё можно уложить в CRUD и я совершенно не сторонник идеи того, что надо обязательно всеми руками и ногами пытаться это сделать.

Но в целом, постараться это сделать можно. Например, login, logout осуществляются, как
POST /session?user=max&password=secret и DELETE /session
опять же это здорово для вебсервиса. а для сайта?

Запросить форму для заведения нового юзера это как? /user и по отсутствию id система должна понять, что нуно пустую форму или все же /user/new

?
Форма для нового юзера — /users/new, а вот POST пойдёт на /users. Логин пойдёт как POST /session.
Редактирование пользователя, как /users/15/edit (в рельсах экспериментировали с /users/15;edit, но мне это не нравится и они тоже отказались)
идеи с /users/15;edit были вот какие: это тот же ресурс, что и /users/15, просто для него выбирается другой view.
:)

так и до ?view=edit недалеко, что почти равно ?action=edit :)
ну, если бы всегда наполнение методов show и edit совпадало, а отличался бы только шаблон, то к view=edit всё бы и свелось. Однако, реально show показывает как правило другую информацию, нежели edit, поэтому к этому всё не свелось.


Запросить форму для заведения нового юзера это как? /user и по отсутствию id система должна понять, что нуно пустую форму или все же /user/new

например по отсутствию id, или же, если /user отдает список юзеров, то в нем же и вывести форму