php rest api server

Введение в REST API — RESTful веб-сервисы

Эта статья начинает серию постов о разработке REST API:

php rest api server. Смотреть фото php rest api server. Смотреть картинку php rest api server. Картинка про php rest api server. Фото php rest api server
Intro to RESTful Web Services

REST означает REpresentational State Transfer (Википедия: «передача состояния представления»). Это популярный архитектурный подход для создания API в современном мире.

Вы изучите:

Что такое REST?

REST расшифровывается как REpresentational State Transfer. Это был термин, первоначально введен Роем Филдингом (Roy Fielding), который также был одним из создателей протокола HTTP. Отличительной особенностью сервисов REST является то, что они позволяют наилучшим образом использовать протокол HTTP. Теперь давайте кратко рассмотрим HTTP.

Краткий обзор HTTP

Давайте сначала откроем браузер и зайдем на веб-страницу:

php rest api server. Смотреть фото php rest api server. Смотреть картинку php rest api server. Картинка про php rest api server. Фото php rest api server

А затем щелкните на одной из страниц результатов:

php rest api server. Смотреть фото php rest api server. Смотреть картинку php rest api server. Картинка про php rest api server. Фото php rest api server

Далее мы можем нажать на ссылку на странице, на которой мы оказались:

php rest api server. Смотреть фото php rest api server. Смотреть картинку php rest api server. Картинка про php rest api server. Фото php rest api server

И перейти на другую страницу:

php rest api server. Смотреть фото php rest api server. Смотреть картинку php rest api server. Картинка про php rest api server. Фото php rest api server

Вот как мы обычно просматриваем веб страницы.

Когда мы просматриваем страницы в Интернете, за кулисами происходит много вещей. Ниже приведено упрощенное представление о том, что происходит между браузером и серверами, работающими на посещаемых веб-сайтах:

php rest api server. Смотреть фото php rest api server. Смотреть картинку php rest api server. Картинка про php rest api server. Фото php rest api server

Протокол HTTP

Когда вы вводите в браузере URL-адрес, например www.google.com, на сервер отправляется запрос на веб-сайт, идентифицированный URL-адресом.
Затем этот сервер формирует и выдает ответ. Важным является формат этих запросов и ответов. Эти форматы определяются протоколом HTTP — Hyper Text Transfer Protocol.

Когда вы набираете URL в браузере, он отправляет запрос GET на указанный сервер. Затем сервер отвечает HTTP-ответом, который содержит данные в формате HTML — Hyper Text Markup Language. Затем браузер получает этот HTML-код и отображает его на экране.

Допустим, вы заполняете форму, присутствующую на веб-странице, со списком элементов. В таком случае, когда вы нажимаете кнопку «Submit» (Отправить), HTTP-запрос POST отправляется на сервер.

HTTP и RESTful веб-сервисы

HTTP обеспечивает базовый уровень для создания веб-сервисов. Поэтому важно понимать HTTP. Вот несколько ключевых абстракций.

Ресурс

Ресурс — это ключевая абстракция, на которой концентрируется протокол HTTP. Ресурс — это все, что вы хотите показать внешнему миру через ваше приложение. Например, если мы пишем приложение для управления задачами, экземпляры ресурсов будут следующие:

URI ресурса

Когда вы разрабатываете RESTful сервисы, вы должны сосредоточить свое внимание на ресурсах приложения. Способ, которым мы идентифицируем ресурс для предоставления, состоит в том, чтобы назначить ему URI — универсальный идентификатор ресурса. Например:

REST и Ресурсы

Важно отметить, что с REST вам нужно думать о приложении с точки зрения ресурсов:
Определите, какие ресурсы вы хотите открыть для внешнего мира
Используйте глаголы, уже определенные протоколом HTTP, для выполнения операций с этими ресурсами.

Вот как обычно реализуется служба REST:

Компоненты HTTP

HTTP определяет следующую структуру запроса:

Методы HTTP-запроса

Метод, используемый в HTTP-запросе, указывает, какое действие вы хотите выполнить с этим запросом. Важные примеры:

Код статуса ответа HTTP

Код состояния всегда присутствует в ответе HTTP. Типичные примеры:

