Серверный api что это

Серверный api что это

REST API

REST API — это способ взаимодействия сайтов и веб-приложений с сервером. Его также называют RESTful.

Термин состоит из двух аббревиатур, которые расшифровываются следующим образом. API (Application Programming Interface) — это код, который позволяет двум приложениям обмениваться данными с сервера. На русском языке его принято называть программным интерфейсом приложения. REST (Representational State Transfer) — это способ создания API с помощью протокола HTTP. На русском его называют «передачей состояния представления».

Технологию REST API применяют везде, где пользователю сайта или веб-приложения нужно предоставить данные с сервера. Например, при нажатии иконки с видео на видеохостинге REST API проводит операции и запускает ролик с сервера в браузере. В настоящее время это самый распространенный способ организации API. Он вытеснил ранее популярные способы SOAP и WSDL.

У RESTful нет единого стандарта работы: его называют «архитектурным стилем» для операций по работе с серверов. Такой подход в 2000 году в своей диссертации ввел программист и исследователь Рой Филдинг, один из создателей протокола HTTP.

Принципы REST API

У RESTful есть 7 принципов написания кода интерфейсов.

Отделения клиента от сервера (Client-Server). Клиент — это пользовательский интерфейс сайта или приложения, например, поисковая строка видеохостинга. В REST API код запросов остается на стороне клиента, а код для доступа к данным — на стороне сервера. Это упрощает организацию API, позволяет легко переносить пользовательский интерфейс на другую платформу и дает возможность лучше масштабировать серверное хранение данных.

Отсутствие записи состояния клиента (Stateless). Сервер не должен хранить информацию о состоянии (проведенных операций) клиента. Каждый запрос от клиента должен содержать только ту информацию, которая нужна для получения данных от сервера.

Кэшируемость (Casheable). В данных запроса должно быть указано, нужно ли кэшировать данные (сохранять в специальном буфере для частых запросов). Если такое указание есть, клиент получит право обращаться к этому буферу при необходимости.

Единство интерфейса (Uniform Interface). Все данные должны запрашиваться через один URL-адрес стандартными протоколами, например, HTTP. Это упрощает архитектуру сайта или приложения и делает взаимодействие с сервером понятнее.

Многоуровневость системы (Layered System). В RESTful сервера могут располагаться на разных уровнях, при этом каждый сервер взаимодействует только с ближайшими уровнями и не связан запросами с другими.

Предоставление кода по запросу (Code on Demand). Серверы могут отправлять клиенту код (например, скрипт для запуска видео). Так общий код приложения или сайта становится сложнее только при необходимости.

Начало от нуля (Starting with the Null Style). Клиент знает только одну точку входа на сервер. Дальнейшие возможности по взаимодействию обеспечиваются сервером.

Стандарты

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

Это отличает REST API от метода простого протокола доступа к объектам SOAP (Simple Object Access Protocol), созданного Microsoft в 1998 году. В SOAP взаимодействие по каждому протоколу нужно прописывать отдельно только в формате XML. Также в SOAP нет кэшируемости запросов, более объемная документация и реализация словаря, отдельного от HTTP. Это делает стиль REST API более легким в реализации, чем стандарт SOAP.

Несмотря на отсутствие стандартов, при создании REST API есть общепринятые лучшие практики, например:

Архитектура

REST API основывается на протоколе передачи гипертекста HTTP (Hypertext Transfer Protocol). Это стандартный протокол в интернете, созданный для передачи гипертекста. Сейчас с помощью HTTP отправляют любые другие типы данных.

Каждый объект на сервере в HTTP имеет свой уникальный URL-адрес в строгом последовательном формате. Например, второй модуль обучающего видео про Python будет храниться на сервере по адресу http://school.ru/python/2.

В REST API есть 4 метода HTTP, которые используют для действий с объектами на серверах:

Такие запросы еще называют идентификаторами CRUD: create (создать), read (прочесть), update (обновить) delete (удалить). Это стандартный набор действий для работы с данными. Например, чтобы обновить видео про Python по адресу http://school.ru/python/2 REST API будет использовать метод PUT, а для его удаления — DELETE.

В каждом HTTP-запросе есть заголовок, за которым следует описание объекта на сервере — это и есть его состояние.

Серверный api что это

Как работает RESTful

Например, на сайте отеля есть система бронирования номеров трех типов: эконом, стандарт и люкс. В REST API каждому типу будет присвоен свой URL на странице бронирования:

Такие URL однозначно определяют ресурс на сервисе — данные о доступных номерах каждого класса. Чтобы взаимодействовать с этими ресурсам REST API применяет CRUD-команды протокола HTTP. Например, GET econom для передачи клиенту информации о номерах класса эконом. В RESTful такие запросы будут кэшироваться — клиенту не нужно обращаться к серверу снова при повторном запросе.

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

Где применяют

REST API рекомендуют использовать в следующих случаях:

REST API используют чаще альтернативных методов, например SOAP. Помимо сайтов и веб-приложений RESTful используют для облачных вычислений.

Пример

Например, REST API используется в социальной сети Twitter. Запросы отправляются в формате JSON. Разработчики сторонних приложений могут использовать данные Twitter с помощью REST-запросов. Например:

GET geo/id/:place_id
Возвращает информацию о местоположении пользователей.

GET geo/reverse_geocode
Возвращает до 20 возможных местоположений по заданным координатам.

GET geo/search
Возвращает местоположения, которые могут быть прикреплены к твитам.

Источник

