Rest api что это

Что такое REST API

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

REST API предназначено, в основном, для запросов с внешних серверов к серверам Mail.Ru. Для запросов с веб-клиентов — клиентской части социального приложения или от сайта — существуют JS API и Flash-библиотека, которые более удобны и просты в использовании.

Как использовать API

Все вызовы методов API — это GET или POST HTTP-запросы к URL http://www.appsmail.ru/platform/api с некоторым набором параметров. Вы выбираете в документации нужный метод, например, users.getInforest, формируете запрос согласно документации метода, и осуществляете этот запрос. В ответ на запрос вы получаете его результат, который также описан в документации каждой функции. Кодировка результата — UTF-8.


Например, на PHP для осуществления такого запроса можно использовать cURL, на Perl — LWP::Simple, на Python — urllib, использовать cURL из командной строки и даже просто ваш браузер.

Обратите внимание на готовые библиотеки, возможно, для вашего языка программирования уже существует реализация REST API.

Данные запроса могут передаваться в виде query-строки (после знака ?) при использовании метода GET, либо в теле POST-запроса. Помните, что в случае GET-запроса, параметры должны быть закодированы с помощью URL encoding.

На данный момент, API не делает различий между GET- и POST-запросами. Тем не менее, помните, что существует ограничение на длину URL запроса — 2048 символов. Поэтому мы рекомендуем вам выполнять запросы на получение информации с помощью метода GET (они обычно легко умещаются в ограничение), а запросы на изменение данных — загрузку фотографии, новый пост в «Что нового» или гостевую книгу — с помощью метода POST. Так вы не будете ограничены длиной запроса, кроме того, такое использование больше соответствует спецификации протокола HTTP.

Параметры запроса

В каждом запросе должен присутствовать набор обязательных параметров. Также для каждой функции в ее документации определены дополнительные параметры, нужные только для этой функции. Текстовые значения параметров должны быть переданы в кодировке UTF-8. Одинаковые для всех функций параметры перечислены ниже.


Имя Тип Описание
method string название вызываемого метода, например, users.getInfo; обязательный параметр
app_id int идентификатор приложения; обязательный параметр
sig string подпись запроса; обязательный параметр
session_key string сессия текущего пользователя
uid uint64 идентификатор пользователя, для которого вызывается метод; данный аргумент должен быть указан, если не указан session_key
secure bool флаг, обозначающий, что запрос идет по защищенной схеме «сервер-сервер»; возможные значения: 1 или 0; по-умолчанию 0
format string формат выдачи ответа API; возможные значения: xml или json; по-умолчанию json

Порядок следования параметров в запросе значения не имеет, порядок параметров важен только при расчете подписи.


Идентификатор приложения app_id уникален для каждого приложения или сайта и его можно узнать в разделе Мои разработки для приложений и Мои сайты для сайтов.

Флаг secure и подпись sig расчитываются в зависимости от схемы запроса (см. ниже).

Авторизация запроса

Параметры session_key и uid отвечают за авторизацию, то есть от лица какого пользователя происходит запрос. В зависимости от этого одна и та же функция в одном и том же приложении может возвращать немного разные результаты, например, когда один пользователь имеет доступ к каким-то закрытым данным, а другой нет. session_key используется для выполнения запросов по схеме «клиент-сервер» (см. ниже), а uid — по схеме «сервер-сервер».

Сессия (session_key) получается при каждом новом сеансе работы пользователя с вашим приложением или сайтом. При последующих заходах того же пользователя это значение будет другим, поэтому сохранять его не надо. Значение session_key вы получаете в зависимости от того, как вы используете REST API. Если вы используете API в клиенте социального приложения, session_key приходит вам в параметрах запроса (см. как разрабатывать социальные приложения), если вы интегрируете API для сайтов, сессия получается в процессе логина (см. как интегрировать сайты). В любом случае, после получения session_key, вы можете передать это значение на сервер чтобы осуществлять вызовы функций API с вашего сервера от лица текущего пользователя.


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

Мы рекомендем вам всегда использовать session_key, когда это возможно, потому что в дальнейшем он может требоваться для некоторых возможностей API. Используйте uid только когда вы выполняете запросы пока пользователь не использует ваше приложение или сайт.

Подпись запроса

Чтобы удостовериться, что запрос отправлен действительно вами, а не злоумышленниками от лица вашего приложения, все запросы к REST API должны быть подписаны. Подпись может вычисляться по двум схемам: клиент-сервер и сервер-сервер. Результат расчета подписи вы должны передать в параметре sig, Платформа проверит подпись и выполнит запрос только если подпись правильная.

Клиент-сервер

Схема клиент-сервер предназначена для случаев, когда REST API используется из клиента социального приложения, клиентского кода сайта или отдельного мобильного или desktop-приложения.

Если вы хотите использовать схему клиент-сервер, то передайте в параметрах запроса secure=0 и расчитайте sig по следующему алгоритму:


   sig = md5(uid + params + private_key)  

Значение params — это конкатенация пар «имя=значение» отсортированных в алфавитом порядке по «имя», где «имя» — это название параметра, передаваемого в функцию API, «значение» — значение параметра. Разделитель в конкатенации не используется. Параметр sig при расчете подписи не учитывается, все остальные параметры запроса должны учитываться при расчете.

Значение uid — идентификатор текущего пользователя приложения. Значение private_key вы можете взять из настроек приложения.