Резюме

В статье приведен на верхнем уровне обзор архитектурного стиля REST. Подчеркивается тот факт, что HTTP является основным строительным блоком REST сервисов. HTTP — это протокол, который используется для определения структуры запросов и ответов браузера. Мы видели, что HTTP имеет дело главным образом с ресурсами, доступными на веб-серверах. Ресурсы идентифицируются с помощью URI, а операции над этими ресурсами выполняются с использованием глаголов, определенных протоколом HTTP.

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

Источник

RESTful PHP — 5 простых советов

REST (Representational state transfer) — это архитектурный стиль или свод соглашений для web-приложений и сервисов, основанный на манипулировании ресурсами и спецификацией HTTP. Впервые об этом заговорил Рой Филдинг (Roy Fielding) — один из отцов основателей HTTP (Hypertext Transfer Protocol).

Web-приложения зачастую игнорируют спецификацию HTTP и двигаются вперёд используя полюбившиеся возможности: GET и POST, 200 OK и 404 NOT FOUND. Так как используются программируемые web-приложения, со своими собственными API, то решение игнорировать спецификацию HTTP, может создать проблемы в дальнейшем. Как следствие — имеем множество приложений с интерфейсами GET и POST. Например интерфейс удаления пользователя: GET /user/1/delete против POST /user/delete ; в случае REST можно указать /user/1 это ресурс, а удаление HTTP метод DELETE.

Такие важные методы HTTP, как — POST, GET, PUT и DELETE — зачастую сравнивают с CREATE, READ, UPDATE, DELETE (CRUD) операциями маниулирования базами данных. HTTP отделяет понятие web-сервер и web-браузер. Это позволяет каждой реализации отличаться от других подобных, основанных на «клиент/сервер» принципе.

Теперь самое время взглянуть на примеры, так будет понятнее.

1. Использование методов PUT и DELETE

2. Отправка выборочных HTTP 1.1 заголовков

PHP позволяет кастомизировать заголовки посылаемые клиенту. В свою очередь заголовок содержит код ответа от сервера. По умолчанию PHP ответит кодом 200 OK на успешный запрос, на использование функции die() или на создание нового ресурса. Собственно есть два пути кастомизировать ситуацию:

Первый вариант достаточно стандартный метод установки кода ответа. Если же потребуется указать перенаправление на ресурс «201 Created» или «301 Moved Permanently», это несложно реализовать, указав код в третьем параметре функции header(), как показано в примере. Второй пример можно заменить на более удобочитаемый код:

3. Отправка значимых HTTP заголовков

Смысл заключается в использовании прописанных в спецификации заголовков, которые являются вполне самодостаточными, но зачастую игнорируются или эмулируются более стереотипными решениями.

201 Created — используется если был создан новый ресурс. Должен применяться с функционалом направления на ресурс, например /tech/news, т.к. сам автоматического направления не использует.

202 Accepted — как бы говорит клиенту «ваш заказ принят и скоро будет обработан». В отличие от кода 201, который отсылается после создания ресурса, код 202 ставит запрос в очередь.

204 No Content — В связке с кэшированием и условным GET запросом (запросы с If-Modified-Since/If-None-Match заголовками), позволяет сказать web-приложениям «контент не изменился, продолжайте юзать кэшированную версию», без повторной переработки и отправки кэша.

401 Unauthorized — должен использоваться при попытке обратиться к ресурсу, требующему определённого уровня доступа. Используется в связке с www-authentication.

500 Internal Server Error — гораздо лучше 200 OK, когда PHP скрипт уже не дышит или привёл к исключению.

Естественно заголовков гораздо больше, на эту тему неоднократно было написано, приведённые выше — всего лишь примеры.

Настоящее RESTful PHP приложение должно быть полностью независимо, все запросы должны содержать достаточно информации чтобы на них можно было отреагировать без дополнительных усилий со стороны сервера. На практике это подразумевает сохранение авторизационной информации в куках с датой (timestamp) и контрольной суммой. Дополнительная информация так же может быть сохранена в куках. В случае если требуется сохранить большие объёмы данных, их можно уложить в базу данных, авторизационную информацию стоит оставить в куках. UPD: Надо оговориться, что использование cookies не в полной мере соответствует идеологии REST, т.к. сеансовые связи сохраняются. Но в случае cookies информация о сеансе хранится у клиента, а в случае использования session сеансовые связи хранятся во временной директории сервера и в сессионной куке клиента (если включен «session.use_cookies»).