REST API: что это такое простыми словами, примеры запросов, варианты использования сервиса, методы

Серверный api что это

В этой статье мы разберем оболочку REST API, расскажем, что это такое простыми словами, как работает система.

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

Серверный api что это

Что такое REST API

Это английская аббревиатура, которая расшифровывается и переводится как передача состояния представления. Web-службы, которые пользуются системой Representational State Transfer, применяют термин RESTful. Отличие этого архитектурного стиля от других состоит в том, что у него нет единого стандарта, однако при этом допустимо использовать XML, HTTP, JSON и URL.

Representational State Transfer разработали еще в 2000 году, но с того момента он очень развился и сейчас стал одним из самых популярных, отодвинув на задний план аналогичные.

Чтобы объяснить суть Restful API для чайников, можно представить калькулятор на любом компьютере. Когда мы нажимаем на кнопки, желая получить расчеты, также начинают действовать и скрытые функции, которые в итоге и помогают получить результат. А когда сервис получает ответ, он выводит его на экран в виде готовой цифры в графическом интерфейсе.

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

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

Как работает

В первую очередь стоит разобраться, как действует подход:

Серверный api что это

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

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

Что такое API

По сути, это интерфейс программирования, который обладает следующими признаками:

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

В его задачи входит представлять состояние передачи:

Серверный api что это

Протокол по типу концентрированного REST API, работающий по HTTP равно качественным веб-сервисам

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

Те варианты, которые применяются для транслирования, тоже можно учитывать как «веб-сервисы». Клиент, который пользуется этим, способен запросить все что угодно, а сервер ему отвечает и предоставляет результаты. При этом задействуется любой удобный язык программирования или подходящие платформы.

Это вообще лучшая часть всего созданного в компьютерном мире. Так как подобные веб-сервисы не зависят от языков, то могут совмещаться с самыми разными системами. Когда API документируется, то неважно, чем пользовались разработчики при его создании — Ruby это был, Java или Python или что-то принципиально другое. Все запросы высылаются через один и тот же HTTP, решения приходят таким же способом.

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

SOAP стоит отнести к предкам интерфейсов по типу REST API

Еще перед тем, как прикладное программирование нового поколения стало популярным и везде используемым, у него был аналог — SOAP. Он был максимально распространен. А чтобы понять разницу между этим интерфейсами, стоит разобраться в истоках.

SOAP — это протокол, который работает по заранее определенному стандарту. Ему для работы требуется XML, это определит формат, в котором будут отражаться входящие и исходящие запросы. Так как это стандартная вещь, подвид можно определить, если использовать файл WSDL — он помогает расшифровывать язык, на котором пишут веб-службы. Он определяет, есть ли атрибуты или какие-то расширенные элементы в передающихся сообщениях. Это машиночитаемая часть функционирования сети, поэтому пользуются им только сервера, которые действуют и общаются, чтобы облегчить связь.

Все сообщения внутри SOAP собираются в своеобразные «конвертики», в которых есть заголовок и основное тело. Все это «пакуется» при помощи заранее сформированной схемы по принципу XML.

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

Источник

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

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

Серверный api что это
Intro to RESTful Web Services

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

Вы изучите:

Что такое REST?

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

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

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

Серверный api что это

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

Серверный api что это

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

Серверный api что это

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

Серверный api что это

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

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

Серверный api что это

Протокол 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 не накладывает никаких ограничений на форматы представления ресурсов или на определение сервиса.

Источник

Введение в Rest API: что это простыми словами

REST API отвечает почти за все взаимодействия между серверными и клиентскими приложениями — разберемся, как работает эта технология.

Что такое REST API

Representational State Transfer (REST) в переводе — это передача состояния представления. Технология позволяет получать и модифицировать данные и состояния удаленных приложений, передавая HTTP-вызовы через интернет или любую другую сеть.

Если проще, то REST API — это когда серверное приложение дает доступ к своим данным клиентскому приложению по определенному URL. Далее разберем подробнее, начиная с базовых понятий.

Базовые понятия Rest API — HTTP-протокол и API

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

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

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

REST API позволяет использовать для общения между программами протокол HTTP (зашифрованная версия — HTTPS), с помощью которого мы получаем и отправляем большую часть информации в интернете.

HTTP довольно прост. Посмотрим на его работу на примере. Допустим, есть адрес http://website.com/something. Он состоит из двух частей: первая — это адрес сайта или сервера, то есть http://website.com. Вторая — адрес ресурса на удаленном сервере, в данном примере — /something.

Вбивая в адресную строку URL-адрес http://website.com/something, мы на самом деле идем на сервер website.com и запрашиваем ресурс под названием /something. «Пойди вот туда, принеси мне вот то» — и есть HTTP-запрос.

Серверный api что это

Пример HTTP-запроса к серверу

Теперь представим, что по адресу website.com работает программа, к которой хочет обратиться другая программа. Чтобы программа понимала, какие именно функции нужны, используют различные адреса.

В бухгалтерском сервисе работа со счетами может быть представлена в API ресурсом /invoices. А банковские реквизиты — ресурсом /requisites. Названия ресурсов придумывают по правилам формирования URL в интернете.

Методы HTTP: основа работы REST API

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

В API-системе четыре классических метода:

Таким образом, мы получаем четыре функции, которые одна программа может использовать при обращении к данным ресурса, в примере — это ресурс для работы со счетами /invoices.

Для чего используют REST API