Например,

  Пусть uid=1324730981306483817 и private_key=7815696ecbf1c96e6894b779456d330e    Запрос, который вы хотите выполнить:  http://www.appsmail.ru/platform/api?method=friends.get&app_id=423004&session_key=be6ef89965d58e56dec21acb9b62bdaa    Тогда:  params = app_id=423004method=friends.getsession_key=be6ef89965d58e56dec21acb9b62bdaa  sig = md5(1324730981306483817app_id=423004method=friends.getsession_key=be6ef89965d58e56dec21acb9b62bdaa7815696ecbf1c96e6894b779456d330e)   = 5073f15c6d5b6ab2fde23ac43332b002    Итоговый запрос:  http://www.appsmail.ru/platform/api?method=friends.get&app_id=423004&session_key=be6ef89965d58e56dec21acb9b62bdaa&sig=5073f15c6d5b6ab2fde23ac43332b002  

Вот пример функции на PHP, которая возвращает значение подписи запроса по схеме клиент-сервер:


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

Сервер-сервер

Схема сервер-сервер является более надежной. Используйте ее для критичных к безопасности запросов.

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

Схема сервер-сервер использует отдельный ключ secret_key, который мы настоятельно рекомендуем вам хранить только на ваших серверах и использовать только при запросах с них к серверам Платформы.

Когда вы хотите использовать схему сервер-сервер, вы должны передать в параметрах запроса параметр secure=1 и расчитать значение параметра sig следующим образом:

   sig = md5(params + secret_key)  

Например,

  Пусть uid=1324730981306483817 и secret_key=3dad9cbf9baaa0360c0f2ba372d25716    Запрос, который вы хотите выполнить:  http://www.appsmail.ru/platform/api?method=friends.get&app_id=423004&session_key=be6ef89965d58e56dec21acb9b62bdaa&secure=1    Тогда:  params = app_id=423004method=friends.getsecure=1session_key=be6ef89965d58e56dec21acb9b62bdaa  sig = md5(app_id=423004method=friends.getsecure=1session_key=be6ef89965d58e56dec21acb9b62bdaa3dad9cbf9baaa0360c0f2ba372d25716)   = 4a05af66f80da18b308fa7e536912bae    Итоговый запрос:  http://www.appsmail.ru/platform/api?method=friends.get&app_id=423004&session_key=be6ef89965d58e56dec21acb9b62bdaa&secure=1&sig=4a05af66f80da18b308fa7e536912bae  

Вот пример функции на PHP, которая возвращает значение подписи запроса по схеме сервер-сервер:

Безопасность схемы сервер-сервер основывается на том, что secret_key знаете только вы и Платформа. Поэтому никогда не раскрывайте его третьим лицам. Если у вас возникли сомнения в безопасности secret_key, перегенерите его в настройках приложения.

api.mail.ru

Коротко обо мне

Меня зовут Зел, я разработчик-фрилансер из Сингапура. В свободное от работы время я люблю разбираться в коде и попутно публиковать в своем блоге те интересности, которые я обнаружил или изучил.

Вступление

Скорее всего вам уже приходилось слышать о таком термине, как REST API, особенно если вы сталкивались с необходимостью получения данных из другого источника (такого как Twitter или Github). Но что же все-таки это такое? Что мы можем с этим делать и как мы можем это использовать?


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

Что же такое REST API?

Давайте представим, что вы пытаетесь найти фильмы о Бэтмене на YouTube. Вы открываете сайт, вбиваете в форму поиска слово «Бэтмен», жмакаете «Окей» и видите список фильмов о супергерое. Похожим образом работает и WEB API. Вы ищите что-то и получаете список результатов от запрашиваемого ресурса.

Дословно API расшифровывается как Application Programming Interface. Это набор правил, позволяющий программам «общаться» друг с другом. Разработчик создает API на сервере и позволяет клиентам обращаться к нему.

REST – это архитектурный подход, определяющий, как API должны выглядеть. Читается как «Representational State Transfer». Этому набору правил и следует разработчик при создании своего приложения. Одно из этих правил гласит, что при обращении к определенному адресу, вы должны получать определенный набор данных (ресурс).

Каждый адрес маршрутом, пакет данных — запросом, в то время как результатирующий ресурс – ответом.

Анатомия запроса

Важно понимать структуру запроса:

  1. Маршрут отправки
  2. Тип метода
  3. Заголовки
  4. Тело (или данные)

Маршрут – это адрес, по которому отправляется ваш запрос. Его структура примерно следующая:


Rest api что это

Root-endpoint  — это точка приема запроса на стороне сервера (API). К примеру, конечная точка GitHub – https://api.github.com.

Путь определяет запрашиваемый ресурс. Это что-то вроде автоответчика, который просит вас нажать 1 для одного сервиса, 2 для другого и так далее.

Для понимания того, какие именно пути вам доступны, вам следует просмотреть документацию. К примеру, предположим, вы хотите получить список репозиториев для конкретного пользователя на Git. Согласно документации, вы можете использовать следующий путь для этого:

Rest api что это

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

Rest api что это

Последняя часть маршрута – это параметры запроса. Технически запросы не являются частью REST-архитектуры, но на практике сейчас все строится на них. Так что давайте поговорим о них более детально. Параметры запроса позволяют использовать в запросе наборы пар «ключ-значение». Они всегда начинаются знаком вопроса. Каждая пара параметров после чего разделяется амперсантом (что-то вроде этого):


Rest api что это

Как только вы пытаетесь получить список репозиториев для пользователя, вы добавляете эти три опциональных параметра и после чего получаете следующий результат:

Rest api что это

Если же вы желаете получить список моих недавно запушеных репозиториев, вам следует ввести следующее:

Rest api что это

Итак, как же понять, что маршруты рабочие? Что ж, пришло время проверить их на практике!

Тестирование при помощи Curl