5. Тестирование при помощи cURL или rest-client

cURL позволяет легко выполнять любые HTTP методы для нужного ресурса. Можно передавать любые параметры запросов и заголовков, а так же проверять ответные заголовки и данные. Инструмент коммандной строки «curl», стандартен для большинства *nix систем. Для пользователей Windows подойдёт MinGW/MSYS.

Пример использования и базовые опции:

-X [METHOD] определяет HTTP метод.
-d «name=value» устанавливает имя и значения переменных в POST/PUT.
-H [HEADER] устанавливает заголовок.
-I отображает заголовки ответа.

Так же существует бесплатный графический, основанный на Java/Swing, rest-client для тестирования REST. Он так же поддерживает JSON/XML.

Полезные ссылки по теме

Где так или иначе используется

* restful (англ.) — успокоительный; успокаивающий.

Источник

Php rest api server

Jacwright RESTServer v1.2.0

A PHP REST server for providing a very light-weight REST API. Very easy to set up and get going. Independent from other libraries and frameworks. Supports HTTP authentication.

Simple REST server in PHP

After building a couple of RESTful services using the Zend Framework, I decided to create a dead simple REST server that allowed me to skip all the features I didn’t need as well as a tons of classes that came with Zend Framework MVC. There are still useful features to add (XML support for example), but overall I’m quite happy with what I’ve come up with.

The RestServer class assumes you are using URL rewriting and looks at the URL from the request to map to the necessary actions. The map that gets a request from URL to class method is all in the doc-comments of the classes. Here is an example of a class that would handle some user actions:

Let’s walk through the above TestController class to talk about the features demonstrated. First we’ll look at the test method. You’ll notice there is a new kind of doc-comment tag in the docblock. @url maps a URL to the method below it and is in the form:

In this particular example, when someone does a GET on http://www.example.com/ (assuming example.com is where our service is located) it will print out:

which is a valid representation of a string in JSON.

One last thing to note in getUser is that this method simply returns a User object. This gets serialized into JSON (or potentially XML) and printed out for consumption by the application.

but POSTing a new user object for our saveUser method could look like this:

So you’re able to allow POSTing JSON in addition to regular web style POSTs.

In order to get the whole server kicked off, you’ll want to create an index.php file, have your URL rewriting direct requests to it (another topic which you can learn about elsewhere), and create the RestServer and add controller classes to it for handling. RestServer will cache the URL mappings between requests using APC or a file to speed up requests. You won’t have to load every controller file on every request if you use autoload and this cache, only the one needed for the request. The cache only runs in production mode. Here is an example index.php file:

That’s it. You can add as many classes as you like. If there are conflicts, classes added later will overwrite duplicate URL mappings that were added earlier. And the second parameter in addClass can be a base URL which will be prepended to URL mappings in the given class, allowing you to be more modular.

You can view the RestServer class, copy it and use it for your own purposes. It is under the MIT license. Features to be added include XML support and HTTP Authentication support. If you make this class better please share your updates with everyone by leaving a comment. I will try and keep this class updated with new features as they are shared. I hope you enjoy!

Good luck and let me know if you end up using it!

Authentication is unique for each application. But tying your authentication mechanisms into RestServer is easy. By simply adding a method named authorize to your Controller all requests will call that method first. If authorize() returns false, the server will issue a 401 Unauthorized response. If authorize() returns true, the request continues on to call the correct controller action. All actions will run the authorization first unless you add @noAuth in the action’s docs (I usually put it above the @url mappings).

RestServer is meant to be a simple mechanism to map your application into a REST API. The rest of the details are up to you.

Cross-origin resource sharing

For security reasons, browsers restrict cross-origin HTTP or REST requests initiated from within scripts. So, a web application using REST APIs from browsers, could only make API requests to its own domain. To override this restriction RestServer can be configured to allow cros-orign requests, by including following code in REST index.php file.