Архитектура REST API — самое популярное решение для организации взаимодействия между различными программами. Так произошло, поскольку HTTP-протокол реализован во всех языках программирования и всех операционных системах, в отличие от проприетарных протоколов.

Чаще всего REST API применяют:

Источник

Грамотная клиент-серверная архитектура: как правильно проектировать и разрабатывать web API

Серверный api что это

Рассказывает Владимир, веб-разработчик Noveo

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

Приближение первое: Действующие лица

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

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

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

Сервером в данном случае мы считаем абстрактную машину в сети, способную получить HTTP-запрос, обработать его и вернуть корректный ответ. В контексте данной статьи совершенно не важны его физическая суть и внутренняя архитектура, будь то студенческий ноутбук или огромный кластер из промышленных серверов, разбросанных по всему миру. Нам в той же мере совершенно неважно, что у него под капотом, кто встречает запрос у дверей, Apache или Nginx, какой неведомый зверь, PHP, Python или Ruby выполняет его обработку и формирует ответ, какое хранилище данных используется: Postgresql, MySQL или MongoDB. Главное, чтобы сервер отвечал главному правилу — услышать, понять и простить ответить.

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

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

Философия REST

REST (Representational state transfer) изначально был задуман как простой и однозначный интерфейс для управления данными, предполагавший всего несколько базовых операций с непосредственным сетевым хранилищем (сервером): извлечение данных (GET), сохранение (POST), изменение (PUT/PATCH) и удаление (DELETE). Разумеется, этот перечень всегда сопровождался такими опциями, как обработка ошибок в запросе (корректно ли составлен запрос), разграничение доступа к данным (вдруг этого вам знать не следует) и валидация входящих данных (вдруг вы написали ерунду), в общем, всеми возможными проверками, которые сервер выполняет перед тем, как выполнить желание клиента.

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

Независимость сервера от клиента — серверы и клиенты могут быть мгновенно заменены другими независимо друг от друга, так как интерфейс между ними не меняется. Сервер не хранит состояний клиента.
Уникальность адресов ресурсов — каждая единица данных (любой степени вложенности) имеет свой собственный уникальный URL, который, по сути, целиком является однозначным идентификатором ресурса.

Пример: GET /api/v1/users/25/name

Независимость формата хранения данных от формата их передачи — сервер может поддерживать несколько различных форматов для передачи одних и тех же данных (JSON, XML и т.д.), но хранит данные в своем внутреннем формате, независимо от поддерживаемых.

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

Чего нам не хватает

Серверный api что это

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

Вызовы функций

Чтобы не менять данные и связи между ними вручную, мы просто вызываем у ресурса функцию и «скармливаем» ей в качестве аргумента необходимые данные. Эта операция не подходит под стандарты REST, для нее не существует особого глагола, что заставляет нас, разработчиков, выкручиваться кто во что горазд.

Самый простой пример – авторизация пользователя. Мы вызываем функцию login, передаем ей в качестве аргумента объект, содержащий учетные данные, и в ответ получаем ключ доступа. Что творится с данными на серверной стороне – нас не волнует.

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

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

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

Множественные операции

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

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

Статистические запросы, агрегаторы, форматирование данных

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

Серверный api что это

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

Разновидности данных

Объекты

Ключевым типом данных в общении между клиентом и сервером выступает объект. По сути, объект – это перечень свойств и соответствующих им значений. Мы можем отправить объект на сервер в запросе и получить в результат запроса в виде объекта. При этом объект не обязательно будет реальной сущностью, хранящейся в базе данных, по крайней мере, в том виде, в котором он отправлен или получен. Например, учетные данные для авторизации передаются в виде объекта, но не являются самостоятельной сущностью. Даже хранимые в БД объекты склонны обрастать дополнительными свойствами внутрисистемного характера, например, датами создания и редактирования, различными системными метками и флагами. Свойства объектов могут быть как собственными скалярными значениями, так и содержать связанные объекты и коллекции объектов, которые не являются частью объекта. Часть свойств объектов может быть редактируемой, часть системной, доступной только для чтения, а часть может носить статистический характер и вычисляться на лету (например, количество лайков). Некоторые свойства объекта могут быть скрыты, в зависимости от прав пользователя.

Коллекции объектов

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

Скалярные значения

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

Приближение второе: Правильный путь

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

О чем стоит подумать, стоя на берегу

Серверный api что это

Версионность

Автономность компонентов

Формат обмена данными

Локализация и многоязычность

Внутренняя маршрутизация

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

Пути к коллекциям

Элементы коллекции

Уникальные объекты

Свойства объектов и коллекций

Коллекции связанных объектов

Функции объектов и коллекций

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

Приближение третье: Запросы и ответы

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

Универсальный ответ

Мы уже проговаривали, что конкретный формат общения сервера с клиентом может быть любым на усмотрение разработчика. Для меня наиболее удобным и наглядным кажется формат JSON, хотя в реальном приложении может быть реализована поддержка нескольких форматов. Сейчас же сосредоточимся на структуре и необходимых атрибутах объекта ответа. Да, все данные, возвращаемые сервером, мы будем оборачивать в специальный контейнер — универсальный объект ответа, который будет содержать всю необходимую сервисную информацию для его дальнейшей обработки. Итак, что это за информация:

Success — маркер успешности выполнения запроса

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

Error — сведения об ошибке