Вы моете отправить запрос при помощи любого языка программирования. JavaScript может использовать методы вроде Fetch API или JQuery`s Ajax Method. Руби использует другое. И так далее.

В этой статье я буду использовать такую утилитку, как Curl. Дело в том, что она указана в официальной документации для веб-сервисов. Если вы поймете, как использовать эту утилиту, вы поймете, как работать с API. После чего вы можете производить запросы любым удобным для вас языком.

Перед тем, как продолжить, вам следует убедится, что Curl установлен на вашей машине.

Rest api что это

Ели же он не установлен, самое время установить. В таком случае вы получите ошибку «command not found».

Для того, чтобы использовать утилиту, необходимо ввести следующее (по примеру):

Rest api что это

И как только вы подтверждаете ввод, вы получаете ответ (наподобие этого):

Rest api что это

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

Rest api что это

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

Rest api что это

Также попробуйте другие команды и произведите запросы! В результате вы получаете похожие ответы.

JSON

JSON – JavaScript Object Notation – общий формат для отправки и приема данных посредством REST API. Ответ, отправляемый Github, также содержится в формате JSON.

Содержание объекта этого формата примерно следующее:

Rest api что это

Возвращаемся к анатомии запроса

Вы изучили, что запрос состоит из четырех частей:

  1. Маршрут отправки
  2. Тип метода
  3. Заголовки
  4. Тело (или данные)

Теперь же давайте попробуем разобраться с остальным.

Тип метода

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

  1. GET
  2. POST
  3. PUT
  4. PATCH
  5. DELETE

GET – используется для получения со стороны севера определенного ресурса. Если вы производите этот запрос, сервер ищет информацию и отправляет ее вам назад. По сути, он производит операцию чтения на сервере. Дефолтный тип запросов.

POST – нужен для создания определенного ресурса на сервере. Сервер создает в базе данных новую сущность и оповещает вас, был ли процесс создания успешным. По сути, это операция создания.

PUT и PATCH – используются для обновления определенной информации на сервере. В таком случае сервер просто изменяет информацию существующих сущностей в базе данных и оповещает об успехе выполнения операции.

DELETE – как и следует из названия, удаляет указанную сущность из базы или сигнализирует об ошибке, если такой сущности в базе не было.

Сам же API позволяет указать, какой метод должен быть использован в определенных контекстных ситуациях.

Rest api что это

GET запрос в этом случае необходим, чтобы получить список всех репозиториев указанного пользователя. Также можно использовать curl:

Rest api что это

Попробуйте отправить этот запрос. В качестве ответа вы получите требование об аутентификации.

Rest api что это

Заголовки

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

Заголовки представляют из себя пары ключей-значений. Пример:

Rest api что это

Также пример с использованием curl:

Rest api что это

(Примечание: заголовок Content-Type в случае Github для работы не является обязательным. Это всего лишь пример использования заголовка в запросе, ничего более.)

Для просмотра отправленных заголовком можно использовать следующее:

Rest api что это

Rest api что это

Здесь звездочка относится к дополнительной информации, предоставленной посредством curl. > относится к заголовкам запроса, а <, соответственно, — к заголовкам ответа.

Чтобы отправить информацию с curl, используйте следующее:

Rest api что это

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

Rest api что это

Также, если необходимо, вы можете разбить ваш запрос на несколько линий для обеспечения большей читабельности:

Rest api что это

Если вы знаете, как развернуть сервер, вы можете создать собственный API и протестировать свои запросы. Если же нет, обязательно попробуйте. Существует множество информации, посвященной этому.

Если же желания разворачивать свой сервер нет, попробуйте бесплатную опцию Request bin.

Rest api что это

После чего вы получите адрес, который спокойно сможете тестировать.

Rest api что это

Убедитесь, что вы создаете свой собственный request bin, если вы хотите протестировать именно ваш запрос. Учитывайте, что дефолтное время существования request bin – 48 часов. Потому те примеры адресов, которые я здесь привожу, на момент прочтения статьи давно как устарели.

Теперь же попробуйте отправить некоторую информацию, после чего обновите свою страницу.

Если все пройдет успешно, вы увидите следующее:

Rest api что это

Rest api что это

По умолчанию curl отправляет данные так, как если бы они были отправлены посредством полей форм. Если вы хотите отправить данные через JSON, ваш Content-Type должен равняться applicationjson, впоследствии вам необходимо отформатировать данные в виде JSON-объекта.

Rest api что это

Rest api что это

По сути, это все, что вам необходимо знать о структуре запроса.

Теперь давайте вспомним об аутентификации. Что же это такое и для чего она нужна?

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

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

Так как POST, PUT, PATCH, DELETE запросы изменяют базу данных, разработчики должны всегда быть на страже неавторизированного доступа к ним. Впрочем иногда GET запросы также требуют аутентификации (к примеру, когда вы желаете посмотреть состояние вашего банковского счета).

В случае с вебом существует два способа представиться системе:

  • Через ник и пароль (базовая аутентификация)
  • Через секретный токен

Секретный токен позволяет представить вас системе через соц. Сети по типу Github, Google, Twitter и так далее.

Здесь же я рассмотрю только базовую аутентификацию.

Для произведения базовой аутентификации вы можете использовать следующее:

Rest api что это

Попробуйте залогиниться под свой профиль по запросу, указанному выше. Как только вы успешно войдете в свой профиль, вы увидите ответ «problems parsing JSON».

Почему? Все просто: системе-то вы представились, но – вот беда – ничего полезного ей не предоставили. Все типы запросов требуют определенной информации.

Теперь же давайте поговорим о статус-кодах и возможных ошибках.

Статус-коды и возможные ошибки

Некоторые из сообщений, приведенных выше, как раз-таки и относятся к кодам ошибок. Логично, что они появляются только, когда что-то идет не совсем так, как было запланировано. Что же касательно статуса кодов, они позволяют вам познать успех (или неудачу) при выполнении определенного запроса. Бывают статус-коды от 100 до 500+. В целом их можно разделить на следующие группы:

  • 200+: запрос успешен
  • 300+: запрос перенаправлен на другой маршрут
  • 400+: ошибка на стороне клиента
  • 500+: ошибка на стороне сервера

Вы можете отладить статус ответа при помощи –v или –verbose. К примеру, я попытался получить доступ к определенному ресурсу без авторизации. Следовательно, я поймал ошибку:

Rest api что это

В случае же, когда запрос не верен по причине ошибки в самой передаваемой информации, вы получаете статус-код 400:

Rest api что это

Версии API

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

Запросить текущую версию API можно двумя путями.

  • Через маршурт
  • Через заголовок

К примеру, Твиттер использует первый метод. На момент написания версия Твиттер API была 1.1.

Rest api что это

С другой стороны, GitHub использует другой способ:

Rest api что это

В заключение

В этой статье мы рассмотрели, что такое REST API и как его можно использовать совместно с curl. Кроме того, вы также выучили, как залогиниться при помощи запроса и что такое статус-код.

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

Автор перевода: Евгений Лукашук

Источник

itvdn.com

Что такое REST?

REST — (сокр. от англ. Representational State Transfer — «передача состояния представления») архитектурный стиль взаимодействия компонентов распределённого приложения в сети по модели клиент-сервер. Был разработан в диссертации Роя Филдинга в 200 году, как альтернатива SOAP, когда запрос клиента несет в себе исчерпывающую информацио о желаемом ответе сервера и сервер не обязан сохранять сессию взаимодействия с клиентом.

Особенности архитектурного стиля:

  • Каждая сущность должна иметь уникальный идентификатор – URI.
  • Сущности должны быть связаны между собой.
  • Для чтения и изменения данных должны использоваться стандартные методы.
  • Должна быть поддержка нескольких типов ресурсов.
  • Взаимодействие должно осуществляться без состояния.

Стандартные методы таковы:

  • GET – получение данных без их изменения. Это наиболее популярный и легкий метод. Он только возвращает данные, а не изменяет их, поэтому на клиенте вам не нужно заботиться о том, что вы можете повредить данные.
  • POST – метод, подразумевающий вставку новых записей.
  • PUT – метод, подразумевающий изменение существующих записей.
  • PATCH – метод, подразумевающий изменение идентификатора существующих записей.
  • DELETE – метод, подразумевающий удаление записей.

Что такое REST-API?

REST API – это набор удаленных вызовов стандартных методов, возвращающих данные в определенном формате.

Где используется стиль REST в Android?

1) См. реализации различных библиотек REST-клиентов, например: Retrofit, Volley, RoboSpice… См. статью Volley vs Retrofit

2) Content Provider

Задачи, которые требуется решить при реализации REST-клиента

Перечислим, какие основные задачи придется решать при реализации REST-клиента на Android согласно паттернам Virgil Dobjanschi (Это так называемые паттерны A/B/C, которые описывают способы реализации REST-клиента под Android. Подробней о паттернах на русском можно глянуть здесь (лекция 2) или здесь):

  • Управление сервисом: запуск, остановка.
  • Передача результатов из сервиса в активити.
  • Кэшировать результатов в sqlite.
  • Фиксирование статуса данных sqlite перед и после выполнения REST-запроса.
  • Запись информации о проводимых REST-операциях в sqlite.
  • Парсинг полученных данных.
  • Конструирование REST-запроса на основе URI и набора параметров.
  • Выполнение сетевых запросов к REST-серверу.
  • Чистка базы данных от устаревших данных.
  • В случае неудачи REST-запроса, пытаться повторить запрос (например, экспоненциально увеличивая время между запросами).
  • Возможность отложенного запуска REST-запроса через SyncAdapter.

Некоторые важные моменты для реализации REST-клиента под Android, согласно паттернам A/B/C

  • Данные, полученные от REST-сервера, всегда сохраняются в sqlite. Напрямую в Activity они никогда не передаются. Вместо этого в Activity передается уведомление о том, что данные загружены в sqlite и их можно оттуда загрузить (вариант — Activity получает уведомление об обновлении данных в Content Provider через Content Observer).
  • При выполнении операций insert, delete, update данные в sqlite обновляются дважды: первый раз до отправки REST-запроса, второй раз — после получения результата. Первая операций выставляет информационные флаги, сигнализирующие о типе операции, проводимой над данными, и о статусе операции.
  • REST-методы следует всегда выполнять в отдельном потоке.
  • Следует использовать Apache HTTP client, а не Java URL connection.
  • Форматы данных в порядке предпочтения: какой-либо бинарный формат (например, AMF3), затем JSON, затем XML.
  • Желательно включать gzip. GZip на Android реализован “нативно”, библиотека быстрая. В некоторых случаях можно получить коэффициент сжатия 5:1 и даже 10:1, в зависимости от количества получаемых данных. Использование GZip ускоряет загрузку данных и экономит батарею.
  • Если используете Sqlite — используйте транзакции.
  • Если программе требуется скачать 10-20 картинок, не стоит запускать 10-20 параллельных закачек. Запускайте 1-3, а остальные ставьте в очередь.
  • Activity регистрирует binder callback (т.е. ResultReceiver), для получения ответа от сервиса. Этот callback нужно обязательно удалить при вызове onPause у Activity, иначе можно налететь на ANR.
  • Длительные операции всегда следует запускать из сервиса. Сервис обязательно следует останавливать после того, как требуемые операции выполнены.
  • Необходимо минимизировать сетевой трафик.
  • Следует разбивать данные на страницы (конечно, если REST Api предоставляют такую возможность).
  • Для некритичной по времени синхронизации данных между клиентом и сервером рекомендуется использовать SyncAdapter.

Алгоритм фомирования запроса к серверу

В общем случае, при выполнении запроса к REST-серверу, требуется выполнить ряд операций:

  • сформировать URL
  • задать HTTP-заголовки
  • выбрать тип HTTP-запроса
  • сформировать тело HTTP-запроса, т.е. преобразовать Java объект в JSON
  • выполнить запрос, воспользовавшись HTTP-клиентом
  • распарсить результаты запроса — преобразовать полученный JSON в Java объект

ziginsider.github.io

На днях кое-кто спросил меня, дескать, на кой черт вообще нужен этот REST. Зачем, например, заморачиваться с методом DELETE или там заголовком Accept? Не проще ли использовать метод GET и передавать все в параметрах, например, delete=true или format=json? Вбил в браузере, и работает! А вот этот ваш DELETE так просто через браузер не пошлешь. На что я ответил примерно так.

Вот, допустим, у вас есть некоторые ресурсы. Для определенности, пусть это будут книги и пользователи. Что, собственно, означает иметь REST API для работы с этими ресурсами? В первом приближении, следующее. Если мы хотим получить какую-то книгу, то говорим GET /books/123. Аналогично информация о пользователе получается запросом GET /users/456. Вообще-то, в начале URL неплохо бы иметь что-то вроде /api/v1.0/, но для краткости мы это опустим. По умолчанию данные отдаются, например, в JSON’е, но при желании мы можем передать Accept-заголовок с другим форматом. Для создания или обновления существующей книги следует использовать метод PUT, передав данные в теле запроса и указав формат этих данных в заголовке Content-type. Для удаления данных используется метод DELETE.

Внимательный читатель спросит, а для чего тогда нужен POST? Вообще, если делать все по науке, он должен использоваться для добавления элементов в сущность, словно она является неким контейнером, например, словарем. Однако на практике так обычно не делают, ведь при использовании API несколькими клиентами один клиент может изменить название книги, а второй — ее цену, в результате чего получится ерунда. Поэтому POST либо вообще не используют, либо используют в качестве замены методов PUT и DELETE. То есть, POST с каким-то телом запроса работает, как PUT, а без тела запроса — как DELETE. Это позволяет работать с клиентами, которые почему-то не умеют посылать PUT и DELETE.

Можно работать и сразу с целыми коллекциями. Для получения списка всех пользователей говорим GET /users, а для создания нового пользователя с автоматически сгенерированным id — POST /users. Как и ранее, в последнем случае данные передаются в теле запроса. Также можно перезаписать всю коллекцию, сказав PUT /users, и удалить сразу всех пользователей, сказав DELETE /users. Еще иногда требуется фильтрация по полям или пагинация, в этих случаях делают так:

… или как-то так:

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

В свое время я имел удовольствие работать над проектом, где API был устроен «простым и понятным» образом, на методах GET и POST, со всякими delete=1 и так далее. Смею вас заверить, что на самом деле вы этого не хотите. Потому что на практике работа с этим API превращается в какой-то кошмар.

Допустим, один программист занимается книгами, а второй пользователями. Первый решает, что для получения списка всех сущностей будет использоваться запрос GET /all_books, а второй решает перечислять только id и использовать URL GET /select_user_ids. Для удаления сущности первый программист решает использовать параметр del=true, а второй — delete=1. Для экспорта данных в CSV первый программист делает поддержку export=text/csv, а второй — format=CSV. Потом выясняется, что некоторые библиотеки не умеют посылать GET-запросы со слишком длинными query string и ходить за данными на чтение начинают методом POST. А затем кто-то случайно удаляет через браузер всех пользователей в боевом окружении… И так далее, и тому подобное, полный бардак в общем.

Вы спросите, что же мешает привести все это безобразие в одному стандарту, например, использовать только del=1 и export=csv? Так вот, REST — это и есть то самое приведение к одному стандарту, с учетом всяческих граблей типа случайного удаления данных через браузер и так далее. Притом у разных компаний этот стандарт одинаковый. Когда в команду разработчиков приходит новичок, вы просто говорите ему, что у вас всюду REST, а основные ресурсы — это пользователи и книги. Все, после этого одного предложения ваш новый коллега знает 90% API, безо всякого там чтения Wiki. Если вы хотите говорить с иностранцами, вы же просто используете общепринятый английский язык, а не изобретаете новый? Вот так же и здесь. Нельзя также не напомнить о пользе повторного использования протоколов и кода. А ведь для работы с REST, и HTTP вообще, написана куча библиотек и фреймворков.

Вы скажите «я, конечно, согласен, что REST такой весь из себя интуитивно понятный и общепринятый, но что, если я просто хочу загрузить через браузер список книг в формате CSV»? Тут важно понимать, что REST — это не о том, как сделать все через браузер. Предполагается, что должен быть клиент, который умеет работать с вашим API, вот через него и экспортируете. Но если по каким-то причинам это затруднительно, вы можете, например, использовать curl. Если у вас нелады с консолью, вы без труда найдете множество GUI-клиентов или, скажем, какой-нибудь плагин для Chrome, с аналогичным функционалом. Однако я все же советую попробовать curl. Пользоваться им совсем не так сложно, как вам может казаться. Всего-то нужно запомнить десяток параметров.

Так задаются дополнительные HTTP-заголовки:

Выбираем используемый метод:

Указываем тело запроса:

Если тело запроса большое, можно сохранить его в файл и сказать:

Выводим заголовки из ответа сервера в stdout:

Говорим передавать данные в gzip’е:

Сохраняем тело ответа в указанный файл вместо stdout:

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

Теперь рассмотрим пару примеров.

Экспорт книг в формате CSV:

Создание пользователя c выводом заголовков из ответа сервера в stdout:

Удаление пользователя с заданным id:

Несложно, правда ведь?

Несколько финальных замечаний, относящихся не совсем к REST. Во-первых, иногда от приложения требуется не только предоставлять доступ к некоторым ресурсам, но и выполнять какие-то команды. Таким командам имеет смысл выделять URL-адреса, начинающиеся с /commands/. Например, запуск почтовой рассылки по всем пользователям будет выглядеть как-то так:

Дополнение: Некоторые команды должны быть доступны только в тестовом окружении, для них можно выделить URL-адреса, начинающиеся с /debug/.

Во-вторых, иногда требуется реализовать бесконечные потоки событий, или отправку текущего состояния, а затем обновлений к нему. Таким концам разумно выделить URL, начинающиеся, например, со /streams/. Вот как примерно это должно работать:

Нужно обратить внимание на несколько моментов. Здесь используется формат x-json-stream, то есть, поток JSON-объектов, разделенных символом n. Если этот символ встречается в самом JSON-объекте, его, соответственно, следует кодировать. Некоторым клиентам может быть удобнее работать с честным JSON’ом, то есть, списком JSON-объектов. Предусмотреть поддержку сразу нескольких форматов довольно просто. Во втором случае список объектов должен начинаться с открывающейся квадратной скобки, а объекты должны разделяться запятыми. Для удобства работы со стримом нужно либо ставить после запятых символ n, либо делать это на стороне клиента с помощью sed:

Каждый объект имеет поле type и опциональное поле data. Объекты с типом heartbeat посылаются несмотря ни на что один раз в пять секунд. Если клиент не видит такого объекта в течение десяти секунд, он считает, что либо что-то сломалось на стороне сервера, либо что-то не так с сетью, и закрывает соединение. Объект с типом sync используется в стримах, посылающих некое состояние, а затем обновления к нему, для разделения первого от второго. Наконец, все остальные типы представляют собой полезную нагрузку. Поле data нужно по той причине, что вложенные данные также могут иметь поле type, что приводило бы к неразберихе.

В-третьих, когда вы пишите RESTful приложение, старайтесь с самого начала придерживаться некоторых соглашений. Например, с самого начала договоритесь, что имена полей в JSON-объектах должны всегда писаться в camelCase. Раз и навсегда запретите использовать в идентификаторах такие спецсимволы, как знак плюс и пробелы. Договоритесь, что в случае получения кода 301 клиент должен посылать точно такой же запрос на URL, указанный в заголовке Location. Примите соглашение о том, как будет передаваться автоматически сгенерированные id. Например, в Riak для этого используется заголовок Location. Подумайте о том, как вы будете сообщать о различных типах ошибок, в том числе временной недоступности БД, ошибках валидации полей и так далее. Пользователи почти наверняка предпочтут увидеть:

… вместо кода 500 без каких-либо дополнительных пояснений. Если для вашего приложения важна точность представления чисел, договоритесь передавать все числа в виде строк, чтобы json-декодер не терял точность из-за преобразования строк во float’ы.

Но помните, хотя все написанное выше — это идеал, к которому стоит стремиться, на практике всем наплевать на стандарты. А значит, вас ждет много подпорок, слепленных на скорую руку, нежелание коллег переходить на более правильные версии API (зачем, если все работает?), и многие другие увлекательные вещи.

Дополнение: Пишем REST-сервис на Python с использованием Flask

Метки: Протоколы, Разработка.

eax.me

В этой статье я хочу поделиться опытом освоения тестирования (в т. ч. автоматизации) на уровне API (Application Programming Interface – интерфейс программирования приложений, интерфейс прикладного программирования). Надеюсь, что предлагаемый материал будет представлять интерес для всех, кто ранее проводил тестирование через графический интерфейс и еще не имеет опыта работы с http-запросами.

Немного о REST API и SOAP API

Стоит отметить, что на сегодняшний день есть два основных подхода к построению программного интерфейса веб-приложений: REST (RESTful) API и SOAP API:

Rest api что этоЕсли уподобить HTTP-запрос бумажному носителю, то можно сказать, что REST API в большинстве случаев передает простые записки, а время от времени – письмо в конверте (возможно, написав при этом часть послания и на самом конверте). В свою очередь, SOAP API передает все инструкции в подробном письме стандартного вида, используя конверт (единичный HTTP-запрос) лишь как средство доставки. Для лучшего понимания разницы подходов я рекомендую читателю посмотреть следующую инфографику.

В статье речь будет идти о REST API, так как этот подход является более распространенным из-за своей относительной простоты и удобства для разработчиков. SOAP API преимущественно характерен для больших корпоративных (enterprise) систем.

Чем работа с API может быть полезна тестировщику?

Для начала постараемся понять, зачем вообще тестировщику осваивать что-либо на таком уровне. Казалось бы, программные интерфейсы – это территория разработчиков. Ниже мы рассмотрим выгоды использования тестирования API.

Выгода первая: точная локализация.
Умение работать с API позволяет лучше понимать и точнее описывать возникшие ошибки. Предположим, вы открываете некую страницу сайта и видите в пользовательском интерфейсе сообщение об ошибке. Чем конкретно она вызвана? Насколько она серьезна? Может ли она отразиться на других частях системы? Нам будет гораздо проще ответить на эти вопросы, если мы сможем понять, какую именно функцию не удалось выполнить системе. Сообщения в графическом интерфейсе не всегда позволяют оценить эту зависимость.

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

Более того – многочисленные действия в браузере часто являются причиной ложных «падений» автоматизированных тестов, которым на уровне GUI свойственна «хрупкость». Одно неуспешное нажатие кнопки может привести к необходимости повторения либо всего теста, либо какой-то его части. Сформировав запрос программно или воспроизведя его с помощью специальных инструментов (об этом чуть позже), мы можем существенно сократить время проверки.

Выгода третья: возможность воспроизводить тесты на больших наборах входных данных.
Для некоторых проектов важно проводить тесты с большим количеством разнообразных наборов входных данных, отделенных от кода самого теста и вынесенных в отдельный файл. В этом случае один и тот же сценарий может повторяться многократно для разных значений. Эту методологию (так называемую Data Driven Testing) сложно реализовать через графический интерфейс с приемлемой скоростью и стабильностью. Напротив, на уровне http-запросов это делается очень быстро и с гораздо более высокой надежностью.

Практические шаги к освоению работы с REST API сайта

Итак, вы решили освоить работу с программным интерфейсом вашего сайта. С чего же начать?

Rest api что этоШаг 1: откройте средства разработчика в браузере.
Откройте средства разработчика (developer tools) в браузере (например, в Mozilla Firefox и Google Chrome просто нажмите F12) и перейдите во вкладку, в которой отражается сетевая активность (Network, Net, Сеть и т. д.)

Совершайте обычные действия в браузере и наблюдайте за результатом. Первое, что бросается в глаза, – это огромное количество запросов даже при загрузке одной страницы: для получения каждого изображения, стилей, шрифтов, структуры страницы, скриптов. При использовании AJAX (от англ. Asynchronous Javascript and XML – асинхронный JavaScript и XML, подход к построению интерактивных пользовательских интерфейсов веб-приложений, заключающийся в «фоновом» обмене данными браузера с веб-сервером) количество запросов может увеличиваться, даже если вы не производите никаких активных действий.

Шаг 2: скройте запросы, не относящиеся к логике работы.
Что же делать с огромным количеством запросов? Как выбрать те, которые для нас полезны? Попробуйте применить текстовый фильтр. Многие запросы, относящиеся к логике взаимодействия клиента и сервера (то есть, к API), могут содержать в своих URL фрагмент, указывающий на это (например, «api/rest»). Если вы обнаружили такой фрагмент – введите его в поисковую строку DevTools. Средства разработчика в браузере также позволяют выделить запросы определенного типа: XHR, JS, CSS, Images и т. д.

Выберите XHR (XMLHttpRequest) – это интерфейс языка JavaScript, используемый для конструирования запросов, имеющих тело. Обычно именно этот интерфейс используется для обращения к API. Вы можете столкнуться с большим количеством однотипных запросов, порождаемых различными системами мониторинга (например, yandex.webvisor). Их можно скрыть, применив негативный фильтр (например, «-yandex» для Chrome), даже если вы не знаете точно, что именно эти запросы делают. Однотипные и часто повторяющиеся запросы, как правило, относятся к мониторингу сайта, а не к логике совершаемых пользователем действий.

По клику на картинку откроется полная версия.

Просмотрите внимательно оставшиеся после применения фильтра запросы и постарайтесь выявить те, которые относятся именно к логике действий. В случае необходимости обратитесь за разъяснениями к разработчикам. Если вам доступна документация, в которой описываются endpoint-ы сервисов вашего проекта (т. е. адреса, к которым обращаются запросы, относящиеся к API), – изучите ее. Ниже я буду рассматривать вариант, когда подробной документации или соответствующих доступов у вас нет.

Достаточно часто по адресу endpoint-а можно догадаться, за что именно отвечает запрос к данному сервису. Например, адрес, содержащий фрагмент «api/rest/createContract», скорее всего, используется для создания договора, «api/rest/buildInfo» – для вывода информации о версии, установленной в текущий момент, а «api/rest/news/search» – для поиска новостей. Если трудно «выловить» нужный запрос в общей массе (а запросов к API тоже может быть немало) – очистите историю запросов перед совершением интересующего вас действия. Довольно быстро вы научитесь видеть нужные запросы и сопоставлять их с действиями в пользовательском интерфейсе.

Шаг 3: проведите более детальный анализ структуры запросов.
Обратите внимание на то, что часть запросов передает информацию только в запрошенном URL-е. В первую очередь, это GET-запросы, которые предназначены для получения определенного содержимого или запуска процесса. Классический пример – запрос на текстовый поиск. Его URL может выглядеть как «https://anysite.ru/search?keywords=my_query&itemsperpage=20», где «../search» – адрес поискового сервиса, «keywords=…» – текст запроса, «itemsperpage» – параметр, отвечающий за количество результатов, выводимых на одной странице.

С другой стороны, встречаются запросы, передающие большинство параметров в теле самого запроса. При этом часть параметров может передаваться и в URL. Примером могут послужить POST-запросы:

URL: POST https://www.youtube.com/feed_ajax?action_pause_watch_history=1 HTTP/1.1
Request headers: дополнительная информация, в т. ч. cookies.
Message Body:
session_token=QUFFLUhqbER0TE5idlp2MngybFh1ZUUyblYtaGlmLVhmZ3xBQ3Jtc0tta1J5W
m9uZHpVTW9oWHIzOWdIblkzVk1wVTNFQS1aS0pfNG85OWw3Sk14U2
В этом случае суть необходимого действия передается в URL-е (action_pause_watch_history=1), а информация о пользователе – в теле запроса (session_token).

На структуру тела запросов и ответов не накладывается ограничений. Это может быть как просто набор пар поле/значение (т. н. Form Data, как в примере выше session_token/значение), так и документ в удобном для разработчика формате (JSON, XML или каком-то ином).

Проанализируйте приходящие ответы (вкладка Response) и их коды. Помимо всего прочего, коды ответов, как правило, несут полезную информацию и сообщают о логике происходящего. Большинство запросов имеют код ответа «200 OK», сообщающий о том, что операция выполнена успешно. В случае возникновения ошибки коды будут начинаться на 4 (ошибка на стороне клиента) или на 5 (ошибка на стороне сервера). Например, таковы всем известные ошибки 404 («клиент запросил несуществующий ресурс») и 500 («внутренняя ошибка сервера»). Обратите внимание, что браузеры предоставляют возможность просмотра подробностей запросов/ответов как в удобном формате («parsed» в Google Chrome, «pretty print» в Mozilla Firefoх), так и в «сыром» виде («source»). Конечно, для понимания проще «parsed»/«pretty print», но в том случае, когда вам необходимо скопировать часть запроса, лучше переключиться в режим «source».

По клику на картинку откроется полная версия.

По клику на картинку откроется полная версия.

Шаг 4: воспроизведите запросы.
Итак, вы видите нужные запросы и понимаете, какие именно параметры они передают и с какой целью. Теперь можно попробовать самостоятельно менять значения параметров для получения нужных действий. Каким образом можно воспроизвести запросы с измененными параметрами? Самый простой способ — создавать GET-запросы, просто вводя их в адресную строку браузера (по сути, адресная строка – это интерфейс командной строки для воспроизведения GET-запросов). Но вам не удастся сделать многое, ограничившись лишь GET-методом.

Для расширения ваших возможностей используйте Fiddler или подобные ему инструменты (например, такие). Эти программы перехватывают весь сетевой трафик, позволяя просматривать, редактировать и воспроизводить отдельные запросы. Уже на этом уровне можно что-то тестировать – например, валидацию данных на стороне сервера. Если веб-клиент в браузере не позволил вам ввести некоторые значения – в Fiddler-е вы сконструируете запрос сами. Такой способ может существенно ускорить проверку большого набора данных для ввода, особенно если изменение значений в браузере занимает длительное время.

В качестве приятного бонуса я приведу небольшую пошаговую инструкцию по воспроизведению запроса в Fiddler.

По клику на картинку откроется полная версия.

Дальше – автоматизация тестирования REST API!

Постигнув принципы работы API, вы можете использовать эти навыки в автоматизированных тестах. Остается выбрать инструменты, которые будут воспроизводить нужные вам запросы и отслеживать содержимое ответов. Если вы умеете писать автоматизированные тесты для графического интерфейса (например, с использованием Selenium), то идеальным вариантом, на мой взгляд, будет интеграция тестов API в существующий фреймворк. Тесты часто содержат подготовительные/вспомогательные действия, многие из которых удобнее выполнить с использованием API. Это будет быстрее и стабильнее.

С другой стороны, механизм авторизации бывает достаточно сложным, его не всегда легко пройти только с помощью запросов. Но и это не представляет проблемы в том случае, если API-тесты интегрированы с тестами GUI. Нужные cookie можно забрать в браузере, открытом с помощью Selenium (driver.manage().getCookieNamed(«sessionId»).getValue()).

Для доступа к API посредством языка программирования потребуется библиотека, работающая с http-запросами. Для Java могу порекомендовать rest-assured, в своем фреймворке я использую именно ее. Эта библиотека удобна и популярна – у вас не возникает проблем ни с пониманием кода, ни с нахождением документации, примеров и обсуждений. Rest-assured использует синтаксис в стиле BDD (Behavior Driven Development – подход к автоматизации тестирования, стремящийся описывать код тестов языком, близким к естественному) с характерными ключевыми словами given/when/then:

protected ExtractableResponse postRequest(String requestPayload, String endpoint, int expectedStatus){
  return
    given().
      auth().basic("login", "password").
      cookies("sessionId", session).
      contentType(ContentType.JSON).
      body(requestPayload).
      relaxedHTTPSValidation().
    when().
      post(endpoint).
    then().
      statusCode(expectedStatus).
      body(containsString("www")).
      extract();
}

Блок given описывает предусловия, такие как авторизация и параметры запроса. Обратите внимание: отдельно можно провести базовую http-авторизацию (auth().basic(«login», «password»)) и пользовательскую авторизацию, передав нужные куки (cookies(«sessionId», session)). Очень удобно использовать опцию relaxedHTTPSValidation(), чтобы избежать хлопот с подтверждением сертификатов. Блок when() описывает требуемое действие – запрос какого типа и на какой адрес следует отправить. Блок then() включает проверки, которые необходимо произвести (их может быть несколько одновременно).

Например, вы можете проверить, соответствует ли статус ответа ожидаемому (statusCode(expectedStatus)) и содержит ли тело ответа определенный фрагмент текста (body(containsString(«www»))). Команда extract() позволяет получить ответ и использовать его, например, для извлечения определенных значений.

Это можно сделать следующим образом:

ExtractableResponse response = postRequest(session, payload, endpoint, 200);
int numberOfResults = response.path("results.total");

Здесь команда path(«results.total») позволяет извлечь значение, используя JsonPath либо XPath (в зависимости от того, в каком формате предоставлен ответ). Обратите внимание, что вызываемый метод postRequest определен в моем фреймворке, а не в библиотеке rest-assured. Если вам важно просто получить тело ответа для дальнейших проверок, а блок then не изменяется, то удобнее всего будет для каждого типа запросов (get, post, delete и т. д.) создать свой вспомогательный метод и не прописывать given/when/then каждый раз. Для работы с языком Python используется популярная библиотека requests.

Стоит отметить, что и Java, и Python имеют средства работы с http в числе стандартных возможностей, но я неоднократно сталкивался с мнением, что они не слишком удобны. Если вы не планируете писать тесты с использованием языка программирования, то вам, скорее всего, подойдет инструмент Postman – он позволяет воспроизводить и сохранять запросы, а также выстраивать из них тесты.

Заключение

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

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

quality-lab.ru


You May Also Like

About the Author: admind

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

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

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.

Adblock
detector