Throwing and Handling Errors

Источник

Простой RESTful-сервис на нативном PHP

Почти любой php-фреймворк умеет делать это из коробки. Например, Laravel, где роутинг реализован понятно и просто. Но что если нам не нужно прямо сейчас заниматься изучением новой большой темы, а хочется просто быстро завести проект с поддержкой REST API? Об этом и пойдет речь в статье.

Что должен уметь наш RESTful-сервис?

1. Поддерживать все 5 основных типов запросов: GET, POST, PUT, PATCH, DELETE.
2. Разруливать разнообразные маршруты вида
POST /goods
PUT /goods/
GET /users//info
и прочие сколь угодно длинные цепочки.

Какой функционал мы будем поддерживать?

Для товаров возможности следующие:

По пользователям для разнообразия рассмотрим несколько вариантов с GET

Как это заработает на нативном PHP?

.htaccess

index.php

Рассмотрим index.php строка за строкой. Для начала получим метод запроса.

Затем данные из тела запроса

Теперь у нас есть все данные, нужно сделать с ними что-нибудь полезное. А сделают это всего лишь 4 строки кода

GET /goods/

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

Давайте попробуем на примере: откройте консоль браузера и выполните код

php rest api server. Смотреть фото php rest api server. Смотреть картинку php rest api server. Картинка про php rest api server. Фото php rest api server

php rest api server. Смотреть фото php rest api server. Смотреть картинку php rest api server. Картинка про php rest api server. Фото php rest api server

В конце функции мы написали такой код.

По http-кодам ответов сервера
Мы не будем заморачиваться с выводом разных кодов, хотя по REST-у это и стоит делать. Клиентских ошибок много. Даже в нашем простом случае уместна 405 в случае неправильно переданного метода. Намеренно не хочу усложнять.
В случае успеха сервер у нас всегда вернет 200 ОК. По хорошему, при создании ресурса стоит отдавать 201 Created. Но опять-таки в плане упрощения эти тонкости мы отбросим, а в реальном проекте Вы их легко реализуете сами.

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

POST /goods

Добавление нового товара

PUT /goods/

PATCH /goods/

Частичное обновление товара

DELETE /goods/

GET /users/

GET /users//info

Общая информация о пользователе

GET /users//orders

Получение списка заказов пользователя

Итоги и исходники

Источник

RESTful API для сервера – делаем правильно (Часть 1)

В 2007-м Стив Джобс представил iPhone, который произвел революцию в высокотехнологичной индустрии и изменил наш подход к работе и ведению бизнеса. Сейчас 2012-й и все больше и больше сайтов предлагают нативные iOS и Android клиенты для своих сервисов. Между тем не все стартапы обладают финансами для разработки приложений в дополнение к основному продукту. Для увеличения популярности своего продукта эти компании предлагают открытые API, которыми могут воспользоваться сторонние разработчики. Пожалуй Twitter был первым в этой сфере и теперь число компаний, последовавших этой стратегии, растет стремительно. Это действительно отличный способ создать привлекательную экосистему вокруг своего продукта.

Жизнь стартапа полна перемен, поворотных моментов, в которых от принятых решений зависит дальнейшая судьба проекта. Если ваша кодовая база не сможет обеспечить воплощение самых разных ваших решений – вы проиграли. Серверный код, который достаточно гибок для того, чтобы в короткие сроки подстроиться под нужды бизнеса, решает быть проекту или нет. Успешные стартапы не те, которые просто предложили отличную идею, но те, которые смогли ее качественно воплотить. Успех стартапа зависит от успешности его продукта, будь то приложение под iOS, сервис или API. Последние три года я работал над разными приложениями под iOS (в основном для стартапов) использовавшими web сервисы и в этом блоге я попытался собрать накопленные знания воедино и показать вам лучшие методики, которым вам нужно следовать при разработке RESTful API. Хороший RESTful API тот, который можно менять легко и просто.

Целевая аудитория

Структура и организация статьи

