Комментарии 180
Могу написать пост с работающим примером вокруг вашего примера.
Что у вас за задача?
Что у вас за задача?
Подключение их к вам или вас к ним? :) То есть вы для них будете выступать поставщиком сервиса или вам нужны их сервисы?
Обычная тактика в таких случаях — у них есть API, а вам надо думать как его связать с вашей системой. Простая логика подсказывает, что более-менее крупных платежных агентов не больше сотни (с большим преувеличением), а вот клиентов (в чей адрес платежи принимают) у них может быть миллионы, подстраиваться под каждый велосипед — никаких разработчиков не хватит.
Стандартная, афаик, практика — они инициализируют транзакцию обычным GET/POST запросом (по указанном вами в договоре/настройках url), указывая данные о предполагаемом платеже и подписывая их вроде как в топике или по https своим сертификатом — вы отвечаете, что готовы такой платеж принять (что такой абонент/лицевой счёт/… существует) они посылают вам второй запрос, что платеж пошёл (здесь все нужные данные), вы отвечаете что платеж приняли, они отвечают «спасибо, мы поняли, что вы платеж получили» и завершают транзакцию.
Стандартная, афаик, практика — они инициализируют транзакцию обычным GET/POST запросом (по указанном вами в договоре/настройках url), указывая данные о предполагаемом платеже и подписывая их вроде как в топике или по https своим сертификатом — вы отвечаете, что готовы такой платеж принять (что такой абонент/лицевой счёт/… существует) они посылают вам второй запрос, что платеж пошёл (здесь все нужные данные), вы отвечаете что платеж приняли, они отвечают «спасибо, мы поняли, что вы платеж получили» и завершают транзакцию.
Сто раз уже думал, что пора стандартизовать такие протоколы. А то что ни платёжная система, то заново все интерфейсы реализовывать.
В таком случае вам надо не писать Апи, а читать ихнее)
Честно говоря осталось больше вопросов, чем ясности: почему свой велосипед, а не OAuth для аутентификации; почему команды не имеют отдельных URL'ов, а передаются через параметры; почему не используется тип запроса (GET, POST, DELETE) для изменения его семантики, почему не поддерживается XML (который на ряду с JSON является форматом де-факто для RESTful приложений) и т.д. и т.п.?
ок, дельные вопросы.
сигнатуры позволяют проверить целостность запроса+пользователями API могут быть не только люди, но и другие системы. Ни фейсбук, ни контакт в своих API не использует OAuth.
команды входят в URL — можно считать что они имеют отдельные урлы.
Не вижу особых причин делать работу API непредсказуемой — по моему неважно откуда и как пришли данные, если они правильные — на них необходимо отдать адекватный ответ.
XML легко ввести(собственно в объекте Response можно это настраивать), я просто не стал перегружать пример лишними данными.
P.S. спасибо за вашу статью, кстати, сейчас переписываю на Node.js.
сигнатуры позволяют проверить целостность запроса+пользователями API могут быть не только люди, но и другие системы. Ни фейсбук, ни контакт в своих API не использует OAuth.
команды входят в URL — можно считать что они имеют отдельные урлы.
Не вижу особых причин делать работу API непредсказуемой — по моему неважно откуда и как пришли данные, если они правильные — на них необходимо отдать адекватный ответ.
XML легко ввести(собственно в объекте Response можно это настраивать), я просто не стал перегружать пример лишними данными.
P.S. спасибо за вашу статью, кстати, сейчас переписываю на Node.js.
А на чем сейчас написано? Сложно переходить на Node.js? Мне вот посоветовали его использовать для написания чата, но что не знаю даже с какой стороны подойти, знания JS минимальные, на уровне форму по ссылке засабмитить, провалидировав предварительно.
Сейчас — PHP, переход на Node.js — это переписывание всего кода по хорошему.
Но производительность манит)
Но производительность манит)
попробуйте лучше Erlang))
Не, ну я серьезно. Может я зря смайлик воткнул, но Erlang здесь на самом деле лучше подходит, особенно если вашим API действительно кто то будет пользоваться, и не пара запросов в сутки (иначе и от PHP отказываться смысла нет).
А если уж JavaScript не очень хорошо знаете, то, пожалуй, все равно что учить. Причем на Erlang-е первое время вполне можно в довольно таки привычном стиле писать и не погружаться сразу во все эти асинхронности, каллбеки и т.п.
А если уж JavaScript не очень хорошо знаете, то, пожалуй, все равно что учить. Причем на Erlang-е первое время вполне можно в довольно таки привычном стиле писать и не погружаться сразу во все эти асинхронности, каллбеки и т.п.
А я серьезно и воспринял, установил, настроил nitrogen начал туториал с сайта nitrogen проходить :) Или лучше сначала сам я зык изучать?
Пожалуй начать лучше отсюда rsdn.ru/article/erlang/GettingStartedWithErlang.xml т.е. сам язык подучить все же сперва нужно (мне недели хватило для более-менее уверенного использования, хотя дзен до сих пор не познал:)).
А в качестве REST API фреймворка на эрланге чуть ниже порекомендовали habrahabr.ru/blogs/development/108973/#comment_3456783 webmachine. Я его не пробовал, фигачил напрямую на Mochiweb.
А в качестве REST API фреймворка на эрланге чуть ниже порекомендовали habrahabr.ru/blogs/development/108973/#comment_3456783 webmachine. Я его не пробовал, фигачил напрямую на Mochiweb.
А для редактирования что используете? Полноценной IDE, как я понял, нет, пока в gedit редактирую, хоть подсветка есть.
erlide.org/ очень даже полноценная IDE — плагин для Eclipse. Поддерживает отладку даже пошаговую, ошибки умеет диагностировать (статический анализ?). Всякие там автоподстановки, подсветки — все как положено. Активно развивается.
Вот быстрый старт посмотрите т.к. там нужно небольшую преднастройку сделать чтоб все фичи работали erlide.org/erlide.html#gettingStarted
Вот быстрый старт посмотрите т.к. там нужно небольшую преднастройку сделать чтоб все фичи работали erlide.org/erlide.html#gettingStarted
А, настройку я как-то и пропустил из-за чего ошибка постоянно вылетала, решил неюзабельно :) Спасибо
В напутствие — небольшой «Джентельменский набор»:
github.com/mochi/mochiweb Mochiweb — базовый довольно мощный веб-сервер + хелперы для парсинга JSON и еще пара мелочей.
github.com/evanmiller/erlydtl ErlyDTL порт шаблонного языка из Django (хотя для построения API вряд ли понадобится)
github.com/wg/epgsql драйвер PostgreSQL
github.com/josephwecker/epgsql_pool — пулл соединений с Postgre
github.com/dizzyd/erlang-mysql-driver — драйвер MySQL с поддержкой пуллинга соединений
В эрланге есть встроенная поддержка ODBC, но я пользоваться не пробовал.
Есть несколько модулей для работы с мемкешем, у всех есть свои слабые и сильные стороны. Кто поддерживает бинарный протокол, кто нет; кто поддерживает работу с несколькими серверами с хешированием ключей, кто нет… Выбор есть в общем.
Ну и как то мне показалось, что документацию разработчики модулей очень не любят писать, так что есть смысл смотреть сразу в код модулей, можно найти полезные недокументированные возможности.
И да, пожалуй нужно иметь базовое представление о Gnu Make, т.к. он активно используется для сборки проектов и модулей, прогона юнит-тестов.
github.com/mochi/mochiweb Mochiweb — базовый довольно мощный веб-сервер + хелперы для парсинга JSON и еще пара мелочей.
github.com/evanmiller/erlydtl ErlyDTL порт шаблонного языка из Django (хотя для построения API вряд ли понадобится)
github.com/wg/epgsql драйвер PostgreSQL
github.com/josephwecker/epgsql_pool — пулл соединений с Postgre
github.com/dizzyd/erlang-mysql-driver — драйвер MySQL с поддержкой пуллинга соединений
В эрланге есть встроенная поддержка ODBC, но я пользоваться не пробовал.
Есть несколько модулей для работы с мемкешем, у всех есть свои слабые и сильные стороны. Кто поддерживает бинарный протокол, кто нет; кто поддерживает работу с несколькими серверами с хешированием ключей, кто нет… Выбор есть в общем.
Ну и как то мне показалось, что документацию разработчики модулей очень не любят писать, так что есть смысл смотреть сразу в код модулей, можно найти полезные недокументированные возможности.
И да, пожалуй нужно иметь базовое представление о Gnu Make, т.к. он активно используется для сборки проектов и модулей, прогона юнит-тестов.
Фейсбук использует именно OAuth, чтобвызнали. Помимо OAuth, почитайте ещё про REST, прежде чем сочинять велосипеды.
И ведь толпы народу сейчас по этой «статье» кинутся чего-то писать…
И ведь толпы народу сейчас по этой «статье» кинутся чего-то писать…
простите, я имею ввиду их API для приложений.
developers.facebook.com/docs/authentication/ самая первая строчка «Facebook Platform uses the OAuth 2.0 protocol for authentication and authorization.»
Вконтакте да, велосипед тоже с сигнатурами
Вконтакте да, велосипед тоже с сигнатурами
И нет возможности взамодействия сервер-сервер. Во всяком случае, у меня прикрутить их вариант для mobile-устройств к сайту не получается.
Или я не прав и всё-таки можно?
Или я не прав и всё-таки можно?
Я писал консольную софтину которая по e-mail ищет юзера в фейсбуке тут писал об этом habrahabr.ru/blogs/facebook/102964/#comment_3317822
> сигнатуры позволяют проверить целостность запроса+пользователями API могут быть не только люди, но и другие системы.
ну, с точки зрения чего бы то ни было, разницы между людьми и отдельными системами нет никакой ;)
> команды входят в URL — можно считать что они имеют отдельные урлы.
с точки зрения RFC URL все же один
> Не вижу особых причин делать работу API непредсказуемой
«Непредсказуемые» — это про GET, POST, DELETE? Вообще-то, как раз наоборот — использование стандартизированных типов делают API предсказуемым.
ну, с точки зрения чего бы то ни было, разницы между людьми и отдельными системами нет никакой ;)
> команды входят в URL — можно считать что они имеют отдельные урлы.
с точки зрения RFC URL все же один
> Не вижу особых причин делать работу API непредсказуемой
«Непредсказуемые» — это про GET, POST, DELETE? Вообще-то, как раз наоборот — использование стандартизированных типов делают API предсказуемым.
В микроформатах рекомендуется /login.xml и /login.json :)
Я подумал, что UrlRewrite это какой-то аналог апачевского mod_rewrite или роутеров на ЯП и преобразовать по шаблону URL в список параметров (например /login.xml -> api.aspx?command=login&format=json) для него не проблема
В новых (IIS7+) уже не надо. В интегрированном пайплайне все ходит через асп.нет приложение кроме статики.
Для этого есть стандартный хеадер Accept. Там указываеш application/json или application/xml. Это мение удобно с точки зрения разраболтчика, зато по идее правильней. Хотя никто не мешает обьеденить эти два подхода.
/login.xml
/login.json
выглядит лучше
/login.json
выглядит лучше
Не очень люблю расширения в урлах. Как-то сильно технично. Мне больше нравятся просто урлы типа habrahabr.ru/blogs/development/108973/. Но это я думаю дело вкуса. Тем более что РоР сапортит и урлы и хеадер Accept, не так ли?
да, так
Ну, расширения предназначены не для людей, а для других серверов/аяксов — расширение по умолчанию html. С заголовками оно, конечно, правильней, но громоздко :)
Громоздкость зависит тока от ферймворка, в большенстве случаев это просто дается забезплатно. Например в .NET WCF Data Services вы указываете тока источник данных, а фреймворк уже сам вернет нужные типы в зависимости от запроса.
Вы про фреймворк на стороне сервера или клиента? А вообще иногда со слишком «умными» фреймворками (или самописными обработчиками) приходится бороться вплоть до написания своего кода, например, если приоритеты в противоречащих запросах не устраивают (Accept хочет html, а расширение просит xml) — тут как повезёт
«Как повезет», конечно же, не должно быть. WCF просто позволяет не задумываться что «там дальше» и решает эту проблему за вас. Я предпочитаю REST как архитектуру, но реализовывать приходится самому — тут как раз полный контроль — кому что и как отдать, по какому запросу (Resource Request) и с каким MIME-типом.
пост о том, как НЕ надо писать API
А теперь должен идти пост о том, как НАДО писать API. Возьметесь?
Вот, например, WCF в .net. Там совершенно другой уровень простоты и прозрачности. Все те вещи, которые автор тут изобретает, там просто сделаны во фреймворке, причем стандартным образом.
«может я дурак и всё такое… но я в глаза никогда не видел ни WCF, ни .net — и вряд ли увижу, да и разбираться я во всех тонкостях конкретной реализации просто не хочу — мне жалко моё время.»
А не надо разбираться во всех тонкостях. Ровно наоборот — надо посмотреть общую документацию и примеры кода.
«Скажите — как мне ваша информация может помочь написать свой API, для php движка?»
Ну, я думал, что вы-таки пойдете и прочитаете. Можно еще Фаулера почитать, в принципе, там есть про огранизацию сервисного слоя.
Понимаете ли, в чем дело. Для веб-сервисов уже давно есть стандарты (уже упомянутый ниже WS*), и разрабатывая свой API неплохо бы их почитать. А автор статьи их радостно проигнорировал. Как следствие, любой, кому понадобится взаимодействовать с его API, будет вынужден разбираться в этом конкретном велосипеде вместо того, чтобы взять миллион уже существующих готовых решений.
Поэтому «как надо»? Надо по стандартам.
И тогда вопрос «как написать api» из всех этих рассуждений о параметрах, ответах и структуре команды превратится в нормальный вопрос: «как мне написать api» — то есть, из каких методов состоит ваш API, и как именно они реализованы на сервере. А не «как бы нам передать параметры с клиента на сервер и обратно».
Ну и да. Из статьи никак не следует, что она только для php-движков. Блог вроде называется «разработка», и в заголовке слова php нет, и в тексте статьи тоже не очень. Поэтому извините, но я ее оцениваю в контексте общих знаний, а не частных.
А не надо разбираться во всех тонкостях. Ровно наоборот — надо посмотреть общую документацию и примеры кода.
«Скажите — как мне ваша информация может помочь написать свой API, для php движка?»
Ну, я думал, что вы-таки пойдете и прочитаете. Можно еще Фаулера почитать, в принципе, там есть про огранизацию сервисного слоя.
Понимаете ли, в чем дело. Для веб-сервисов уже давно есть стандарты (уже упомянутый ниже WS*), и разрабатывая свой API неплохо бы их почитать. А автор статьи их радостно проигнорировал. Как следствие, любой, кому понадобится взаимодействовать с его API, будет вынужден разбираться в этом конкретном велосипеде вместо того, чтобы взять миллион уже существующих готовых решений.
Поэтому «как надо»? Надо по стандартам.
И тогда вопрос «как написать api» из всех этих рассуждений о параметрах, ответах и структуре команды превратится в нормальный вопрос: «как мне написать api» — то есть, из каких методов состоит ваш API, и как именно они реализованы на сервере. А не «как бы нам передать параметры с клиента на сервер и обратно».
Ну и да. Из статьи никак не следует, что она только для php-движков. Блог вроде называется «разработка», и в заголовке слова php нет, и в тексте статьи тоже не очень. Поэтому извините, но я ее оцениваю в контексте общих знаний, а не частных.
Ну так я предполагаю, что даже новичок способен набрать в гугле WS* и получить второй же ссылкой сайт Web Services Interoperability. В случае с WCF — первая ссылка.
Так что вы спросили «как надо» — я вам показал, куда посмотреть.
Так что вы спросили «как надо» — я вам показал, куда посмотреть.
см мой коммент ниже
> ну php я привёл просто в качестве примера, но было бы просто здорово если бы вы накидали ссылок на стандарты (хот бы одну), чтобы любой новичок мог от чего-то оттолкнутся. И всё!!! И нет проблемы!!!
RESTful Web Services от O'Reilly. Снимает все вопросы о том, как проектировать REST
RESTful Web Services от O'Reilly. Снимает все вопросы о том, как проектировать REST
Топикстартер упомянул REST в топике, но видимо он вообще не знает что, такое REST. выдумал какието Модули, Менеджеры, Реестры. Когда все прозрачно делается через REST для: HTML, JSON, XML
например
все ясно и понятно.
кто не понял, что это rails объясню:
например контроллер user_sessions выполняет аутентификацию, причем стандартным REST путем:
new — отоброжает страничку логина
create — сама аутентификация
destroy — соотвественно выход из системы
код контроллера у меня один на html/json/xml запрос
зачем отдельное API когда все унифицированно по REST?
например
register /register(.:format) {:controller=>"users", :action=>"new"} login /login(.:format) {:controller=>"user_sessions", :action=>"new"} logout /logout(.:format) {:controller=>"user_sessions", :action=>"destroy"} users GET /users(.:format) {:controller=>"users", :action=>"index"} POST /users(.:format) {:controller=>"users", :action=>"create"} new_user GET /users/new(.:format) {:controller=>"users", :action=>"new"} edit_user GET /users/:id/edit(.:format) {:controller=>"users", :action=>"edit"} user GET /users/:id(.:format) {:controller=>"users", :action=>"show"} PUT /users/:id(.:format) {:controller=>"users", :action=>"update"} DELETE /users/:id(.:format) {:controller=>"users", :action=>"destroy"} user_sessions GET /user_sessions(.:format) {:controller=>"user_sessions", :action=>"index"} POST /user_sessions(.:format) {:controller=>"user_sessions", :action=>"create"} new_user_session GET /user_sessions/new(.:format) {:controller=>"user_sessions", :action=>"new"} edit_user_session GET /user_sessions/:id/edit(.:format) {:controller=>"user_sessions", :action=>"edit"} user_session GET /user_sessions/:id(.:format) {:controller=>"user_sessions", :action=>"show"} PUT /user_sessions/:id(.:format) {:controller=>"user_sessions", :action=>"update"} DELETE /user_sessions/:id(.:format) {:controller=>"user_sessions", :action=>"destroy"} countries GET /countries(.:format) {:controller=>"countries", :action=>"index"} POST /countries(.:format) {:controller=>"countries", :action=>"create"} new_country GET /countries/new(.:format) {:controller=>"countries", :action=>"new"} edit_country GET /countries/:id/edit(.:format) {:controller=>"countries", :action=>"edit"} country GET /countries/:id(.:format) {:controller=>"countries", :action=>"show"} PUT /countries/:id(.:format) {:controller=>"countries", :action=>"update"} DELETE /countries/:id(.:format) {:controller=>"countries", :action=>"destroy"}
все ясно и понятно.
кто не понял, что это rails объясню:
например контроллер user_sessions выполняет аутентификацию, причем стандартным REST путем:
new — отоброжает страничку логина
create — сама аутентификация
destroy — соотвественно выход из системы
код контроллера у меня один на html/json/xml запрос
зачем отдельное API когда все унифицированно по REST?
вот кстати код контроллера countries:
$ cat app/controllers/countries_controller.rb class CountriesController < InheritedResources::Base respond_to :html, :xml, :json end
curl http://localhost:3000/countries.xml | head -10 <?xml version="1.0" encoding="UTF-8"?> <countries type="array"> <country> <name>Australia</name> <created-at type="datetime">2010-11-25T17:49:21Z</created-at> <location nil="true"></location> <updated-at type="datetime">2010-11-25T17:49:48Z</updated-at> <iso2>AU</iso2> <location-ru>Океания</location-ru> <id type="integer">1</id> curl -q http://localhost:3000/countries.json | head -c 200 [{"country":{"name":"Australia","created_at":"2010-11-25T17:49:21Z","location":null,"updated_at":"2010-11-25T17:49:48Z","iso2":"AU","location_ru":"\u041e\u043a\u0435\u0430\u043d\u0438\u044f","id":1,"i
О, спасибо за идею new_user_session GET /user_sessions/new(.:format), а то я делал что вроде login_form_user GET /users/login/new(.:format)
P.S. На Ruby это красивее и проще выглядит чем хоть на PHP, хоть на YAML, хоть на XML
P.S. На Ruby это красивее и проще выглядит чем хоть на PHP, хоть на YAML, хоть на XML
я не понял. почему edit_user — это GET? ведь, по идее, edit_user — это PUT? или это отображаемая форма, а всё работает через
Дальше — а что, если нам надо еще добавить блокировку юзера, авторизацию юзера, изменения прав юзера.
а если у нас на странице проиходит добавление и одновременное отображение формы (если запрос не удался — показывается та же форма с ошибками, если удался — редиректится на нужную страницу).
Мне РЕСТ не кажется правильным. Он или избыточен или недостаточно широк.
И эту штуку, имхо, понятнее и легче было бы записать так:
PUT /users/:id
? А не нужно ли тогда взять :id в скобки PUT /users/(:id)
на случай, если мы добавляем нового юзера и формат не указываем? Этот момент точно не знаю, как в Рейлз оно организовано — просто уточняю?Дальше — а что, если нам надо еще добавить блокировку юзера, авторизацию юзера, изменения прав юзера.
а если у нас на странице проиходит добавление и одновременное отображение формы (если запрос не удался — показывается та же форма с ошибками, если удался — редиректится на нужную страницу).
Мне РЕСТ не кажется правильным. Он или избыточен или недостаточно широк.
user GET /users/:id
PUT /users/:id
DELETE /users/:id
И эту штуку, имхо, понятнее и легче было бы записать так:
user /users/
/users/:id
/users/edit
/users/edit/:id
/users/delete/:id
а если у нас на странице проиходит добавление и одновременное отображение формы
Хотя на счёт этого я сморозил. Оно ведь для Апи используется, там вполне есть разделение на изменение и отображение, но всё равно я не вижу особых причин пользовать GET-POST-PUT-DELETE
и да, почему create countries — это POST, а не PUT?
Более того, советую ознакомиться с webmachine.basho.com/diagram.html
REST во-многом мощнее, чем можно себе представить. Только мне известен ровно один фреймворк, который позволяет полноценно его реализовать без лишнего геморроя.
REST во-многом мощнее, чем можно себе представить. Только мне известен ровно один фреймворк, который позволяет полноценно его реализовать без лишнего геморроя.
Какой фреймворк, поделитесь?
А вот тот самый, по ссылке. Webmachine. Правда, только для Erlang'а :)
Так то что для Erlang это наоборот преимущество! Вы с ним работали? Если да, поделитесь впечатлениями? Насколько сложные вещи на нем удалось собрать? Как производительность, общие впечатления?
К сожалению, ничего особо большого я с ним не собирал :(
Общие впечатления: круто. Впервые можно делать REST и, по большому счету, не парить себе мозг :)
Общие впечатления: круто. Впервые можно делать REST и, по большому счету, не парить себе мозг :)
Черт. Что-то кнопка нажалась
По сути досаточно реализовывать нужные тебе функции из webmachine.basho.com/resources.html Все остально сделает аутомагия :)
Насчет роизводительности… В целом, должно работать со скоростью mochiweb ± накладные расходы на сам фреймворк. В прошлом году mochiweb сравнивали с nginx тут: www.joeandmotorboat.com/2009/01/03/nginx-vs-yaws-vs-mochiweb-web-server-performance-deathmatch-part-2/
Главное, что внушает надежду — то что webmachine делается сейчас для нужд nosql-базы данных Riakтаnfr xnтатам и со стабильностью и с производительностью должно быть ок.
По сути досаточно реализовывать нужные тебе функции из webmachine.basho.com/resources.html Все остально сделает аутомагия :)
Насчет роизводительности… В целом, должно работать со скоростью mochiweb ± накладные расходы на сам фреймворк. В прошлом году mochiweb сравнивали с nginx тут: www.joeandmotorboat.com/2009/01/03/nginx-vs-yaws-vs-mochiweb-web-server-performance-deathmatch-part-2/
Главное, что внушает надежду — то что webmachine делается сейчас для нужд nosql-базы данных Riakтаnfr xnтатам и со стабильностью и с производительностью должно быть ок.
Спасибо.
С Mochiweb я работал (особенно впечатлила эта статья), впечатления только положительные, хотя первое время несколько непривычно.
Надо будет посмотреть на Webmachine как нибудь хотябы для общего развития.
Спасибо еще раз.
С Mochiweb я работал (особенно впечатлила эта статья), впечатления только положительные, хотя первое время несколько непривычно.
Надо будет посмотреть на Webmachine как нибудь хотябы для общего развития.
Спасибо еще раз.
Принято такое разделение:
GET /objs — список
GET /objs/id — объект
GET /objs/new — форма для создания объекта (для html прежде всего)
POST /objs — запрос на создание новог объект
GET /objs/id/edit — форма редактирования объекта (для html)
PUT /objs/id — запрос на редактирование объекта
DELETE /objs/id — запрос на удаление объекта
формат по умолчанию html (веб-интерфейс)
При успешном действии POST/PUT/DELETE — редирект 303 (увы, далеко не все клиенты поддерживают 2хх коды с Location), при ошибки валидации или ещё какой — повтор формы для html, сообщение об ошибке для других
Блокировку юзера я бы сделал PUT /users/id/block, форма для просмотра ролей GET /users/id/roles (список ролей), присвоение новой роли POST /users/id/roles
Порядок соответствует выражению (псевдокод) collection.getById(id).action
POST — типа вывесить что-то там где раньше не было, PUT — положили назад (изменив) то, что раньше получили (по GET ). Семантические нюансы в общем.
GET /objs — список
GET /objs/id — объект
GET /objs/new — форма для создания объекта (для html прежде всего)
POST /objs — запрос на создание новог объект
GET /objs/id/edit — форма редактирования объекта (для html)
PUT /objs/id — запрос на редактирование объекта
DELETE /objs/id — запрос на удаление объекта
формат по умолчанию html (веб-интерфейс)
При успешном действии POST/PUT/DELETE — редирект 303 (увы, далеко не все клиенты поддерживают 2хх коды с Location), при ошибки валидации или ещё какой — повтор формы для html, сообщение об ошибке для других
Блокировку юзера я бы сделал PUT /users/id/block, форма для просмотра ролей GET /users/id/roles (список ролей), присвоение новой роли POST /users/id/roles
Порядок соответствует выражению (псевдокод) collection.getById(id).action
POST — типа вывесить что-то там где раньше не было, PUT — положили назад (изменив) то, что раньше получили (по GET ). Семантические нюансы в общем.
edit_user — это вывод формочки для редактирования, поэтому GET
Как по мне, так очень похоже на архитектуры многих MVC фреймворков:
Manager — фронт-контроллер (инициализация, роутинг и другой «мидлвар», включая проверку подписи)
Module — судя по всему контроллер+action
Registry — обёртка для запроса
Response — обёртка для ответа, включая view
Если ошибаюсь — поправьте, может я что-то упустил, может вы забыли что-то упомянуть. А если нет: была большая необходимость в изобретении велосипеда своего?
Manager — фронт-контроллер (инициализация, роутинг и другой «мидлвар», включая проверку подписи)
Module — судя по всему контроллер+action
Registry — обёртка для запроса
Response — обёртка для ответа, включая view
Если ошибаюсь — поправьте, может я что-то упустил, может вы забыли что-то упомянуть. А если нет: была большая необходимость в изобретении велосипеда своего?
Да, патерны примерно правильно распределены. Только module — comand.
Собственно, важен не велосипед — а конечная реализация. Этот набор классов был несколько раз переписан и показал себя оптимальным с точки зрения производительности и расширяемости.
Собственно, важен не велосипед — а конечная реализация. Этот набор классов был несколько раз переписан и показал себя оптимальным с точки зрения производительности и расширяемости.
… вот только паттерн MVC вообще не имеет отношения к разработке внешнего api. В отличие от паттернов service layer, facade и так далее.
Отсюда сразу путаница в дальнейшем анализе. Manager — это дейтвительно фронт-контроллер, Module — это команда, как верно сказано ниже, а вот реестр и респонс — это совсем не то, что кажется. Во-первых, ни для чего они не обертки. В «правильной» системе первого просто не должно быть, а второе — это либо декоратор, либо часть фронт-контроллера, в зависимости от реализации.
Отсюда сразу путаница в дальнейшем анализе. Manager — это дейтвительно фронт-контроллер, Module — это команда, как верно сказано ниже, а вот реестр и респонс — это совсем не то, что кажется. Во-первых, ни для чего они не обертки. В «правильной» системе первого просто не должно быть, а второе — это либо декоратор, либо часть фронт-контроллера, в зависимости от реализации.
Ну если ясно написано, что «заворачивает в себя входящие данные под чутким руководством объекта Manager» значит обёртка :)
А вообще коммент был о том, что подобный функционал вероятно можно реализовать на практически любом MVC фреймворке
А вообще коммент был о том, что подобный функционал вероятно можно реализовать на практически любом MVC фреймворке
Зачем? Это гвозди микроскопом. То, что MVC-фреймворк (в вебе) реализует паттерн «request processing», еще не повод его всюду пихать. Оверхед будет совершенно нездоровый. Спуститься на уровень ниже и обрабатывать прямо сразу реквесты — намного дешевле.
Какая часть фреймворка будет не нужна? Особенно учитывая, что к этому API, похоже есть обычный веб-интерфейс (по крайней мере других UI с JS сходу не припомню :) )
View Engine, как минимум (а это дохрена). Плюс, на самом деле, все эти заморочки с controller/action не нужны, в SOA это прямолинейнее (есть конкретный сервис с конкретным описанием, у него есть методы), плюс подстановка параметров намного более формализованная — ну и так далее.
Ну это смотря где дохрена, там где используются отдельные шаблонизаторы — наверняка, а там где допускается «спагетти» из ЯП и языка разметки её, считайте, и нет.
На самом деле, не зная задачи сложно говорить, что лучше — одно дело прицепить веб-апи к существующему сервису, скажем интранет приложению с десктопным клиентом, совсем другое реализовать какой-то сервис с нуля предоставив к нему и обычный веб-интерфейс (плюс «продажный» сайт), и веб-апи.
На самом деле, не зная задачи сложно говорить, что лучше — одно дело прицепить веб-апи к существующему сервису, скажем интранет приложению с десктопным клиентом, совсем другое реализовать какой-то сервис с нуля предоставив к нему и обычный веб-интерфейс (плюс «продажный» сайт), и веб-апи.
«Ну это смотря где дохрена, там где используются отдельные шаблонизаторы — наверняка, а там где допускается «спагетти» из ЯП и языка разметки её, считайте, и нет.»
Ой, да ну. А выбор нужного вью? А разбор спагетти?
Ой, да ну. А выбор нужного вью? А разбор спагетти?
А что там выбирать? Передать константу с именем шаблона?
Разбор транслятор обеспечивает, то есть для сервиса отдающего json, а не html, вместо вызова пары методов и инклуда одного файла будет вызвана «нативная» функция преобразования объекта в json.
А вообще давайте заканчивать обсуждение с помощью чего лучше писать сферический веб-сервис в вакуумном окружении :)
Разбор транслятор обеспечивает, то есть для сервиса отдающего json, а не html, вместо вызова пары методов и инклуда одного файла будет вызвана «нативная» функция преобразования объекта в json.
А вообще давайте заканчивать обсуждение с помощью чего лучше писать сферический веб-сервис в вакуумном окружении :)
Ну как бы пост изначально про то «с помощью чего лучше писать сферический веб-сервис в вакуумном окружении».
Да какая разница. Ну представьте, что это не один из существующих, а такой сам по себе, легковесный MVC-фреймворк.
А смысл?
Здесь нет ни Model, ни View.
Здесь нет ни Model, ни View.
Ну, начнем с того, что где-то есть Model. А, к примеру, JSON — это просто один конкретный вариант View.
Тот факт, что где-то есть Model не делает Remote Facade MVC, правда?
MVC — этот UI-паттерн. Если уж мы хотим говорить в терминах паттернов, то давайте применять их по месту, а не просто «потому что похоже». Веб-сервис — это контроллер (или фронт контроллер).
MVC — этот UI-паттерн. Если уж мы хотим говорить в терминах паттернов, то давайте применять их по месту, а не просто «потому что похоже». Веб-сервис — это контроллер (или фронт контроллер).
Ох, да как хотите можете называть :) Это просто еще один уровень абстрации — в любом случае! Тут можно не спорить, стоит лишь отметить, что из самого поста не понятно, о чем речь — это и не о формате или принципе (SOAP/REST), не о каком-то архитектурном подходе (MVC/Remote Facade) и не о конкретном фреймворке.
Я так понял, автор просто высказал свой Opinion, вне зависимости от архитектуры, подходов и технологий. Потому и непонятно, как это «переваривать», а мы спорим тут, паттерны, не паттерны.
Я так понял, автор просто высказал свой Opinion, вне зависимости от архитектуры, подходов и технологий. Потому и непонятно, как это «переваривать», а мы спорим тут, паттерны, не паттерны.
Да нет, автор как раз навязывает нам свой формат — json и querystring, свой подход (фронт контроллер) и так далее. Совершенно игнорируя факт существования готово инфраструктуры.
Мы, видимо, говорим об одном и том же, но под разными… хмм… углами что ли.
Я понимаю, есть куча готовых фреймворков для самого разного рода задач и полностью согласен, что не надо придумывать никаких костылей/велосипедов/автомобилей/самолетов, чтобы можно было «очень просто и понятно и удобно» сделать из любого веб-фреймворка (например) WCF-сервис. Ибо если такая задача появляется — WCF и нужно использовать (WCF исключительно в качестве примера).
Я понимаю, есть куча готовых фреймворков для самого разного рода задач и полностью согласен, что не надо придумывать никаких костылей/велосипедов/автомобилей/самолетов, чтобы можно было «очень просто и понятно и удобно» сделать из любого веб-фреймворка (например) WCF-сервис. Ибо если такая задача появляется — WCF и нужно использовать (WCF исключительно в качестве примера).
«вот только паттерн MVC вообще не имеет отношения к разработке внешнего api»
Еще как имеет. Внутренняя архитектура диктует сложность/простоту создания на ней того или иного рода API.
Как показывает практика, любое такое вот легковесное начинание, когда начинает обрастать «мясом» (причем, необходимым), получается уже не таким «простым и легковесным».
Еще как имеет. Внутренняя архитектура диктует сложность/простоту создания на ней того или иного рода API.
Как показывает практика, любое такое вот легковесное начинание, когда начинает обрастать «мясом» (причем, необходимым), получается уже не таким «простым и легковесным».
Почему Registry и Response — синглтоны? Вы смотрите на приложение только в разрезе разработки под plain PHP? В режиме FastCGI (даже на пхп), или на node.js, или на чём-угодно другом такой подход совершенно неоправдан.
Вам на кажется, что это один модуль? auth[action=open] + auth[action=close]
Почему название открытия — auth, а закрытия — log_out. Почему не login-logout? или auth_open/auth_close?
То, что вы описали как модули, обычно интерфейс отдельного модуля.
Что за модуль такой? Просмотр списка записей чего? Списка комментариев? Списка статтей? Списка юзеров. Аналогично по другим модулям.
Пока не очень…
# auth — открытие соединения с API
# log_out — собственно закрытие соединения
Вам на кажется, что это один модуль? auth[action=open] + auth[action=close]
Почему название открытия — auth, а закрытия — log_out. Почему не login-logout? или auth_open/auth_close?
То, что вы описали как модули, обычно интерфейс отдельного модуля.
list — просмотр списка записей
Что за модуль такой? Просмотр списка записей чего? Списка комментариев? Списка статтей? Списка юзеров. Аналогично по другим модулям.
Пока не очень…
login-logout — вероятно перейду на эту систему именования, спасибо.
list и прочие — это примеры команд. Данный набор команд был для простенького органайзера, list выводил список заданий и принимал в аргументах параметры выбора и прочее.
list и прочие — это примеры команд. Данный набор команд был для простенького органайзера, list выводил список заданий и принимал в аргументах параметры выбора и прочее.
Немного не по статье, но по теме: Насколько удобно/эффективно использовать API на своем же сайте (страница составляется без контента, контент забирается отдельно), вместо генерации страниц (страница содержит контент)?
p.s. использую — django, для api — piston
p.s. использую — django, для api — piston
Ох. А зачем изобретать велосипед, когда уже давно есть WS*, в частности, WS-Security?
Ну и да, вот вы изобрели велосипед, а в том же .net он прекрасно реализован до вас. Соответственно, вы мало того, что изобрели велосипед, так еще и сделали его несовместимым — есть же прекрасная вещь faultContract, так нет, вы зачем-то свой response изобретаете.
А если вы посмотрите на то, как сделано в WCF и прочих интересных местах, то быстро поймете, что ни Registry, ни Response вам не нужен — вы должны разобрать входные параметры и прямо передать их в «модуль», а потом точно так же разобрать его ответ и вернуть как положено.
Ну и да, вот вы изобрели велосипед, а в том же .net он прекрасно реализован до вас. Соответственно, вы мало того, что изобрели велосипед, так еще и сделали его несовместимым — есть же прекрасная вещь faultContract, так нет, вы зачем-то свой response изобретаете.
А если вы посмотрите на то, как сделано в WCF и прочих интересных местах, то быстро поймете, что ни Registry, ни Response вам не нужен — вы должны разобрать входные параметры и прямо передать их в «модуль», а потом точно так же разобрать его ответ и вернуть как положено.
Вообще многие технологии MS (кроме IE ;-( ) проходят мимо веб-разработчиков в силу, скажем так, коньюктурных причин :)
Эм. Во-первых WS* — это не MS-технология. Во-вторых, все-таки, в курсе быть полезно.
>> * возможность расширения
Так и не понял, что именно вы сделали для возможности расширения. Потому что не понятно, что именно будет расширяться.
>> * удобный стандартизированный формат запросов
SOAP.
>> * удобный стандартизированный формат ответов
SOAP
>> * достаточный уровень безопасности
Безопасности чего? Данных? Передачи данных? Вообще, при чем тут безопасность?
>> * возврат ошибок выполнения запроса
Боюсь показаться КО, но снова же SOAP.
Так и не понял, что именно вы сделали для возможности расширения. Потому что не понятно, что именно будет расширяться.
>> * удобный стандартизированный формат запросов
SOAP.
>> * удобный стандартизированный формат ответов
SOAP
>> * достаточный уровень безопасности
Безопасности чего? Данных? Передачи данных? Вообще, при чем тут безопасность?
>> * возврат ошибок выполнения запроса
Боюсь показаться КО, но снова же SOAP.
xml, имхо, недостаток.
Недостаток чего?
почти всего, что его использует ;)
Странно, но в моей практике как раз все наоборот. Один сплошной XML. Выгрузить кредитные дела из банка в БКИ? XML!
Срастить несколько банковских систем? XML! Куда ни плюнь, везде XML.
Попробуйте json при помощи XSLT куда-то преобразовать.
Срастить несколько банковских систем? XML! Куда ни плюнь, везде XML.
Попробуйте json при помощи XSLT куда-то преобразовать.
а еще html — это тоже xml.
а зачем json при помощи XSLT преобразовывать?
вы попробуйте сравните работу с xml и json при помощи javascript.
и для того и для другого есть удобные либы. но с джсоном работать намного приятнее.
а зачем json при помощи XSLT преобразовывать?
вы попробуйте сравните работу с xml и json при помощи javascript.
и для того и для другого есть удобные либы. но с джсоном работать намного приятнее.
Нет, html это sgml, а не xml.
Затем, что json существенно ограничивает варианты использования структуры.
Для меня не составляет проблем работать что с XML, что с json. ЧЯДНТ?
Ах вот оно что, приятнее работать. Вы знаете, я категорически не приветствую такой способ мышления. Потому что он ставит процесс создания продукта как основу всего мироздания. Если приятно работать вам, то это не значит, что всем остальным тоже будет приятно :)
Затем, что json существенно ограничивает варианты использования структуры.
Для меня не составляет проблем работать что с XML, что с json. ЧЯДНТ?
Ах вот оно что, приятнее работать. Вы знаете, я категорически не приветствую такой способ мышления. Потому что он ставит процесс создания продукта как основу всего мироздания. Если приятно работать вам, то это не значит, что всем остальным тоже будет приятно :)
Нет, html это sgml, а не xml.
да, прошу прощения, я про xhtml.
Затем, что json существенно ограничивает варианты использования структуры.
json предоставляет достаточно вариантов использования структуры, для того, чтобы сделать прозрачный и удобный апи.
Для меня не составляет проблем работать что с XML, что с json. ЧЯДНТ?
для меня тоже не составляет проблем. просто на так приятно, как с json.
Если приятно работать вам, то это не значит, что всем остальным тоже будет приятно
а я и не говорю, что остальным будет приятно. лично я сказал, что xml как недостаток — моё мнение. кто-то другой может считать иначе.
Не рассказывая почему XML является недостатком, первое высказывание сильно смахивает на фанатичное. Поэтому просьба, поясняйте что именно вы имеете в виду.
json гораздо труднее читать простому смертному. А чтение xml напрямую часто делается менеджерами, аналитиками, которые работают с данными.
json гораздо труднее читать простому смертному. А чтение xml напрямую часто делается менеджерами, аналитиками, которые работают с данными.
нет в json'е ничего труднее :) Если уж менеджеры научились XML читать, то надо просто JSON в похожий вид привести и все будет ок.
Возьмите человека с улицы и покажите ему XML и аналогичный по структуре json. Узнайте много нового про «ничего труднее».
То, что легко вам, не значит, что и легко другим.
То, что легко вам, не значит, что и легко другим.
Странно, у нас все менеджеры легко читают JSON и при этом у них рябит в глазах от перенасыщенности XML.
> Возьмите человека с улицы и покажите ему XML и аналогичный по структуре json. Узнайте много нового про «ничего труднее».
Я узнаю очень много нового про себя и про всех своих родственников в самой нелицеприятной форме.
Человек существо обучаемое. Благо ниж вы сами говорите, что «Привычка такая занятная штука».
Я узнаю очень много нового про себя и про всех своих родственников в самой нелицеприятной форме.
Человек существо обучаемое. Благо ниж вы сами говорите, что «Привычка такая занятная штука».
Зато это стандарт. Причем не только на бумаге, но и реально.
Вот SOAP с его гигантскими WSDL-ками весьма сомнительный формат для API сайта. Особенно для выполнения запросов к API прям из браузера.
Мне иногда кажется что его создали чтоб толкать дорогущий софт для проектирования этих всех WSDL и пр. Или я просто с плохим API работал (eBay) не знаю…
Мне иногда кажется что его создали чтоб толкать дорогущий софт для проектирования этих всех WSDL и пр. Или я просто с плохим API работал (eBay) не знаю…
За деревьями леса не видите. SOAP-библиотеки есть почти в каждом языке программирования. Вам не нужно уже работать с XML напрямую.
Есть конечно. Ими я и пользовался. Для просмотра структуры WSDL использовал Eclipse. Запросы из PHP библиотеки SoapClient к API eBay. Знаете, когда PHP-шный клиент загружает 3-х мегабайтный WSDL developer.ebay.com/webservices/latest/ebaySvc.wsdl это страшное зрелище…
Да и как мне к этому SOAP из браузера обращаться?
Да и как мне к этому SOAP из браузера обращаться?
«Знаете, когда PHP-шный клиент загружает 3-х мегабайтный WSDL»
для работы клиента wsdl не нужен, он нужен для его построения один раз
«Да и как мне к этому SOAP из браузера обращаться? „
Омг. Можно подумать, врапперов еще никто не написал. Выбираете тот, который вам больше нравится, и вперед.
для работы клиента wsdl не нужен, он нужен для его построения один раз
«Да и как мне к этому SOAP из браузера обращаться? „
Омг. Можно подумать, врапперов еще никто не написал. Выбираете тот, который вам больше нравится, и вперед.
Не хочу прослыть КО, но в нормальных браузерах есть нативная поддержка SOAP, в ненормальных есть flash, silverlight. Поэтому вопрос обращения не является проблемой уже много-много лет.
Интересно, когда же пхпшники начнут учиться?
Статью — в сборник антипаттернов.
Статью — в сборник антипаттернов.
Напишите обучающую статью на хабр. Мы прочитаем и подумаем, подходит ли нам ваш метод.
За меня все уже успел написать упомянутый выше Фаулер.
> При запросе сервер-клиент (AJAX-JavaScript) приходится использовать менее секурный вариант — secret хранится в cookie и меняется каждый сеанс.
Несовсем понял, можно более подробней?
Несовсем понял, можно более подробней?
упаси Вас б-г так брать это как пример
причем тут rails или php?
REST не зависит от языка и фреймворка
специально для Вас: www.google.com/search?q=php+rest&ie=utf-8&oe=utf-8
REST не зависит от языка и фреймворка
специально для Вас: www.google.com/search?q=php+rest&ie=utf-8&oe=utf-8
Первый вариант легко реализуется в PHP фреймворке symfony (в нём вообще довольно много взято из django, RoR, Java)
Не вполне понятно о чем пост. Если о форматах/стандартах/подходах, то у нас уже есть SOAP/WS-*/REST.
Если о том, как это «быстренько и просто» организовать внутри, архитектуру для этого — уже есть куча готовых веб-фреймворков (в первую очередь — MVC-фреймворки для всех платформ), средств для создания веб-сервисов, построения корпоративных SOA и всяких штучек вроде WCF.
Если же речь о том, какая именно надстройка должна быть над этими фреймворками и какой именно должен быть формат взаимодействия компонентов системы — это уже Opinion, частный случай, и его каждый формирует для себя, или под конкретный проект. Любой из существующих фреймворков позволяет построить именно такой opinion как у вас, или любой другой.
Если о том, как это «быстренько и просто» организовать внутри, архитектуру для этого — уже есть куча готовых веб-фреймворков (в первую очередь — MVC-фреймворки для всех платформ), средств для создания веб-сервисов, построения корпоративных SOA и всяких штучек вроде WCF.
Если же речь о том, какая именно надстройка должна быть над этими фреймворками и какой именно должен быть формат взаимодействия компонентов системы — это уже Opinion, частный случай, и его каждый формирует для себя, или под конкретный проект. Любой из существующих фреймворков позволяет построить именно такой opinion как у вас, или любой другой.
Есть одна проблема с md5(cmd+secret+data). Например, злоумышленник заставляет пользователя сделать cmd=«withdraw», data="{target:'badguy', amount:0.01}". Пользователю совершенно не жалко отдать 0.01, поэтому он соглашается. Злоумышленник перехватывает запрос и сохраняет его, после чего повторяет его серверу сколько угодно раз. Чтобы избежать этого, надо добавить либо время, либо некий sequence number.
Ещё можно рандом в достаточно большом диапазоне или guid вставить в data. А может в data уже есть уникальный токен запроса
Ага, salt надо.
Клиент должен первым запросом спросить у сервера salt, потом использовать его для кодирования хеша. Сервер, зная salt, может сравнить правильный хеш или нет. Тогда «перехватчику» от перехваченного мало толка, устанет запоминать результаты при достаточно разнообразном salt.
Как правило, в финансово важных данных уже есть «номер заказа», и повторно оплатить его не так то просто. Но, бывают разные системы, конечно.
Как правило, в финансово важных данных уже есть «номер заказа», и повторно оплатить его не так то просто. Но, бывают разные системы, конечно.
Я не против Вашей статьи, но поймите правильно: если Вы опираетесь в статье на REST, то будьте добры хотя бы поинтересоваться сперва что такое RESTful API. Ибо Вы нарушили все принципы и идеологию рест-а
Посетите группу на яху, погуглите на эту тему, прочтите пару книг (если позволяют возможности и знание англ, то на амазоне есть «RESTful webservices in practise»)
Парочка советов на скорую руку:
— для аутентификации с Вашим сервером прийдется писать либу: нарушена идеология KISS (используйте OAuth, APIKeys на крайний случай)
— используйте конечные понятные урлы, вместо невменяемых комманд
— используйте внятное указание формата (в урле или посмотрите как это делает гугль в GDS)
— используйте CRUD модель
ЗЫ: постараюсь более детально описать в своей статье в ближайшее время, похоже тема душещипательная и сильно назрела
Посетите группу на яху, погуглите на эту тему, прочтите пару книг (если позволяют возможности и знание англ, то на амазоне есть «RESTful webservices in practise»)
Парочка советов на скорую руку:
— для аутентификации с Вашим сервером прийдется писать либу: нарушена идеология KISS (используйте OAuth, APIKeys на крайний случай)
— используйте конечные понятные урлы, вместо невменяемых комманд
— используйте внятное указание формата (в урле или посмотрите как это делает гугль в GDS)
— используйте CRUD модель
ЗЫ: постараюсь более детально описать в своей статье в ближайшее время, похоже тема душещипательная и сильно назрела
А почему Manager занимается валидацией и проверкой данных? Что-то много на него)
Пои идее, роутинг и экшны нужно разделять…
Пои идее, роутинг и экшны нужно разделять…
Как делать автоматизированиые тесты на web-services?
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Написание web-API к своей системе