В случае, если выполнение запроса завершилось неудачей — о причинах и разновидностях отрицательных ответов сервера поговорим чуть позже, — к ответу добавляется атрибут «error», содержащий в себе HTTP-код статуса и текст сообщения об ошибке. Прошу не путать с сообщениями об ошибках валидации данных для конкретных полей. Правильнее всего, на мой взгляд, возвращать код статуса и в заголовке ответа, но я встречал и другой подход — в заголовке всегда возвращать статус 200 (успех), а детали и возможные данные об ошибках передавать в теле ответа.

Data — данные, возвращаемые сервером

Большинство ответов сервера призваны возвращать данные. В зависимости от типа запроса и его успеха ожидаемый набор данных будет разным, тем не менее атрибут«data» будет присутствовать в подавляющем большинстве ответов.

Пример возвращаемых данных в случае успеха. В данном случае ответ содержит запрашиваемый объект user.

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

Pagination — сведения, необходимые для организации постраничной навигации

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

Минимальный набор значений для пагинации состоит из:

Некоторые разработчики web API также включают в пагинацию набор готовых ссылок на соседние страницы, а также первую, последнюю и текущую.

Работа над ошибками

Как уже упоминалось выше, не все запросы к web API завершаются успехом, но это тоже часть игры. Система информирования об ошибках является мощным инструментом, облегчающим работу клиента и направляющим клиентское приложение по правильному пути. Слово «ошибка» в этом контексте не совсем уместно. Здесь больше подойдёт слово исключение, так как на самом деле запрос успешно получен, проанализирован, и на него возвращается адекватный ответ, объясняющий, почему запрос не может быть выполнен.

Каковы же потенциальные причины получаемых исключений?

500 Internal server error — всё сломалось, но мы скоро починим

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

400 Bad request — а теперь у вас всё сломалось

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

401 Unauthorized — незнакомец, назови себя

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

403 Forbidden — вам сюда нельзя

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

404 Not found — по этому адресу никто не живёт

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

405 Method not allowed — нельзя такое делать

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

422 Unprocessable entity — исправьте и пришлите снова

Одно из самых полезных исключений. Возвращается каждый раз, когда в данных запроса существуют логические ошибки. Под данными запроса мы подразумеваем либо набор параметров и соответствующих им значений, переданных методом GET, либо поля объекта, передаваемого в теле запроса методами POST, PUT и DELETE. Если данные не прошли валидацию, сервер в секции «data» возвращает отчет о том, какие именно параметры невалидны и почему.

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

Запросы

Получение элементов коллекции

Одним из наиболее частотных запросов является запрос на получение элементов коллекции. Информационные ленты, списки товаров, различные информационные и статистические таблицы и многое другое клиентское приложение отображает посредством обращения к коллекционным ресурсам. Для осуществления этого запроса мы обращаемся к коллекции, используя метод GET и передавая в строке запроса дополнительные параметры. Как мы уже обозначили выше, в качестве ответа мы ожидаем получить массив однородных элементов коллекции и информацию, необходимую для пагинации — подгрузки продолжения списка или же конкретной его страницы. Содержимое выборки может быть особым способом ограничено и отсортировано с помощью передачи дополнительных параметров. О них и пойдёт речь далее.

Постраничная навигация

page — параметр указывает на то, какая страница должна быть отображена. Если этот параметр не передан, то отображается первая страница. Из первого же успешного ответа сервера будет ясно, сколько страниц имеет коллекция при текущих параметрах фильтрации. Если значение превышает максимальное число страниц, то разумнее всего вернуть ошибку 404 Not found.

perPage — указывает на желаемое число элементов на странице. Как правило, API имеет собственное значение по умолчанию, которое возвращает в качестве поля perPage в секции pagination, но в ряде случаев позволяет увеличивать это значение до разумных пределов, предоставив максимальное значение maxPerPage:

Сортировка результатов

Зачастую результаты выборки требуется упорядочить по возрастанию или убыванию значений определенных полей, которые поддерживают сравнительную (для числовых полей) или алфавитную (для строковых полей) сортировку. Например, нам нужно упорядочить список пользователей по имени или товары по цене. Помимо этого мы можем задать направление сортировки от A до Я или в обратном направлении, причём разное для разных полей.

sortBy — существует несколько подходов к передаче данных о сложной сортировке в GET параметрах. Здесь необходимо четко указать порядок сортировки и направление.

В некоторых API это предлагается сделать в виде строки:

В других вариантах предлагается использовать массив:

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

Простая фильтрация по значению

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

Усложнённые варианты фильтрации

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

Фильтрация по верхней и нижней границе с использованием операторов сравнения from (больше или равно), higher (больше), to (меньше или равно), lower (меньше). Применяется к полям, значения которых поддаются ранжированию.

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

Фильтрация по частичному совпадению строки. Применяется к полям, содержащим текстовые данные или данные, которые могут быть приравнены к текстовым, например, числовые артикулы товаров, номера телефонов и т. д.

Именованные фильтры

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

Именованные фильтры могут также иметь свои параметры.

Серверный api что это

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

За перевод материала выражаем благодарность международной IT-компании Noveo.

Источник

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 остается таким же, как это было оговорено в документации. Алгоритм работы контроллера будет примерно таким:
Серверный api что это
Вам следует переместить логику создания экземпляра класса в отдельный класс согласно паттерну 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-сервисов не разрабатывал, мой уровень в этой области можно описать как «Собираюсь стать начинающим». Но тема мне интересна и статья понравилась, причем настолько, что решил перевести.

Источник

REST, что же ты такое? Понятное введение в технологию для ИТ-аналитиков