Статья довольно подробна и состоит из двух частей. Первая описывает основы REST тогда как вторая описывает документирование и поддержку разных версий вашего API. Первая часть для новичков, вторая для профи. Я не сомневаюсь, что вы профи, а потому вот вам ссылка чтобы перескочить сразу к главе «Документирование API». Возможно, вам стоит начать оттуда, если вам кажется, что этот пост из разряда «Многа букаф, ниасилил…».

Принципы RESTful

Сервер может считаться RESTful если он соответствует принципам REST. Когда вы разрабатываете API, который будет в основном использоваться мобильными устройствами, понимание и следование трем наиважнейшим принципам может быть весьма полезным. Причем не только при разработке API, но и при его поддержке и развитии в дальнейшем. Итак, приступим.

Независимость от состояния (Statelessness)

Первый принцип – независимость от состояния. Проще говоря, RESTful сервер не должен отслеживать, хранить и тем более использовать в работе текущую контекстную информацию о клиенте. С другой стороны клиент должен взять эту задачу на себя. Другими словами не заставляйте сервер помнить состояние мобильного устройства, использующего API.

Давайте представим, что у вас есть стартап под названием «Новый Фейсбук». Хороший пример, где разработчик мог совершить ошибку это предоставление вызова API, который позволяет мобильному устройству установить последний прочитанный элемент в потоке (назовем его лентой Фейсбука). Вызов API, обычно возвращающий ленту (назовем его /feed), теперь будет возвращать элементы, которые новее установленного. Звучит умно, не правда ли? Вы «оптимизировали» обмен данными между клиентом и сервером? А вот и нет.

Что может пойти не так в приведенном случае, так это то, что если ваш пользователь использует сервис с двух или трех устройств, то, в случае когда одно из них устанавливает последний прочитанный элемент, то остальные не смогут загрузить элементы ленты, прочитанные на других устройствах ранее.

Независимость от состояния означает, что данные, возвращаемые определенным вызовом API, не должны зависеть от вызовов, сделанных ранее.

Правильный способ оптимизации данного вызова – передача времени создания последней прочитанной записи ленты в качестве параметра вызова API, возвращающего ленту (/feed?lastFeed=20120228). Есть и другой, более «правильный» метод – использование заголовка HTTP If-Modified-Since. Но мы пока не будем углубляться в эту сторону. Мы обсудим это во второй части.

Клиент же со своей стороны, может (должен) помнить параметры, сгенерированные на сервере при обращении к нему и использовать их для последующих вызовов API, если потребуется.

Кэшируемая и многоуровневая архитектура

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

Клиент – серверное разделение и единый интерфейс

RESTful сервер должен прятать от клиента как можно больше деталей своей реализации. Клиенту не следует знать о том, какая СУБД используется на сервере или сколько серверов в данный момент обрабатывают запросы и прочие подобные вещи. Организация правильного разделения функций важна для масштабирования если ваш проект начнет быстро набирать популярность.

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

REST запросы и четыре HTTP метода

GET
POST
PUT
DELETE

Принцип “кэшируемости” и GET запросы

Главное, что следует помнить — вызов, совершенный через GET не должен менять состояние сервера. Это в свою очередь значит, что ваши запросы могут кэшироваться любым промежуточным прокси (снижение нагрузки). Таким образом Вы, как разработчик сервера, не должны публиковать GET методы, которые меняют данные в вашей базе данных. Это нарушает философию RESTful, особенно второй пункт, описанный выше. Ваши GET вызовы не должны даже оставлять записей в access.log или обновлять данные типа “Last logged in”. Если вы меняете данные в базе, это обязательно должны быть методы POST/PUT.

То самое обсуждение POST vs PUT

Спецификация HTTP 1.1 гласит, что PUT идемпотентен. Это значит, что клиент может выполнить множество PUT запросов по одному URI и это не приведет к созданию записей дубликатов. Операции присвоения — хороший пример идемпотентной операции

Даже если эту операцию выполнить дважды или трижды, никакого вреда не будет (кроме лишних тактов процессора). POST же с другой стороны не идемпотентен. Это что-то вроде инкремента. Вам следует использовать POST или PUT с учетом того является ли выполняемое действие идемпотентным или нет. Говоря языком программистов, если клиент знает URL объекта, который нужно создать, используйте PUT. Если клиент знает URL метода/класса создающего нужный объект, используйте POST.

