на чем писать rest api

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

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

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

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

Вы изучите:

Что такое REST?

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

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

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

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

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

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

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

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

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

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

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

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

на чем писать rest api. Смотреть фото на чем писать rest api. Смотреть картинку на чем писать rest api. Картинка про на чем писать rest api. Фото на чем писать rest 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 для перфекционистов за 5 минут

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

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

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

Почему я должен постоянно вспоминать о том, общался я с этим человеком или нет? Мы уже перешли на ты? Я пишу какое-то коммерческое предложение и мне надо «Выкнуть» или это ответ на рядовое письмо и достаточно простого «вы». Почему мне постоянно надо расстраиваться, когда мне с порога совершенно незнакомый человек начинает «тыкать», как будто я его друг с курилки?

Я принципиально всем «выкаю» с маленькой буквы и я убеждён, что это имеет свою цену. Наверняка есть люди, которым не нравится, что их назвали с маленькой буквы и они не ответят на моё письмо.

Так зачем эти сложности?

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

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

Введение

Речь пойдёт об инструменте, который позволит вам построить полноценный и простой в использовании REST API за минимальное количество времени. Называется он – Python Eve.

К сожалению в Интернете очень много инструкций на эту тему, но все они вводят в заблуждение. Начинающие разработчики, начитавшись подобных статей, думают, что REST API это GET/POST/PUT/DELETE. Заказчики думают, что это дело пары часов. А когда они встречаются вместе, происходят магия в виде Express.js/Mongoose/Passport и ещё кучи хлама, который течёт и временами блокирует event-loop. Всё это запускается с помощью какого-нибудь supervisor, потому что иногда падает и надо как-то перезапускать.

И всё бы ничего, но вчера у меня состоялся разговор с хабра-пользователем, который предложил воспользоваться «Express.js, MongoDB, Mongoose, Passport, отладчиком WebStorm’a и головой на плечах«. Похожие разговоры случались часто, поэтому я решил написать эту статью и «отсылать» ссылкой на неё.

Полноценный REST API?

Речь не только о реализации архитектурного стиля REST API, но и о протоколе HTTP, о валидации и кэшировании, о HATEOAS (wikipedia), о котором, похоже, вообще предпочитают не вспоминать. Затем нам понадобится фильтрация результатов и сортировка, постраничная навигация и частичное обновление записей. Потом мы задумаемся о целостности данных и условных запросах. Наверняка нам понадобится аутентификация, возможно захотим отображать данные не только в JSON, но и в XML. Это ещё про версионность и вложенные записи я не упомянул. Затем, как это обычно бывает, какой-то #$%$%^ начнёт долбить в наш могучий API с тяжёлым запросом и нам понадобится ограничить частоту запросов.

Даже если представить, что разработкой такого API займётся невероятно крутой разработчик с 3-мя мониторами, отладчиком WebStorm’a и головой на плечах, он затратит на это не просто много времени, а очень много. Поддержка кодовой базы будет обходиться дорого, а внедрение новых функций будет долгим.

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

Но мы с вами простоту – любим, а время – уважаем. Так приступим же!

Установка

Это обычный python-пакет, поэтому устанавливается он стандартным способом:

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

Быстрый старт

Перед тем, как мы начнём «творить» магию, нам понадобится база данных MongoDB. Если у вас её нет, вы можете воспользоваться любым бесплатным сервисом, например MongoLab. Регистрация займёт не больше минуты. После регистрации создайте базу данных и пользователя для этой базы.

Теперь давайте напишем минимальную версию нашего REST API. Для начала создадим главный файл run.py со следующим содержимым:

Теперь нам надо создать файл настроек settings.py:

На мой взгляд здесь всё достаточно просто и вопросов возникнуть не должно. Если это не так – добро пожаловать в комментарии. Полный список параметров конфигурации вы можете глянуть в документации.

Всё готово, запускаем:

Прелюдия

Вы уже подумали, что сейчас мы начнём безбожно «curlить», но я вынужден вас разочаровать. Мы, со свойственным нам перфекционизмом, воспользуемся инструментом автора, который обладает чувством прекрасного:

на чем писать rest api. Смотреть фото на чем писать rest api. Смотреть картинку на чем писать rest api. Картинка про на чем писать rest api. Фото на чем писать rest api
Инструмент называется HTTPie и ставится в один клик одну команду:

Игрища и забавы

HTTPie вызывается командой «http«. Для того, что бы отправить GET запрос к нашему API, выполним:

Благодаря HATEOAS мы видим, что у нас есть 2 ресурса: users и groups. Заглянем внутрь:

Давайте создадим пользователя johndoe:

Первое, на что стоит обратить внимание, это на нашу команду:

HTTPie увидел, что мы отправляем параметр username и превратил его в JSON:

Затем отправил нашему API методом POST. Давайте обратим внимание на ошибки:

Мы видим сразу весь список ошибок валидации и это здорово. Исправим их и выполним запрос повторно:

Ну вот, мы только что успешно создали нового пользователя. Давайте проверим так ли это:

Нет никаких сомнений, что это так. Настало время попробовать перезаписать (обратите внимание, не отредактировать, а перезаписать) пользователя. Делается это с помощью метода PUT, который надо указать явно (если не указать, будет выполнен POST):

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

Для того, что бы мы в такой ситуации не оказались, используется идентификатор ETag. В двух словах — это уникальный идентификатор, который генерируется Eve при каждом изменении записи. Используя этот идентификатор мы можем сказать нашему API, что хотим изменить запись только определённой версии и если она с тех пор была отредактирована, то наши изменения выполнены не будут. Делается это с помощью условного запроса с HTTP заголовком «If-Match«:

Обратите внимание каким образом мы передали HTTP заголовок HTTPie. Это не единственное, для чего может использоваться идентификатор ETag и условные запросы. Я здесь не буду останавливаться на этом, но советую вам ознакомиться с этой темой, если вы этого ещё не сделали.

Настало время создать новую группу. Для начала попробуем создать группу с несуществующим пользователем:

И действительно, пользователя с таким _id не существует. Обратите внимание как мы передаём список пользователей:

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

На этот раз мы укажем правильный _id:

«Усё добра», как говорила моя прабабушка. Проверим:

Прабабушка оказалась бы права. На этом можно было бы закончить, но мы поступим иначе.

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

Попросим тоже самое в XML:

Попробуем изменить только имя нашего пользователя (без полной перезаписи). Для этого воспользуемся HTTP методом PATCH:

Что сказала бы бабуля?

«Усё добра». Мне так понравилось, что я бы создавал пользователей пачками:

Найдём пользователя «John Doe» по его имени:

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

Ну и наконец-то удалим всех пользователей:

Я бы не стал включать данную возможность в production. Указывается это в параметре RESOURCE_METHODS (стоит убрать из списка DELETE):

Заключение

Мы рассмотрели не все возможности Eve, но даже c учётом этого – получили законченный вариант REST API.

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

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

Источник

В данной статье вы узнаете, как создать простой REST API в PHP.

1. Обзор проекта

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

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

1.2 Зачем нужен REST API?

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

1.3 Где используется REST API?

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

2. Файловая структура

3. Настройка базы данных

3.1 Создание таблицы категорий

3.2 Дамп данных для таблицы категорий

3.3 Создание таблицы товаров

3.4 Дамп данных для таблицы товаров

3.5 Подключение к базе данных

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

Создайте папку api и откройте её. Создайте папку config и в ней создайте файл database.php со следующим кодом.

4. Получение товаров

4.1 Создание объекта Product

Код ниже содержит класс с именем Product и несколько свойств. Также показан метод конструктора, который принимает соединение с базой данных.

4.2 Создание файла для чтения товаров

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

4.3 Подключение к базе данных и таблице товаров

Замените комментарий // подключение к базе данных будет здесь в файле read.php следующим кодом.

4.4 Чтение товаров из базы данных

Замените комментарий // чтение товаров будет здесь в файле read.php следующим кодом.

4.5 Создание метода read()

4.6 Уведомление пользователя о том, что товары не найдены

Замените комментарий // ‘товары не найдены’ будет здесь в файле read.php следующим кодом.

5. Создание товаров

5.1 Создание файла create.php

Откройте папку product и создайте в ней файл create.php со следующим содержимым.

5.2 Создание метода create()

6. Получение одного товара

6.1 Создание файла read_one.php

6.2 Создание метода readOne()

7. Обновление товара

7.1 Создание файла update.php

7.2 Создание метода update()

8. Удаление товара

8.1 Создание файла delete.php

Откройте папку product и создайте файл delete.php со следующим содержимым.

8.2 Создание метода delete()

9. Поиск товаров

9.1 Создание файла search.php

В папке product создайте файл search.php со следующим кодом.

9.2 Создание метода search()

10. Пагинация товаров

10.1 Создание файла read_paging.php

В папке product создайте файл read_paging.php со следующим кодом.

10.2 Создание файла core.php

Этот файл содержит нашу базовую конфигурацию, такую как базовый URL и переменные пагинации.

Откройте папку config и создайте в ней файл core.php со следующим содержимым.

10.3 Создание метода readPaging()

10.4 Создание метода count()

Так же в классе Product (файл product.php) добавьте метод count() для создания массива пагинации.

10.5 Получение массива пагинации

11. Получение категорий

11.1 Создание объекта Category

Откройте папку objects и создайте новый файл category.php со следующим кодом.

11.2 Создание файла read.php

Создайте новую папку category в корне, и в ней файл read.php со следующим кодом.

11.3 Создание метода read()

Если вам понравилась данная статья, рекомендую к прочтению создание регистрации и авторизации в php с использованием JWT.

Надеюсь, вам понравилась данная информация. Если вам интересна тема web-разработки, то можете следить за выходом новых статей в Telegram.

Источник

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

Источник

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

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