Мы подготовили статью Андрея Буракова на основе его вебинара на нашем YouTube-канале:

Проектирование и работа с REST-сервисами стали повседневными задачами для многих аналитиков. Однако мы часто встречаемся на работе с различными или даже противоречащими друг другу трактовками таких понятий, как REST, RESTful-сервис, RESTAPI.

Сегодня мы разберём, какие принципы вложил в парадигму REST её автор и как они могут помочь нам при проектировании систем.

Выясним, почему существует терминологическая путаница вокруг REST и как нам научиться лучше понимать коллег.

Поговорим о том, как связаны HTTP и REST. А также почему REST противопоставляют SOAP.

Терминология

Формат представления данных

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

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

Но я мог бы написать это и на английском: blue, green, red, white, black.

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

Plain text — это обычный текст, который я использовал при написании письма;

XML — язык разметки информации;

JSON — текстовый формат обмена данными;

Binary — бинарный формат.

Давайте запомним из этой части статьи что XML и JSON — это форматы представления данных.

Протокол передачи данных

Я написал письмо и теперь хочу его отправить. Что мне нужно для этого сделать? Как правило, я кладу письмо в конверт. В нашем случае таким конвертом будет такое понятие, как протокол передачи данных.

Протокол передачи данных — это набор соглашений, которые определяют обмен данными между различными программами. Эти соглашения задают единообразный способ передачи сообщений и обработки ошибок.

Серверный api что этоАналогия протокола передачи данных с письмом в конверте

Если продолжать рассматривать аналогию с письмом, то стоит обратить, что:

1. конверт имеет структуру;

2. я наклеиваю на конверт марки, указываю определённую информацию: от кого письмо, куда я его отправляю, адрес и т.д.

Транспорт

Получил письмо в конверте, всё здорово! Но нужно его как-то отправить. Как мне его отправить? Я воспользуюсь услугами почты. Что для этого нужно сделать? Прийти на почту, отдать письмо. Затем его кто-то должен доставить, используя некоторый транспорт.

Транспорт — это подмножество сетевых протоколов, с помощью которых мы можем передавать данные по сети.

Такими протоколами могут быть, например: HTTP, AMQP, FTP.

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

Протокол HTTP

HyperText Transfer Protocol (HTTP) — это протокол передачи данных. Изначально для передачи данных в виде гипертекстовых документов в формате HTML, сегодня — для передачи произвольных данных.

Этот протокол имеет две особенности, которые должны учитывать все, кто работает с этим протоколом: ресурсы и HTTP-глаголы.

Ресурсы

Чтобы разобраться с понятием ресурса, давайте представим, что у нас имеется некоторая ссылка: http://webinar.ru/schedule/speech.

Это как раз и есть тот самый URL, который мы используем поверх HTTP. Рассмотрим, из чего состоит эта ссылка:

Серверный api что это

А вот как нам работать с этими объектами, нам говорят HTTP-глаголы (методы).

HTTP-глаголы

HTTP-глаголы — это элемент протокола HTTP, который используется в каждом запросе, чтобы указать, какое действие нужно выполнить над данным ресурсом.

GET/schedule/speech/id413 — получить информацию об объекте

Здесь мы видим некоторый объект (ресурс) с конкретным идентификатором с номером 413. Я могу использовать HTTP-глагол GET для, того чтобы получить информацию о выступлении 413.

Я могу воспользоваться каким-либо другим HTTP-глаголом, если мне необходимо выполнить какие-либо другие действия.

PUT/schedule/speech/id413 — создать или перезаписать объект

Или удалить объект:

Главное здесь то, что мы рассматриваем некоторые объекты (ресурсы) и совершаем над ними некоторые действия, которые определены в протоколе списком HTTP-методов: GET, PUT, POST, DELETE и т.д.

Что такое REST?

Какое же определение в понятие REST заложил его основатель Рой Филдинг?

Representational State Transfer — это архитектурный стиль взаимодействия компонентов распределённого приложения в сети. Архитектурный стиль – это набор согласованных ограничений и принципов проектирования, позволяющий добиться определённых свойств системы.

Но зачем нам REST? Зачем нам этот стиль? Что нам даст применение принципов REST?

Если мы обратимся опять же к первоисточнику — к работе Филдинга, то мы выясним, что назначение REST в том, чтобы придать проектируемой системе такие свойства как:

Гибкость к изменениям,

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

Принципы REST

Каким образом REST может помочь нам достичь этих свойств и реализовать эти нефункциональные требования?

Чтобы это понять, давайте рассмотри 6 принципов REST — ограничений, которые и помогают нам добиться этих нефункциональных требований.

6 принципов REST:

Далее мы рассмотрим эти шесть принципов поподробнее.

Принцип 1. Клиент-серверная архитектура

Сама концепция клиент-серверной архитектуры заключается в разделении некоторых зон ответственности: в разделении функций клиента и сервера. Что это означает?

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

Что мы этим добиваемся и как могло бы быть иначе? Давайте представим, что клиент и сервер у нас объединены. Тогда, если мы говорим о мобильном приложении, каждое мобильное приложение каждого клиента должно было бы быть абсолютно самодостаточной единицей. И тогда, поскольку у нас единого сервера нет для получения/отправки информации, у нас получилась бы какая-то сеть единообразных компонентов – например, мобильные приложения общались бы друг с другом – такая распределённая сеть равноценных узлов.

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

Серверный api что этоКлиент-серверная архитектура