Используйте PUT если клиент знает URI, который сам бы мог быть результатом запроса. Даже если клиент вызовет это PUT метод много раз, какого либо вреда или дублирующих записей создано не будет.

Используйте POST если сервер сам создает уникальный идентификатор и возвращает его клиенту. Дублирующие записи будут создаваться если этот запрос будет повторяться позже с такими же параметрами.
Более подробная информация в данном обсуждении.

Метод DELETE

DELETE абсолютно однозначен. Он идемпотентен как и PUT, и должен использоваться для удаления записи если таковая существует.

REST ответы

Ответы от Вашего RESTful сервера могут использовать в качестве формата XML или JSON. Лично я предпочитаю JSON, поскольку он более лаконичен и по сети передается меньший объем данных нежели при передаче такого же ответа в формате XML. Разница может быть порядка нескольки сотен килобайт, но, с учетом скоростей 3G и нестабильности обмена с мобильными устройствами, эти несколько сотен килобайт могут иметь значение.

Аутентификация

Аутентификация должна производиться через https и клиент должен посылать пароль в зашифрованном виде. Процесс получения sha1 хэша NSString в Objective-C достаточно понятен и прост и приведенный код наглядно это показывает.

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

RFC 2617 описывает два способа аутентификации на HTTP сервере. Первый — это Basic Access, второй Digest. Для мобильных клиентов подходит любой из этих двух методов и большинство серверных (и клиентских тоже) языков обладают встроенными механизмами для реализации таких схем аутентификации.

Если вы планируете сделать свой API публичным, вам следует также посмотреть в сторону oAuth или лучше oAuth 2.0. oAuth позволит Вашим пользователям публиковать контент, созданный в Вашем приложении, на других ресурсах без обмена ключами (логинами/паролями). oAuth также позволяет пользователям контролировать что именно находится в доступе и какие разрешения даны сторонним ресурсам.

Facebook Graph API это наиболее развитая и распространенная реализация oAuth на данный момент. Используя oAuth, пользователи Facebook могут давать доступ к своим фотографиям сторонним приложениям без публикации другой приватной и идентификационной информации (логин/пароль). Пользователь также может ограничить доступ нежелательным приложениям без необходимости менять свой пароль.

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

Документирование API

Худшая документация, которую может написать разработчик сервера — это длинный, однообразный список вызовов API с описанием параметров и возвращаемых данных. Главная проблема такого подхода заключается в том, что внесение изменений в сервер и формат возвращаемых данных по мере развития проекта становится кошмаром. Я внесу кое какие предложения на этот счет, чтобы разработчик клиентского ПО понимал Вас лучше. Со временем это также поможет Вам в развитии в качестве разработчика серверного ПО.

Документация

Первым шагом я бы порекомендовал подумать об основных, высокоуровневых структурах данных (моделях), которыми оперирует ваше приложение. Затем подумайте над действиями, которые можно произвести над этими компонентами. Документация по foursquare API хороший пример, который стоит изучить перед тем как начать писать свою. У них есть набор высокоуровневых объектов, таких как места, пользователи и тому подобное. Также у них есть набор действий, которые можно произвести над этими объектами. Поскольку вы знаете высокоуровневые объекты и действия над ними в вашем продукте, создание структуры вызовов API становится проще и понятней. Например, для добавления нового места логично будет вызвать метод наподобие /venues/add

Документируйте все высокоуровневые объекты. Затем документируйте запросы и ответы на них, используя эти высокоуровневые объекты вместо простых типов данных. Вместо того, чтобы писать “Этот вызов возвращает три строковых поля, первое содержит id, второе имя, а третье описание” пишите “Этот вызов возвращает структуру (модель), описывающую место”.

Документирование параметров запроса

Давайте представим, что у Вас есть API, позволяющий пользователю входить, используя Facebok token. Вызовем этот метод как /login.