Также сервер может иметь базу данных (см. рисунок ниже). В данном случае надо понимать, что пара «сервер и БД» тоже будет парой «клиент-сервер». Только в данном случае сервером будет БД, а сам сервер — клиентом.

Серверный api что этоТрёхзвенная архитектура

Что дает клиент-серверная архитектура и зачем она нужна?

Во-первых, клиент-серверная архитектура дает нам определённую масштабируемость: есть сервер, есть единая точка обработки запросов. При необходимости выдерживать большую нагрузку мы можем поставить несколько серверов. Также к нему можно подключать достаточно большое количество клиентов (сколько сможет выдержать). Таким образом, клиент-серверная архитектура позволяет добиться масштабируемости.

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

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

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

Принцип 2. Stateless

Принцип заключается в том, что сервер не должен хранить у себя информацию о сессии с клиентом. Он должен в каждом запросе получать всю информацию для обработки.

Серверный api что этоПример реализации принципа Stateless. Запрос погоды на 20.06 в Москве

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

Что мы делаем в случае, если мы работаем с Stateless? Мы отправляем запрос «Какая погода?», отправляем место, где хотим погоду узнать, и дату. Соответственно, прогноз погоды отвечает нам — «Будет жарко».

Если я захочу узнать, какая будет погода через день, то опять укажу место, где хочу узнать погоду, укажу другую дату. Сервер получит этот запрос, обработает и сообщит мне, что там уже будет очень жарко.

Серверный api что этоПример реализации принципа Stateless. Запрос погоды на 21.06 в Москве

Рассмотрим ситуацию: что было бы, если бы у нас не было Stateless? В таком случае у нас бы был Stateful. В этом случае сервер хранит информацию о предыдущих обращениях клиента, хранит информацию о сессии, какую-то часть контекста взаимодействия с клиентом. А затем может использовать эту информацию при обработке следующих запросов.

Приведём пример на рисунке:

Серверный api что этоПример реализации принципа Stateful

Я всё так же хочу узнать, какая погода будет завтра: отправляю запрос, сервер его обрабатывает, формирует ответ и, помимо того, что он возвращает ответ клиентам, он еще сохраняет какую-то информацию (часть или всю) о том, какой запрос он получил. В случае, если я захочу узнать, какая погода будет через день, я могу сделать такой вызов: «А завтра?». Не сообщая ничего о месте и о дате.

В этом случае у сервера хранится некоторый контекст. Он понимает, что я у него спрашиваю про 21-е число и могу дать ответ на основе информации, хранимой у него в БД или в кэше. Один из примеров, где можно встретить подход Stateful в жизни — это работа с FTP-сервером.

Вернёмся к Statless-подходу. Почему в REST-архитектуре мы должны использовать именно Statless-подход?

Какие он даёт плюсы?

Уменьшение времени обработки запроса,

Возможность использовать кэширование.

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

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

Также подход Stateless позволяет использовать кэширование.

Какие проблемы может создать Stateless-подход?

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

Увеличение нагрузки на сеть (каждый раз мы передаём всю информацию, весь контекст. Таким образом, больше информации гоняем по сети).

Принцип 3. Кэширование

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

Что такое кэширование?

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

Например, клиент обратился к серверу с запросом «Хочу узнать погоду». Что делает сервер?

Если мы его только запустили и используем кэширование или если мы не используем кэширование вообще — сервер обратится к метеостанции, а она вернёт ему ответ. Перед тем, как сервер ответит клиенту, он должен сохранить эту информацию в кэше. И только потом вернуть ответ. Для чего?

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

Серверный api что этоПример реализации архитектуры с использованием кэширования

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

Какие у кэширования плюсы?

Уменьшение количества сетевых взаимодействий.

Уменьшение нагрузки на системы (не грузим их дополнительными запросами).

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

При этом важно понимать, что кэширование — это совсем не простая штука. Она бывает достаточно сложна и нетривиальна в реализации.
Также мы должны учитывать, что если отдаём какие-то данные, которые сохранили раньше, то важно помнить, что эти данные могли уже устареть.

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

Принцип 4. Единообразие интерфейса. HATEOAS

Hypermedia as the Engine of Application State (HATEOAS) — одно из ограничений REST, согласно которому сервер возвращает не только ресурс, но и его связи с другими ресурсами и действия, которые можно с ним совершить.

Рассмотрим пример. Возьмём HTTP-запрос, в котором я хочу получить определенный ресурс:

Серверный api что этоПример запроса ресурса

Здесь мы используем HTTP-глагол GET, то есть хотим получить ресурс. Обращаемся к некоторому счёту с номером 12345.

Если бы мы не использовали подход HATEOAS, то получили бы примерно такой XML-ответ:

Серверный api что этоПример ответа без использования принципа HATEOAS

Здесь указан номер счёта, баланс и валюта.

Что же предлагает HATEOAS? Если бы мы с учётом этого ограничения выполняли бы этот запрос, то в ответе получим не только информацию об этом объекте, но и все те действия, которые мы можем с ним совершить. И, если бы у него были бы какие-то важные связанные объекты, мы получили бы ещё и ссылки на них.

Серверный api что этоПример ответа с использованием принципа HATEOAS

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

Главный плюс этого подхода — клиент становится очень гибким в плане изменений на сервере с точки зрения изменения допустимых действий, изменения модели данных и т.д.

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

Принцип 5. Layered system (слоистая архитектура)

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

В реальной жизни между ними могут быть, к примеру, proxy-сервера, роутеры, балансировщики — все, что угодно. И то, по какому пути запрос проходит от клиента до сервера, мы часто не можем знать.

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

Серверный api что этоМодель слоистой архитектуры

Знания балансировщика в этой схеме об участниках конкретно этой цепочки вызовов должны заканчиваться proxy-сервером слева и сервером справа. О клиенте он уже ничего не знает.

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

Увеличение нагрузки на сеть (больше участников и больше вызовов, чем если бы мы шли один раз от клиента до сервера напрямую).

Увеличение времени получения ответа (из-за появления дополнительных участников).

Принцип 6. Code on done (код по требованию)

Идея передачи некоторого исполняемого кода (по сути какой-то программы) от сервера клиенту.

Серверный api что этоМодель архитектуры, реализующей принцип «Код по запросу»

Представьте, что клиент — это, например, обычный браузер. Клиент отправляет некоторый запрос и ждёт ответа — страницу с определённым интерактивом (например, должен появляться фейерверк в том месте, где пользователь кликает кнопкой мышки). Это всё может быть реализовано на стороне клиента.

Либо клиент, запрашивая данную страницу приветствия, получит в ответ от сервера не просто HTML-код для отображения, а ещё программу, которую он сам и исполнит. Получается, что сервер передаёт исходный код клиенту, а тот его выполняет.

Что мы за счёт этого получаем? Отчасти, это схоже с принципом HATEOAS. Мы позволяем клиенту стать гибче. Если мы захотим изменить цвет фейерверка, то нам не нужно вносить изменений на клиенте — мы можем сделать это на сервере, а затем передавать клиенту. Пример такого языка — javascript.

Насколько же сходятся идеи, которые вложил Рэй Филдинг в концепцию REST, с восприятием REST аналитиками?

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

1. Ограничения REST опциональны (необязательны)

С точки зрения создателя этой концепции существует ровно одно необязательное ограничение — код по требованию. Все остальные ограничения должны выполняться. Если одно из них не выполняется — это уже не REST-подход.

2. REST — протокол передачи данных

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

Но, в целом, REST — это концепция, парадигма, но не протокол. В отличие от HTTP, который действительно является протоколом.

3. REST — это всегда HTTP

С одной стороны, ни один из архитектурных принципов REST не говорит нам о том, какой транспорт мы должны использовать — HTTP или очереди.

Но при этом в жизни очень часто встречаются люди, для которых REST и HTTP — это аксиома.

Поэтому, если сказать человеку, что REST — это необязательно HTTP, то вас могут посчитать сумасшедшими.

Почему же все считают, что REST — это HTTP? Здесь нужно сделать ремарку, что одним из главных авторов протокола HTTP — это Рэй Филдинг, автор концепции REST. Рэй Филдинг стремился спроектировать HTTP так, чтобы с помощью него концепцию REST было максимально удобно реализовывать.

4. REST — это обязательно JSON

Почему так сложилось? Главная причина в том, что какое-то время назад сервисы вида JSON over HTTP стали противопоставлять SOAP. JSON одновременно стал популярным и стал антагонистом XML, как SOAP подходу. JSON использовался, потому что это не SOAP.

Модель зрелости REST-сервисов

Ричардсон выделил уровни зрелости REST-сервисов. Выделение происходило исходя из подхода, что REST — это, с точки зрения протокола, всё-таки HTTP. Соответственно, он спроектировал модель, по которой можно понять: насколько сервис REST или не REST.

Уровень 0

В первую очередь, он выделил нулевой уровень. К нему относятся любые сервисы, которые в качестве транспорта используют HTTP и какой-то формат представления данных. Например, когда мы говорим про JSON over HTTP – мы говорим про нулевой уровень.

Если более наглядно «пощупать ручками» с точки зрения использования протокола HTTP, то можно представить, что мы выставляем некоторый API. Мы начинаем с того, что объявляем единый путь для отправки команд и всегда используем один и тот же HTTP-глагол для совершения абсолютно любых действий с любыми объектами. Например: создай вебинар, запиши вебинар, удали вебинар и т.д. То есть мы всегда используем один и тот же URL и всегда используем один и тот же HTTP-метод, обычно POST.

Как один из примеров:

Серверный api что этоПример 0-го уровня соответствия REST

Уровень 1

Следующий уровень — первый. Мы уже научились использовать разные ресурсы и делаем это не по одному URL. Но при этом всё ещё игнорируем HTTP-глаголы.

Мы просто разделяем явно наши объекты, как некоторые ресурсы. Например: спикер, курс, вебинар. Но, независимо от того, что мы хотим сделать — удалить, создать, редактировать, мы всё равно используем один и тот же HTTP-глагол POST.

Серверный api что этоПример 1-го уровня соответствия REST

Уровень 2

Второй уровень — это когда мы начинаем правильно с точки зрения спецификации HTTP-протокола использовать HTTP-глаголы.

Например, если есть спикер, то, чтобы создать спикера и получить информацию о нём, я использую соответствующий глагол: GET, POST. Когда хочу создать или удалить спикера — я использую глаголы: PUT, DELETE.

По сути, второй уровень зрелости — это то, что чаще всего называют REST.

Надо понимать, что, с точки зрения изначальной концепции, если мы дошли до второго уровня зрелости, то это еще не означает, что мы спроектировали REST-систему/ REST-сервис. Но в очень распространённом понимании соответствие 2-ому уровню часто называют RESTfull сервисом.