Где profileinfo высокоуровневый объект. Поскольку вы уже задокументировали внутреннюю структуру этого объекта то такого простого упоминания достаточно. Если Ваш сервер использует такие же Accept, Accept-Encoding и параметр Encoding type всегда вы можете задокументировать их отдельно, вместо повторения их во всех разделах.

Документирование параметров ответа

Ответы на вызовы API должны также быть задокументированы, основываясь на высокоуровневой модели объектов. Цитируя тот же пример foursquare, вызов метода /venue/#venueid# вернет структуру данных (модель), описывающую место проведения мероприятия.

Обмен идеями, документирование или информирование других разработчиков о том, что вы вернете в ответ на запрос станет проще если Вы задокументируете ваш API используя структуру объектов (моделей). Наиболее важный итог этой главы — это необходимость воспринимать документацию как контракт, который заключаете Вы, как разработчик серверной части и разработчики клиентских приложений (iOS/Android/Windows Phone/Чтобытонибыло).

Причины создания новых и прекращения поддержки старых версий вашего API

До появления мобильных приложений, в эпоху Web 2.0 создание разных версий API не было проблемой. И клиент (JavaScript/AJAX front-end) и сервер разворачивались одновременно. Потребители (ваши клиенты) всегда использовали самую последнюю версию клиентского ПО для доступа к системе. Поскольку вы — единственная компания, разрабатывающая как клиентскую так и серверную часть, вы полностью контролируете то как используется ваш API и изменения в нем всегда сразу же применялись в клиентской части. К сожалению это невозможно с клиентскими приложениями, написанными под разные платформы. Вы можете развернуть API версии 2, считая что все будет отлично, однако это приведет к неработоспособности приложений под iOS, использующих старую версию. Поскольку еще могут быть пользователи, использующие такие приложения несмотря на то, что вы выложили обновленную версию в App Store. Некоторые компании прибегают к использованию Push уведомлений для напоминаний о необходимости обновления. Единственное к чему это приведет — потеря такого клиента. Я видел множество айфонов, у которых было более 100 приложений, ожидающих обновления. Шансы, что ваше станет одним из них, весьма велики. Вам всегда надо быть готовым к разделению вашего API на версии и к прекращению поддержки некоторых из них как только это потребуется. Однако поддерживайте каждую версию своего API не менее трех месяцев.

Разделение на версии

Развертывание вашего серверного кода в разные папки и использование разных URL для вызовов не означает что вы удачно разделили ваш API на версии.
Так example.com/api/v1 будет использоваться версией 1.0 приложения, а ваша свежайшая и крутейшая версия 2.0 будет использовать example.com/api/v2

Когда вы делаете обновления, вы практически всегда вносите изменения во внутренние структуры данных и в модели. Это включает изменения в базе данных (добавление или удаление столбцов). Для лучшего понимания давайте представим, что ваш “новый Фейсбук” имеет вызов API, называемый /feed который возвращает объект “Лента”. На сегодня, в версии 1, ваш объект “Лента” включает URL аватарки пользователя (avatarURL), имя пользователя (personName), текст записи (feedEntryText) и время создания (timeStamp) записи. Позднее, в версии 2, вы представляете новую возможность, позволяющую рекламодателям размещать описания своих продуктов в ленте. Теперь объект “Лента” содержит, скажем так, новое поле “sourceName”, которое перекрывает собой имя пользователя при отображении ленты. Таким образом приложение должно отображать “sourceName” вместо “personName”. Поскольку приложению больше не нужно отображать “personName” если задана “sourceName”, вы решаете не отправлять “personName” если есть “sourceName”. Это все выглядит неплохо до тех пор, пока старая версия вашего приложения, версия 1 не обратится к обновленному серверу. Она будет отображать ваши рекламные записи из ленты без заголовка поскольку “personName” отсутствует. “Грамотный” способ решения такой проблемы — отправлять как “personName”, так и “sourceName”. Но, друзья, жизнь не всегда так проста. Как разработчик вы не сможете отслеживать все одиночные изменения которые когда либо были произведены с каждой моделью данных в вашем объекте. Это не очень эффективный способ внесения изменений поскольку через пол года вы практически забудете почему и как что-то было добавлено к вашему коду.