RESTfull-сервис — это такой сервис, который спроектирован с учётом REST-ограничений. Хотя, в целом, правильнее сервис такого уровня зрелости называть HTTP-сервисом или HTTP-API, нежели REST-API.

Серверный api что этоПример 2-го уровня соответствия REST

Уровень 3

Третий уровень зрелости — это уровень, в котором мы начинаем использовать концепцию HATEOAS. Когда мы передаём информацию, ресурсы, мы сообщаем потребителям (клиентам) о том, какие ещё действия необходимо совершить ресурсу, а также связи с другими ресурсами.

Серверный api что этоПример 3-го уровня соответствия REST

Выводы, которые мы можем сделать из модели зрелости

Итак, как нам эта модель может помочь понять то, что наши коллеги называют RESTом в каждой отдельно взятой компании? REST у вас или не REST?

Первая распространенная трактовка термина REST — всё, что передаётся в виде JSON поверх HTTP.

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

Серверный api что этоЧто называют RESTом?

Подведём итоги

Во-первых, у каждого свой REST. Мнения о том, что такое REST, часто разнятся. Когда мы работаем с новыми проектами, новыми коллегами или специалистами, очень важно понять, что именно ваш коллега называет RESTом. Это полезно для того, чтобы на одном из этапов проектирования или разработки не оказалось, что мы половину проекта говорили о разных вещах.

Во-вторых, принципы REST мы часто применяем в жизни. Они очень полезны для осмысления. Кэширование, STATELESS и STATEFUL, клиент-серверная модель или код по требованию — это те вещи, которые аналитику полезно знать для понимания.

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

1. Способы описания API

2. Инструменты для тестирования API

Источник

Что такое REST API

REST API это HTTP API (иногда говорят WEB API) построенный по принципам REST-архитектуры. Впервые термин REST ввел Рой Филдинг в своей докторской диссертации “Architectural Styles and the Design of Network-based Software Architectures” в 2000 году. Многие обратили на нее серьезное внимание, потому что Рой был не случайным человеком в индустрии. Этот ученый был одним из ключевых разработчиков протокола HTTP/1.0 и автором HTTP/1.1. Он участвовал в разработке языка HTML и стандарта URI. Кроме того, он со-автор некогда самого популярного веб-сервера в мире Apache Web Server.

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

Немного истории

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

Since 1994, the REST architectural style has been used to guide the design and development of the architecture for the modern Web. This work was done in conjunction with my authoring of the Internet standards for the Hypertext Transfer Protocol (HTTP) and Uniform Resource Identifiers (URI), the two specifications that define the generic interface used by all component interactions on the Web.

— Roy Fielding, Architectural Styles and the Design of Network-based Software Architectures, p. 107.

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

Термин “REST” был введён Роем Филдингом, одним из создателей протокола “HTTP”, лишь в 2000 году. В своей диссертации “Архитектурные стили и дизайн сетевых программных архитектур” (“Architectural Styles and the Design of Network-based Software Architectures”) в Калифорнийском университете в Ирвайне он подвёл теоретическую основу под способ взаимодействия клиентов и серверов во Всемирной паутине, абстрагировав его и назвав “передачей представительного состояния”.

Чтобы протокол взаимодействия соответствовал REST-стилю, необходимо соблюсти, как минимум, 5 требований. Если сервис соблюдает только часть из них, то про такой протокол говорят, что он REST-like. Если соблюдаются все требования, то протокол является RESTful. На практике, есть ситуации, в которых невозможно следовать REST требованиям, поэтому большинство протоколов являются REST-like, даже если они утверждают другое.

Единообразие интерфейса

По таблице ниже видно, что каждый URN является идентификатором либо одиночного ресурса, либо коллекции ресурсов (это тоже ресурс), а необходимые действия задаются посредством использования подходящего http метода. И всё это должно происходить в строгом соответствии семантике http, другими словами, REST использует то, что заложено в http, а не меняет это или добавляет свое.

МетодМаршрутОписание
GET/photosdisplay a list of all photos
GET/photos/newreturn an HTML form for creating a new photo
POST/photoscreate a new photo
GET/photos/:iddisplay a specific photo
GET/photos/:id/editreturn an HTML form for editing a photo
PATCH/PUT/photos/:idupdate a specific photo
DELETE/photos/:iddelete a specific photo

Кэширование

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

Отсутствие состояния

Протокол взаимодействия между клиентом и сервером не сохраняет какого-либо сессионного состояния после запроса и ответа (Stateless protocol). В случае необходимости, такое состояние должно сохраняться на клиенте. Только тогда пользователь отвязан от конкретного сервера, что, в свою очередь, позволяет масштабироваться и безболезненно переносить (балансировать) запросы между серверами.

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

Клиент-серверная архитектура

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

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

Код по требованию (необязательное ограничение)

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

Преимущества REST

Филдинг указывал, что приложения, не соответствующие приведённым условиям, не могут называться REST-приложениями. Если же все условия соблюдены, то, по его мнению, приложение получит следующие преимущества:

По-простому

Грубо говоря, REST это набор рекомендаций о том, как лучше сделать для получения преимуществ, описанных абзацем выше. Чем больше рекомендаций вы выполните, тем более REST получается приложение. А поскольку жизнь сложна, то это нормально, что REST ориентированными сервисы являются только отчасти. Использования REST как догмы ни к чему хорошему не приведёт. И REST никоим образом не заменяет собой RPC. Выбор решения зависит от ситуации и предъявляемых требований.

JSONAPI

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

Источник

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

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