Возвращаясь к web 2.0, это не было проблемой вообще. JavaScript клиент немедленно модифицировался для поддержки изменений в API. Однако установленные iOS приложения от вас больше не зависят. Теперь их обновление — прерогатива пользователя.

У меня есть элегантное решение для хитрых ситуаций подобного толка.

Парадигма разделения на версии через URL

Первое решение — это разделение с использованием URL.
api.example.com/v1/feeds будет использоваться версией 1 iOS приложения тогда как
api.example.com/v2/feeds будет использоваться версией 2.
Несмотря на то, что звучит это все неплохо, вы не сможете продолжать создание копий вашего серверного кода для каждого изменения в формате возвращаемых данных. Я рекомендую использование такого подхода только в случае глобальных изменений в API.

Парадигма разделения на версии через модель

Выше я показал как документировать ваши структуры данных (модели). Рассматривайте эту документацию как контракт между разработчиками серверной и клиентской частей. Вам не следует вносить изменения в модели без изменения версии. Это значит, что в предыдущем случае должно быть две модели, Feed1 и Feed2.

В Feed2 есть поле sourceName и она возвращает sourceName вместо personName если sourceName установлен. Поведение Feed1 остается таким же, как это было оговорено в документации. Алгоритм работы контроллера будет примерно таким:
php rest api server. Смотреть фото php rest api server. Смотреть картинку php rest api server. Картинка про php rest api server. Фото php rest api server
Вам следует переместить логику создания экземпляра класса в отдельный класс согласно паттерну Factory method. Соответствующий код контроллера должен выглядеть примерно так:

Где решение о версии используемого API будет принимать контроллер в соответствии с полем UserAgent текста запроса.

Дополнение:
Вместо использования номера версии из строки UserAgent, правильней будет использовать номер версии в заголовке Accept. Таким образом вместо отправки

Таким образом у вас появляется возможность указывать версию API для каждого запроса к REST серверу. Спасибо читателям hacker news за этот совет.

Контроллер использует метод Feed factory для создания корректного объекта feed (лента) основываясь на информации из запроса клиента (все запросы имеют в своем составе поле UserAgent которое выглядит наподобие AppName/1.0) касающейся версии. Когда вы разрабатываете сервер таким образом, любое изменение будет простым. Внесение изменений не будет нарушать имеющиеся соглашения. Просто создавайте новые структуры данных (модели), вносите изменения в factory method для создания экземпляра новой модели для новой версии и все!

При использовании такого подхода ваши приложения версий 1 и 2 могут продолжать работать с одним сервером. Ваш контроллер может создавать объекты версии 1 для старых клиентских приложений и объекты версии 2 для новых.

Прекращение поддержки

С предложенной выше парадигмой разделения API на версии через модель прекращение поддержки вашего API становится намного проще. Это очень важно на последних стадиях когда вы публикуете ваш API. Когда вы делаете глобальное обновление API проведите ревизию всех factory method в ваших моделях в соответствии с изменениями вашей бизнес логики.

Если, в ходе релиза версии 3 вашего API, вы решаете прекратить поддержку версии 1 то для этого достаточно удалить соответствующие модели и удалить строки, создающие их экземпляры в ваших factory method-ах. Создание новых версий и прекращение поддержки старых обязательно будут сопровождать ваш проект показывая насколько он гибок для поддержки ключевых решений, диктуемых бизнесом. Бизнес, неспособный к резким переменам и поворотам, обречен. Обычно неспособность к ключевым переменам обусловлена техническим несовершенством проекта. Указанная техника способна решить такую проблему.

Кэширование

Еще один немаловажный момент, касающийся производительности, которому следует уделить внимание — это кэширование. Если вы считаете, что это задача клиентского приложения подумайте хорошенько. В части 2 этой статьи я расскажу как организовать кэширование, используя средства http 1.1.

Обработка ошибок и интернационализация вашего API

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

От переводчика:
Сам я не являюсь разработчиком под iOS и web-сервисов не разрабатывал, мой уровень в этой области можно описать как «Собираюсь стать начинающим». Но тема мне интересна и статья понравилась, причем настолько, что решил перевести.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *