Создание API-интерфейсов RESTful с помощью веб-API ASP.NET
Практическое занятие. Используйте веб-API в ASP.NET 4.x для создания простого REST API для приложения диспетчера контактов. Вы также создадите клиент для использования API.
В последние годы стало ясно, что HTTP предназначен не только для обслуживания HTML-страниц. Это также мощная платформа для создания веб-API с использованием нескольких команд (GET, POST и т. д.), а также нескольких простых понятий, таких как URI и заголовки. веб-API ASP.NET — это набор компонентов, упрощающих программирование HTTP. Так как он создан на основе среды выполнения ASP.NET MVC, веб-API автоматически обрабатывает низкоуровневые сведения о транспорте HTTP. В то же время веб-API, естественно, предоставляет модель программирования HTTP. На самом деле одна из целей веб-API заключается в том, чтобы не абстрагироваться от реальности HTTP. В результате веб-API является гибким и простым в расширении. Архитектурный стиль REST оказался эффективным способом использования HTTP, хотя это, конечно, не единственный допустимый подход к HTTP. Диспетчер контактов предоставит restful для перечисления, добавления и удаления контактов, а также для других.
Для этого задания требуется базовое понимание HTTP, REST и предполагается, что у вас есть базовые знания в области HTML, JavaScript и jQuery.
Примечание
Веб-сайт ASP.NET имеет область, посвященную платформе веб-API ASP.NET по адресу https://asp.net/web-api. Этот сайт будет по-прежнему предоставлять последние сведения, примеры и новости, связанные с веб-API, поэтому проверка его часто, если вы хотите углубиться в искусство создания пользовательских веб-API, доступных практически для любого устройства или платформы разработки.
веб-API ASP.NET, как и ASP.NET MVC 4, обладает большой гибкостью с точки зрения отделения уровня служб от контроллеров, что позволяет использовать несколько доступных платформ внедрения зависимостей довольно просто.
Все примеры кода и фрагменты кода включены в комплект для обучения веб-лагерей, доступный по адресу https://github.com/Microsoft-Web/WebCampTrainingKit/releases.
Задачи
В этом практическом задании вы узнаете, как:
- Реализация веб-API RESTful
- Вызов API из HTML-клиента
Предварительные требования
Для выполнения этого практического задания требуется следующее:
- Microsoft Visual Studio Express 2012 для Web или более поздней версии (инструкции по установке см. в приложении Б).
Настройка
Установка фрагментов кода
Для удобства большая часть кода, который вы будете управлять в рамках этой лаборатории, доступна в виде фрагментов кода Visual Studio. Чтобы установить фрагменты кода, запустите файл .\Source\Setup\CodeSnippets.vsi .
Если вы не знакомы с фрагментами Visual Studio Code и хотите узнать, как их использовать, см. приложение из этого документа «Приложение А. Использование фрагментов кода».
Упражнения
Это практическое занятие включает в себя следующее упражнение:
- Упражнение 1. Создание веб-API Read-Only
- Упражнение 2. Создание веб-API для чтения и записи
- Упражнение 3. Использование веб-API из HTML-клиента
Каждое упражнение сопровождается папкой End , содержащей полученное решение, которое необходимо получить после выполнения упражнений. Это решение можно использовать в качестве руководства, если вам нужна дополнительная помощь в работе с упражнениями.
Предполагаемое время выполнения этого задания: 60 минут.
Упражнение 1. Создание веб-API Read-Only
В этом упражнении вы реализуете доступные только для чтения методы GET для диспетчера контактов.
Задача 1. Создание проекта API
В этой задаче вы будете использовать новые шаблоны веб-проектов ASP.NET для создания веб-приложения веб-API.
- Запустите Visual Studio 2012 Express для Web, для этого перейдите в меню Пуск и введите VS Express for Web , а затем нажмите клавишу ВВОД.
- В меню Файл выберите Создать проект. Выберите Visual C# | Тип веб-проекта в представлении дерева типа проекта, а затем выберите тип проекта ASP.NET веб-приложение MVC 4 . Задайте для параметра Имя проекта значениеContactManager , а в поле Имя решения — Начало, а затем нажмите кнопку ОК.
Создание проекта веб-приложения ASP.NET MVC 4.0 - В диалоговом окне тип проекта ASP.NET MVC 4 выберите тип проекта Веб-API . Нажмите кнопку ОК.
Указание типа проекта веб-API
Задача 2. Создание контроллеров API Диспетчера контактов
В этой задаче вы создадите классы контроллера, в которых будут находиться методы API.
- Удалите файл с именем ValuesController.cs в папке Controllers из проекта.
- Щелкните правой кнопкой мыши папку Controllers в проекте и выберите Добавить | Контроллер из контекстного меню.
Добавление нового контроллера в проект - В появившемся диалоговом окне Добавление контроллера выберите Пустой контроллер API в меню Шаблон. Назовите класс контроллера ContactController. Затем нажмите кнопку Добавить.
Использование диалогового окна «Добавление контроллера» для создания нового контроллера веб-API - Добавьте следующий код в ContactController. (Фрагмент кода — лаборатория веб-API — Ex01 — получение метода API)
public string[] Get() < return new string[] < "Hello", "World" >; >
по Домашняя страница приложения веб-API ASP.NET по умолчанию
Открытие вкладки «Сеть» и запуск сетевого захвата
Просмотр выходных данных запроса веб-API в представлении «Сеть»
Примечание На этом этапе по умолчанию internet Обозреватель 10 будет спрашивать, хочет ли пользователь сохранить или открыть поток, полученный в результате вызова веб-API. Выходными данными будет текстовый файл, содержащий результат JSON вызова URL-адреса веб-API. Не отменяйте диалоговое окно, чтобы иметь возможность watch содержимое ответа через окно инструментов разработчиков.
Переключение в подробное представление
Просмотр выходного текста JSON в сетевом монитореЗадача 3. Создание моделей контактов и расширение контроллера контактов
В этой задаче вы создадите классы контроллера, в которых будут находиться методы API.
- Щелкните правой кнопкой мыши папку Models и выберите Добавить | Класс. в контекстном меню.
Добавление новой модели в веб-приложение - В диалоговом окне Добавление нового элемента назовите новый файл Contact.cs и нажмите кнопку Добавить.
Создание файла класса Contact - Добавьте следующий выделенный код в класс Contact . (Фрагмент кода — лаборатория веб-API — Ex01 — класс contact)
public class Contact < public int Id < get; set; >public string Name < get; set; >>

public Contact[] Get() < return new Contact[] < new Contact < Name = "Glenn Block" >, new Contact < Name = "Dan Roth" >>; >

- После открытия браузера нажмите клавишу F12 , если средства разработчика еще не открыты.
- Перейдите на вкладку Сеть .
- Нажмите кнопку Начать запись .
- Добавьте URL-суффикс /api/contact в URL-адрес в адресной строке и нажмите клавишу ВВОД .
- Нажмите кнопку Перейти к подробному просмотру .
- Перейдите на вкладку Текст ответа . Вы увидите строку JSON, представляющую сериализованную форму массива экземпляров Contact. Сериализованные выходные данные JSON сложного вызова метода веб-API
Задача 4. Извлечение функциональных возможностей в уровень служб
Эта задача продемонстрирует, как извлечь функциональные возможности на уровень служб, чтобы разработчики могли легко отделять свои функциональные возможности служб от уровня контроллера, тем самым обеспечивая возможность повторного использования служб, которые фактически выполняют эту работу.
- Создайте новую папку в корне решения и назовите ее Службы. Для этого щелкните правой кнопкой мыши проект ContactManager , выберите Добавить | новую папку и назовите ее Службы.
Создание папки служб - Щелкните правой кнопкой мыши папку Службы и в контекстном меню выберите Добавить | Класс. .
Добавление нового класса в папку Services - Когда откроется диалоговое окно Добавление нового элемента , назовите новый класс ContactRepository и нажмите кнопку Добавить.
Создание файла класса, содержащего код для уровня службы «Репозиторий контактов» - Добавьте директиву using в файл ContactRepository.cs , чтобы включить пространство имен models.
using ContactManager.Models;
public class ContactRepository < public Contact[] GetAllContacts() < return new Contact[] < new Contact < Name = "Glenn Block" >, new Contact < Name = "Dan Roth" >>; > >
using ContactManager.Services;
public class ContactController : ApiController < private ContactRepository contactRepository; public ContactController() < this.contactRepository = new ContactRepository(); >. >
public Contact[] Get()

Добавление точек останова в контроллер контактов 11. Нажмите клавишу F5 , чтобы запустить приложение. 12. Когда откроется браузер, нажмите клавишу F12 , чтобы открыть средства разработчика. 13. Перейдите на вкладку Сеть . 14. Нажмите кнопку Начать запись . 15. Добавьте URL-адрес в адресной строке с суффиксом /api/contact и нажмите клавишу ВВОД , чтобы загрузить контроллер API. 16. Visual Studio 2012 должен прерываться после начала выполнения метода Get .

Нарушение в методе Get 17. Нажмите клавишу F5 , чтобы продолжить. 18. Назад в Интернет Обозреватель, если она еще не находится в центре внимания. Обратите внимание на окно сетевого захвата.

Представление сети в Обозреватель Интернета с результатами вызова веб-API 19. Нажмите кнопку Перейти к подробному просмотру. 20. Перейдите на вкладку Текст ответа . Обратите внимание на выходные данные JSON вызова API и то, как они представляют два контакта, полученные уровнем служб.

Просмотр выходных данных JSON из веб-API в окне средств разработчика
Упражнение 2. Создание веб-API для чтения и записи
В этом упражнении вы реализуете методы POST и PUT для диспетчера контактов, чтобы включить функции редактирования данных.
Задача 1. Открытие проекта веб-API
В этой задаче вы будете готовиться к улучшению проекта веб-API, созданного в упражнении 1, чтобы он принимал входные данные пользователя.
- Запустите Visual Studio 2012 Express для Web, для этого перейдите в меню Пуск и введите VS Express for Web , а затем нажмите клавишу ВВОД.
- Откройте решение Begin , расположенное в папке Source/Ex02-ReadWriteWebAPI/Begin/ . В противном случае вы можете продолжить использовать решение End , полученное при выполнении предыдущего упражнения.
- Если вы открыли предоставленное решение Begin , вам потребуется скачать некоторые отсутствующие пакеты NuGet, прежде чем продолжить. Для этого щелкните меню Проект и выберите Управление пакетами NuGet.
- В диалоговом окне Управление пакетами NuGet нажмите кнопку Восстановить , чтобы скачать отсутствующие пакеты.
- Наконец, выполните сборку решения, щелкнув BuildSolution (Сборка | решения).
Примечание Одним из преимуществ использования NuGet является то, что вам не нужно отправлять все библиотеки в проекте, уменьшая размер проекта. С помощью NuGet Power Tools, указав версии пакета в файле Packages.config, вы сможете скачать все необходимые библиотеки при первом запуске проекта. Именно поэтому эти действия необходимо выполнить после открытия существующего решения из этой лаборатории.
Задача 2. Добавление функций Data-Persistence в реализацию репозитория контактов
В этой задаче вы добавите класс ContactRepository проекта веб-API, созданного в упражнении 1, чтобы он сохранял и принимал входные данные пользователем и новые экземпляры Contact.
-
Добавьте следующую константу в класс ContactRepository , чтобы представить имя ключа элемента кэша веб-сервера далее в этом упражнении.
private const string CacheKey = "ContactStore";public ContactRepository() < var ctx = HttpContext.Current; if (ctx != null) < if (ctx.Cache[CacheKey] == null) < var contacts = new Contact[] < new Contact < Name = "Glenn Block" >, new Contact < Name = "Dan Roth" >>; ctx.Cache[CacheKey] = contacts; > > >public Contact[] GetAllContacts() < var ctx = HttpContext.Current; if (ctx != null) < return (Contact[])ctx.Cache[CacheKey]; >return new Contact[] < new Contact < Name = "Placeholder" >>; >Примечание Этот пример предназначен для демонстрации и будет использовать кэш веб-сервера в качестве носителя хранилища, чтобы значения были доступны нескольким клиентам одновременно, а не использовать механизм хранения сеансов или время существования хранилища запросов. Вместо кэша веб-сервера можно использовать Entity Framework, хранилище XML или любой другой вариант.
public bool SaveContact(Contact contact) < var ctx = HttpContext.Current; if (ctx != null) < try < var currentData = ((Contact[])ctx.Cache[CacheKey]).ToList(); currentData.Add(contact); ctx.Cache[CacheKey] = currentData.ToArray(); return true; >catch (Exception ex) < Console.WriteLine(ex.ToString()); return false; >> return false; >Упражнение 3. Использование веб-API из HTML-клиента
В этом упражнении вы создадите HTML-клиент для вызова веб-API. Этот клиент упрощает обмен данными с помощью веб-API с помощью JavaScript и будет отображать результаты в веб-браузере с помощью разметки HTML.
Задача 1. Изменение представления индекса для предоставления графического пользовательского интерфейса для отображения контактов
В этой задаче вы измените представление индекса веб-приложения по умолчанию, чтобы обеспечить поддержку отображения списка существующих контактов в браузере HTML.
- Откройте Visual Studio 2012 Express для Интернета , если он еще не открыт.
- Откройте решение Begin , расположенное в папке Source/Ex03-ConsumingWebAPI/Begin/ . В противном случае вы можете продолжить использовать решение End , полученное при выполнении предыдущего упражнения.
- Если вы открыли предоставленное решение Begin , вам потребуется скачать некоторые отсутствующие пакеты NuGet, прежде чем продолжить. Для этого щелкните меню Проект и выберите Управление пакетами NuGet.
- В диалоговом окне Управление пакетами NuGet нажмите кнопку Восстановить , чтобы скачать отсутствующие пакеты.
- Наконец, выполните сборку решения, щелкнув BuildSolution (Сборка | решения).
Примечание Одним из преимуществ использования NuGet является то, что вам не нужно отправлять все библиотеки в проекте, уменьшая размер проекта. С помощью NuGet Power Tools, указав версии пакета в файле Packages.config, вы сможете скачать все необходимые библиотеки при первом запуске проекта. Именно поэтому эти действия необходимо выполнить после открытия существующего решения из этого лабораторного задания.

- Откройте файл ContactController.cs , если он еще не открыт.
- Поместите точку останова в метод Get класса ContactController . Размещение точки останова в методе Get контроллера API
- Нажмите клавишу F5 , чтобы запустить проект. Браузер загрузит HTML-документ.
Примечание Убедитесь, что вы просматриваете корневой URL-адрес приложения.
- После загрузки страницы и выполнения JavaScript будет достигнута точка останова, а выполнение кода приостанавливается в контроллере.
Отладка в вызове веб-API с помощью Visual Studio 2012 Express for Web - Удалите точку останова и нажмите клавишу F5 или кнопку Продолжить на панели инструментов отладки, чтобы продолжить загрузку представления в браузере. После завершения вызова веб-API вы увидите, что контакты, возвращенные из вызова веб-API, отображаются в браузере в виде элементов списка.
Результаты вызова API, отображаемые в браузере в виде элементов списка - Остановите отладку.
Задача 2. Изменение представления индекса для предоставления графического пользовательского интерфейса для создания контактов
В этой задаче вы продолжите изменять представление индекса приложения MVC. На HTML-страницу будет добавлена форма, которая будет захватывать введенные пользователем данные и отправлять их в веб-API для создания контакта, а также будет создан новый метод контроллера веб-API для сбора данных из графического пользовательского интерфейса.
- Откройте файл ContactController.cs .
- Добавьте новый метод в класс контроллера с именем Post , как показано в следующем коде. (Фрагмент кода — лаборатория веб-API — Ex03 — метод Post)
public HttpResponseMessage Post(Contact contact) < this.contactRepository.SaveContact(contact); var response = Request.CreateResponse(System.Net.HttpStatusCode.Created, contact); return response; > - В Файле ContactController.cs поместите точку останова в метод Post .
- Нажмите клавишу F5 , чтобы запустить приложение в браузере.
- После загрузки страницы в браузере введите новое имя контакта и идентификатор и нажмите кнопку Сохранить .
Клиентский HTML-документ, загруженный в браузере - Когда окно отладчика прерывается в методе Post , просмотрите свойства параметра contact . Значения должны совпадать с данными, введенными в форме.
Объект Contact, отправляемый в веб-API из клиента - Пошаговое выполнение метода в отладчике до создания переменной ответа . После проверки в окне Локальные в отладчике вы увидите, что все свойства заданы.

Ответ после создания в отладчике 11. Если нажать клавишу F5 или нажать кнопку Продолжить в отладчике, запрос завершится. После возврата в браузер новый контакт будет добавлен в список контактов, хранящихся в реализации ContactRepository .

Браузер отражает успешное создание нового экземпляра контакта
Кроме того, вы можете развернуть это приложение в Azure, следуя приложению C. Публикация приложения ASP.NET MVC 4 с помощью веб-развертывания.
Итоги
В этом задании вы ознакомили вас с новой платформой веб-API ASP.NET и реализацией веб-API RESTful с помощью платформы. Здесь можно создать новый репозиторий, который упрощает сохранение данных с помощью любого количества механизмов и подключения, которые обслуживаются, а не простой, представленный в качестве примера в этом задании. Веб-API поддерживает ряд дополнительных функций, таких как включение обмена данными с клиентов, отличных от HTML, написанных на любом языке, поддерживающем HTTP и JSON или XML. Также возможна возможность размещения веб-API за пределами типичного веб-приложения, а также возможность создавать собственные форматы сериализации.
Веб-сайт ASP.NET имеет область, посвященную платформе веб-API ASP.NET по адресу [https://asp.net/web-api](https://asp.net/web-api). Этот сайт будет по-прежнему предоставлять последние сведения, примеры и новости, связанные с веб-API, поэтому проверка его часто, если вы хотите углубиться в искусство создания пользовательских веб-API, доступных практически для любого устройства или платформы разработки.
Приложение А. Использование фрагментов кода
С помощью фрагментов кода у вас есть весь необходимый код. В лабораторном документе будет указано, когда их можно использовать, как показано на следующем рисунке.

Вставка кода в проект с помощью фрагментов кода Visual Studio
Добавление фрагмента кода с помощью клавиатуры (только C#)
- Поместите курсор в то место, куда вы хотите вставить код.
- Начните вводить имя фрагмента (без пробелов или дефисов).
- Посмотрите, как IntelliSense отображает имена соответствующих фрагментов кода.
- Выберите правильный фрагмент (или продолжайте вводить, пока не будет выбрано имя всего фрагмента).
- Дважды нажмите клавишу TAB, чтобы вставить фрагмент в расположение курсора.
Начните вводить имя фрагмента кода
Нажмите клавишу TAB, чтобы выбрать выделенный фрагмент.
. Нажмите клавишу TAB еще раз, и фрагмент кода развернется.
Добавление фрагмента кода с помощью мыши (C#, Visual Basic и XML)
- Щелкните правой кнопкой мыши место, куда нужно вставить фрагмент кода.
- Выберите Вставить фрагмент кода , а затем — My Code Snippets (Фрагменты кода).
- Выберите соответствующий фрагмент из списка, щелкнув его.
кода. Щелкните правой кнопкой мыши место, куда нужно вставить фрагмент кода, и выберите команду Вставить фрагмент кода.
. Выберите соответствующий фрагмент из списка, щелкнув его
Приложение Б. Установка Visual Studio Express 2012 для Web
Вы можете установить Microsoft Visual Studio Express 2012 для Web или другую версию Express с помощью установщик веб-платформы Майкрософт. Ниже приведены инструкции по установке Visual Studio Express 2012 for Web с помощью установщик веб-платформы Майкрософт.
- Перейдите к [https://go.microsoft.com/?linkid=9810169](https://go.microsoft.com/?linkid=9810169). Кроме того, если у вас уже установлен установщик веб-платформы, вы можете открыть его и найти продукт «Visual Studio Express 2012 для веб-приложений с пакетом AZURE SDK«.
- Щелкните Установить сейчас. Если у вас нет установщика веб-платформы , вы будете перенаправлены на его скачивание и установку.
- После открытия установщика веб-платформы нажмите кнопку Установить , чтобы начать установку.
Установка Visual Studio Express - Ознакомьтесь со всеми лицензиями и условиями продуктов и нажмите кнопку Я принимаю , чтобы продолжить.
Принятие условий лицензии - Дождитесь завершения процесса скачивания и установки.
Ход установки - После завершения установки нажмите кнопку Готово.
Установка завершена - Нажмите кнопку Выйти , чтобы закрыть установщик веб-платформы.
- Чтобы открыть Visual Studio Express для Интернета, перейдите на начальный экран и начните писать «VS Express«, а затем щелкните плитку VS Express для Web.
Плитка VS Express для Web
Приложение В. Публикация приложения ASP.NET MVC 4 с помощью веб-развертывания
В этом приложении показано, как создать новый веб-сайт на портале Azure и опубликовать приложение, полученное с помощью лаборатории, используя преимущества публикации веб-развертывания, предоставляемой Azure.
Задача 1. Создание веб-сайта на портале Azure
- Перейдите на портал управления Azure и войдите, используя учетные данные Майкрософт, связанные с вашей подпиской.
Примечание С помощью Azure вы можете разместить 10 ASP.NET веб-сайтов бесплатно, а затем масштабироваться по мере роста трафика. Вы можете зарегистрироваться здесь.
Вход на портал
Создание веб-сайтаПримечание Azure — это узел для веб-приложения, работающего в облаке, которым можно управлять и управлять. Параметр Быстрое создание позволяет развернуть готовое веб-приложение в Azure за пределами портала. Он не включает шаги по настройке базы данных.
Создание веб-сайта с помощью быстрого создания
Переход на новый веб-сайт
Запущенный веб-сайт
Открытие страниц управления веб-сайтомПримечание Профиль публикации содержит все сведения, необходимые для публикации веб-приложения в Azure для каждого включенного метода публикации. Профиль публикации содержит URL-адреса, учетные данные пользователей и строки для открытия базы данных, которые необходимы для проверки подлинности и подключения к каждой из конечных точек, соответствующей разрешенному методу публикации. Microsoft WebMatrix 2, Microsoft Visual Studio Express для Web и Microsoft Visual Studio 2012 поддерживают чтение профилей публикации для автоматизации настройки этих программ для публикации веб-приложений в Azure.
Скачивание профиля публикации веб-сайта
Сохранение файла профиля публикацииЗадача 2. Настройка сервера базы данных
Если приложение использует SQL Server базы данных, необходимо создать сервер База данных SQL. Если вы хотите развернуть простое приложение, которое не использует SQL Server можно пропустить эту задачу.
- Вам потребуется сервер База данных SQL для хранения базы данных приложения. Серверы База данных SQL из подписки можно просмотреть на портале управления Azure напанели мониторинга Сервера баз данных | | SQL. Если сервер не создан, его можно создать с помощью кнопки Добавить на панели команд. Запишите имя сервера и URL-адрес, имя входа администратора и пароль, так как они будут использоваться в следующих задачах. Пока не создавайте базу данных, так как она будет создана на более позднем этапе.
Панель мониторинга сервера База данных SQL - В следующей задаче вы протестируете подключение к базе данных из Visual Studio, поэтому необходимо включить локальный IP-адрес в список разрешенных IP-адресов сервера. Для этого нажмите кнопку Настроить, выберите IP-адрес в поле Текущий IP-адрес клиента , вставьте его в текстовые поля Начальный IP-адрес и Конечный IP-адрес и нажмите
.
Добавление IP-адреса клиента - После добавления IP-адреса клиента в список разрешенных IP-адресов нажмите кнопку Сохранить , чтобы подтвердить изменения.
Подтверждение изменений
Задача 3. Публикация приложения ASP.NET MVC 4 с помощью веб-развертывания
- Назад к решению ASP.NET MVC 4. В Обозреватель решений щелкните правой кнопкой мыши проект веб-сайта и выберите Опубликовать.
Публикация веб-сайта - Импортируйте профиль публикации, сохраненный в первой задаче.
Импорт профиля публикации - Щелкните Проверить подключение. После завершения проверки нажмите кнопку Далее.
Примечание Проверка завершается, когда рядом с кнопкой Проверить подключение появится зеленая галочка.
Проверка подключения
Конфигурация веб-развертывания- В поле Имя сервера введите URL-адрес сервера База данных SQL, используя префикс tcp: .
- В поле Имя пользователя введите имя входа администратора сервера.
- В поле Пароль введите пароль для входа администратора сервера.
- Введите новое имя базы данных, например MVC4SampleDB.
Настройка строки подключения назначения
Создание базы данных
Строка подключения, указывающая на База данных SQL
Публикация веб-приложения
Приложение, опубликованное в AzureОбратная связь
Были ли сведения на этой странице полезными?
Советы по REST API
Будь то RESTful или нет (в соответствии с шестью ограничениями, описанными ранее), вот несколько рекомендованных REST концепций, которые помогут построить более хорошие и удобные сервисы:
Используйте HTTP-глаголы, чтобы ваши запросы имели понятное значение
Пользователи API должны иметь возможность отправлять команды GET, POST, PUT и DELETE, что значительно повышает ясность того, что делает запрос.
Как правило, четыре основных HTTP-глагола используются следующим образом:
GET Прочитать конкретный ресурс (по идентификатору) или набор ресурсов PUT Обновить конкретный ресурс (по идентификатору) или набор ресурсов. Также может использоваться для создания определенного ресурса, если идентификатор ресурса известен заранее DELETE Удалить конкретный ресурс по идентификатору POST Создать новый ресурс. Также универсальное действие для операций, которые не вписываются в другие категории
Примечание
GET-запросы не должны изменять данные базовых ресурсов. При этом может выполняться отслеживание, приводящее к обновлению данных, но данные ресурса, идентифицированного данным URI, не должны изменяться.
Давайте ресурсам продуманные имена
Создание хорошего API — это на 80% искусство и на 20% наука. Создание иерархии осмысленных URL-адресов относится к искусству. Рациональное наименование ресурсов (названия которых представляют собой просто URL-пути, такие как /customers/12345/orders) улучшает понимание того, что делает данный запрос.
Подходящие названия ресурсов предоставляют контекст для запроса и делают API сервиса более понятным. Ресурсы должны просматриваться иерархически по их именам. Пользователям должна предлагаться удобная, легко понимаемая иерархия ресурсов для использования в их приложениях.
Вот несколько простых правил для дизайна URL-пути (имени ресурса):
- Используйте идентификаторы в URL-адресах, а не в строке запроса. Использование параметров строки запроса отлично подходит для фильтрации, но не для имен ресурсов
Хорошо: /users/12345
Плохо: /api?type=user&id=23 - URL-адреса иерархичны, пользуйтесь этим для задания структуры ресурсов
- Дизайн сервиса должен быть ориентирован на ваших клиентов, а не на ваши данные
- Имена ресурсов должны быть существительными. Избегайте глаголов в именах ресурсов, это позволит сделать их яснее. Используйте методы HTTP, чтобы указать, какое действие выполняет запрос
- Используйте множественное число в соответствующих сегментах URL-адресов, чтобы обеспечить согласованность URI вашего API во всех HTTP-методах, применяя метафору коллекции
Хорошо: /customers/33245/orders/8769/lineitems/1
Плохо: /customer/33245/order/8769/lineitem/1 - Избегайте использования наборов слов в URL-адресах (например, customer_list в качестве ресурса). Используйте множественное число для названий коллекций
Хорошо: /customers
Плохо: /customer_list - Используйте строчные буквы в URL, разделяя слова подчеркиванием («_») или дефисом («-«). Некоторые серверы игнорируют регистр, поэтому лучше четко придерживаться нижнего регистра
- Старайтесь, чтобы URL-адреса были как можно короче и содержали как можно меньше сегментов
Используйте коды HTTP-ответов для указания статуса
Коды ответа являются частью спецификации HTTP. Для описания самых распространенных ситуаций существует большой набор HTTP-ответов.
Поскольку наши RESTful сервисы следуют спецификации HTTP, наши веб-API должны возвращать коды состояний HTTP. Например, когда ресурс успешно создан с помощью запроса POST, API должен вернуть код состояния HTTP 201. Полный список возможных кодов состояния HTTP c подробным описанием доступен здесь
Top 10 кодов состояния HTTP-ответа:
200 ОК Код, указывающий на успешное выполнение запроса и чаще всего встречающийся на практике 201 CREATED Ресурс успешно создан (через POST или PUT). Установите заголовок Location со ссылкой на вновь созданный ресурс (при POST). Тело ответа может быть как пустым, так и содержать что-то 204 NO CONTENT Запрос выполнен успешно, но в теле ответа нет данных. Часто используется для операций DELETE и PUT 400 BAD REQUEST Общая ошибка, когда при выполнении запроса возникает недопустимое состояние. Примеры — ошибки проверки домена, отсутствующие данные и т.д. 401 UNAUTHORIZED Код ошибки для отсутствующего или недопустимого токена аутентификации 403 FORBIDDEN Код ошибки, когда пользователь не авторизован для выполнения операции или ресурс недоступен по какой-либо причине (например, ограничения по времени и т.п.) 404 NOT FOUND Этот код используется, когда запрошенный ресурс не найден. Ресурс не существует, либо была ошибка 401 или 403, которую по соображениям безопасности сервис хочет скрыть 405 METHOD NOT ALLOWED Используется для указания на то, что запрошенный URL-адрес существует, но используемый HTTP-метод неприменим. Например, POST /users/12345, где API не поддерживает создание ресурсов таким образом (с предоставленным идентификатором). При возврате ошибки 405 должен быть установлен HTTP-заголовок Allow, указывающий на поддерживаемые методы HTTP. В примере выше заголовок выглядел бы как “Allow: GET, PUT, DELETE” 409 CONFLICT Этот код ошибки отправляется всякий раз, когда выполнение запроса может привести к конфликту ресурсов. Примеры таких ситуаций — двойные записи, например, попытка создать двух клиентов с одинаковой информацией; удаление корневых объектов, когда не поддерживается каскадное удаление 500 INTERNAL SERVER ERROR Никогда не отправляйте этот код вручную. Это общая ошибка, когда на стороне сервера выбрасывается какое-то исключение. Этот код должен использоваться только для ошибок, которые пользователь не может устранить со своей стороны
XML и JSON
Если вы не работаете в строго стандартизированной и регулируемой отрасли, лучше поддерживать JSON. Но если вас ничто не сковывает, позвольте пользователям выбирать в каком формате получать данные — JSON или XML. У пользователей должна быть возможность переключаться между ними с помощью HTTP-заголовка Accept или просто изменив расширение с .xml на .json.
Имейте в виду, что как только мы начинаем говорить о поддержке XML, мы начинаем говорить о валидации, пространствах имен и т.д. Если этого не требует ваша отрасль, избегайте поддержки всех этих усложнений. По крайней мере, вначале. А если в этом функционале нет острой необходимости, то всегда. JSON является простым, лаконичным и функциональным. Сделайте так, чтобы ваш XML выглядел так же, если это возможно.
Другими словами, сделайте возвращаемый XML более похожим на JSON — простым и легко читаемым, без сведений о схеме и пространстве имен, содержащим только данные и ссылки. Если ваш XML будет более сложным, стоимость поддержки будет неоправданно большой. Если судить по нашему опыту — никто никогда не отвечает в формате XML. Обрабатывать XML слишком затратно.
Обратите внимание, что JSON-Schema предлагает возможности по валидации XML, если вам все-таки нужен такой функционал.
Создавайте детальные ресурсы
Сначала гораздо проще создавать API, которые имитируют основной домен приложения или архитектуру базы данных вашей системы. В конце концов, вы захотите объединить сервисы, которые используют несколько основных ресурсов, чтобы избежать избыточности информации. Позже будет гораздо проще создать большие ресурсы из отдельных ресурсов, чем детальные ресурсы из более крупных составных ресурсов. Упростите себе задачу и начните с небольших, легко определяемых ресурсов, предоставив для них CRUD-функциональность. Ресурсы без лишней информации, ориентированные на конкретные ситуации, можно сделать позже.
Учитывайте связность
Одним из принципов REST является связность через ссылки. Хотя сервисы остаются полезными и без них, API становится более самоописательным, когда в ответе содержатся ссылки. По крайней мере, ссылка “на себя” информирует клиентов, как данные были или могут быть получены. Кроме того, используйте заголовок Location, который должен содержать ссылку на создание ресурса с помощью POST (или PUT). Для коллекций возвращайте в ответе сведения о том, что поддерживается пагинация, а также, как минимум, ссылки “первая”, “последняя”, “следующая” и “предыдущая”.
Что касается форматов ссылок, то их существует довольно много.
Спецификация HTTP веб-ссылок RFC5988 определяет ссылку следующим образом:
Ссылка — это типизированное соединение между двумя ресурсами, идентифицируемыми интернационализированными идентификаторами ресурсов (IRI) [RFC3987]
Ссылка состоит из:
- контекстного IRI
- типа ссылки
- целевого IRI
- целевых атрибутов (опционально)
Ссылку можно рассматривать как утверждение вида имеет ресурс в , который имеет .
По меньшей мере, размещайте ссылки в HTTP-заголовке Link, как это рекомендовано в спецификации, или используйте JSON-представление данного стиля HTTP-ссылок (например, ссылки в стиле Atom, см. RFC4287). По мере того, как ваш API будет становиться более зрелым, вы сможете использовать более сложные стили ссылок, такие как HAL+JSON, Siren, Collection+JSON и/или JSON-LD и т.д.
Данный сайт является переводом RestApiTutorial.com
Как создать RESTful API
Узнайте, как создать RESTful API шаг за шагом, от выбора языка программирования до развертывания на сервере.

Алексей Кодов
Автор статьи
1 июня 2023 в 8:42
RESTful API (Representational State Transfer) — это архитектурный стиль, используемый для обмена данными между клиентами и серверами. В этой статье мы рассмотрим, как создать RESTful API с помощью языка программирования и фреймворка на ваш выбор.
1. Выбор языка программирования и фреймворка
Есть множество языков программирования и фреймворков, которые позволяют создать RESTful API. Вот некоторые из них:
- JavaScript и Node.js с фреймворками Express, Koa или Nest
- Python и фреймворки Flask или Django
- Ruby и фреймворк Ruby on Rails
- Java и фреймворки Spring, Jakarta EE или Micronaut
Выберите язык и фреймворк, с которыми вам комфортно работать и которые подходят для вашей задачи.
2. Планирование API
Прежде чем начать разработку, нужно спланировать API. Определите, какие ресурсы (данные) будут доступны через API, и какие операции (CRUD — Create, Read, Update, Delete) можно будет выполнять с этими ресурсами.
Например, если вы создаете API для блога, ресурсы могут включать статьи, авторов и комментарии. Для каждого ресурса определите доступные операции, например:
- Создать статью
- Получить список статей
- Получить статью по ID
- Обновить статью
- Удалить статью
3. Разработка API
Приступите к разработке API, используя выбранный язык программирования и фреймворк. Создайте маршруты для каждой операции, определите структуру данных и реализуйте логику обработки запросов. Не забудьте добавить обработку ошибок и валидацию входных данных.
Пример создания маршрута на Express.js для получения списка статей:
const express = require('express'); const app = express(); app.get('/articles', (req, res) => < // Получение списка статей из базы данных >); app.listen(3000, () => < console.log('Server started'); >);
4. Тестирование API
После разработки API необходимо провести тестирование. Используйте инструменты, такие как Postman или Insomnia, для отправки запросов к вашему API и проверки корректности работы всех маршрутов.
5. Документация
Оформите документацию для вашего API, чтобы другие разработчики могли легко использовать его. В документации должны быть описаны доступные ресурсы, методы запросов, параметры, примеры запросов и ответов.
Python-разработчик: новая работа через 9 месяцев
Получится, даже если у вас нет опыта в IT

6. Развертывание API
После завершения разработки, тестирования и документирования вашего API, разверните его на сервере или облачной платформе. Некоторые популярные варианты размещения включают Heroku, AWS, Google Cloud Platform и Microsoft Azure.
Теперь ваш RESTful API готов к использованию!
Если вы хотите углубить свои знания в области веб-разработки и изучить создание RESTful API подробнее, рекомендую посетить [название знакомой школы](ссылка на сайт школы), которая предлагает качественное обучение.
Полноценный REST API для перфекционистов за 5 минут

Привет, Хабр! Меня зовут Владимир, мне 28 лет и я наркоман наркоман. Мой наркотик – простота. На простоту я подсел из-за своего перфекционизма, которым меня наградили при рождении.
Врачи говорят, что это взаимосвязано, мол перфекционизм — это стремление к совершенству, а простота позволяет подобраться к этому мифическому совершенству. Чем проще решение, тем меньше ошибок можно допустить, вот я и подсел. Я не стал с ними спорить и вместо того, что бы искать виновников моей истории, решил с этим жить и постараться повысить качество этой самой жизни.
Мир вокруг не идеален, сложную вещь сделать простой – невероятно сложно, поэтому всё чрезмерно усложнено. Людям нравится чувствовать себя профессионалами, поэтому они оперируют сложными терминами, когда в этом нет необходимости, так они ощущают свою значимость и заполняют пустоту, которая образовалась из-за страха потерянного времени.
Усложнить можно всё: ты/Вы/вы
Почему я должен постоянно вспоминать о том, общался я с этим человеком или нет? Мы уже перешли на ты? Я пишу какое-то коммерческое предложение и мне надо «Выкнуть» или это ответ на рядовое письмо и достаточно простого «вы». Почему мне постоянно надо расстраиваться, когда мне с порога совершенно незнакомый человек начинает «тыкать», как будто я его друг с курилки?
Я принципиально всем «выкаю» с маленькой буквы и я убеждён, что это имеет свою цену. Наверняка есть люди, которым не нравится, что их назвали с маленькой буквы и они не ответят на моё письмо.
Так зачем эти сложности?
Когда я упомянул про повышение качества жизни, я имел ввиду некоторые правила, которые помогают быстро принимать решения и не жалеть об этом. Например, я не использую сложные вещи постоянно, не общаюсь с людьми, которым нравится всё усложнять. Если вещь, которой вы пользуетесь каждый день – сложна, то это значит только то, что ей не уделили достаточно внимания. Если человек вам не может объяснить даже трудную для понимания тему простым языком, значит, он сам не до конца понимает о чём говорит.
Есть ещё кое-что, что имеет не менее важное значение – время. Время – бесценный ресурс, а выражение «Время — деньги» из уст умных людей вызывает у меня улыбку с разочарованием (выглядишь как идиот и чувствуешь себя так же). Я до сих пор не знаю ни одного миллиардера, которому деньги помогли прожить дольше других людей.
Введение
Речь пойдёт об инструменте, который позволит вам построить полноценный и простой в использовании 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 и головой на плечах, он затратит на это не просто много времени, а очень много. Поддержка кодовой базы будет обходиться дорого, а внедрение новых функций будет долгим.

Но мы с вами простоту – любим, а время – уважаем. Так приступим же!
Установка
Это обычный python-пакет, поэтому устанавливается он стандартным способом:
$ pip install eve
Если вас интересуют альтернативные методы установки, можете заглянуть в официальную документацию.
Быстрый старт
Перед тем, как мы начнём «творить» магию, нам понадобится база данных MongoDB. Если у вас её нет, вы можете воспользоваться любым бесплатным сервисом, например MongoLab. Регистрация займёт не больше минуты. После регистрации создайте базу данных и пользователя для этой базы.
Теперь давайте напишем минимальную версию нашего REST API. Для начала создадим главный файл run.py со следующим содержимым:
from eve import Eve app = Eve() if __name__ == '__main__': app.run()
Теперь нам надо создать файл настроек settings.py:
# замените user, password, ds049945.mongolab.com, example на ваши данные доступа к БД. MONGO_URI = "mongodb://user:password@ds049945.mongolab.com:49945/example" # По умолчанию Eve запускает API в режиме "read-only" (т.е. поддерживаются только GET запросы), # мы включаем поддержку методов POST, PUT, PATCH, DELETE. RESOURCE_METHODS = ['GET', 'POST', 'DELETE'] ITEM_METHODS = ['GET', 'PATCH', 'PUT', 'DELETE'] DOMAIN = < # Описываем ресурс `/users` 'users': < # Здесь мы описываем модель данных. Для валидации используется модуль Cerberus от автора Eve. # Вы можете ознакомиться с ним в официальной документации модуля http://docs.python-cerberus.org/en/stable/. # Либо прочитать заметки в официальной документации EVE http://python-eve.org/validation.html#validation. 'schema': < 'username': < 'type': 'string', 'minlength': 5, 'maxlength': 32, 'required': True, # уникальное поле (индекс не создаётся, просто значение должно быть уникальным) 'unique': True, >, 'firstname': < 'type': 'string', 'minlength': 1, 'maxlength': 10, 'required': True, >, 'lastname': < 'type': 'string', 'minlength': 1, 'maxlength': 15, 'required': True, >, 'role': < 'type': 'list', # тип: список 'allowed': ["author", "contributor"], # разрешаем использовать значения: "author", "contributor" >, 'location': < 'type': 'dict', # тип: словарь # описываем "схему" словаря 'schema': < 'address': , 'city': >, >, 'born': < 'type': 'datetime', >, 'active': < 'type': 'boolean', 'default': True >> >, # Описываем ресурс `/groups` 'groups': < # Описываем модель данных (см. выше). 'schema': < 'title': < 'type': 'string', 'minlength': 5, 'maxlength': 32, 'required': True, 'unique': True >, 'users': < 'type': 'list', # тип: список 'default': [], # по умолчанию: пустой список # описываем "схему" списка 'schema': < 'type': 'objectid', # тип данных: objectid # ссылаемся на запись в другой коллекции 'data_relation': < 'resource': 'users', # на ресурс `users` (который мы описали выше) 'field': '_id', # на поле `_id` 'embeddable': True >> > > > >
На мой взгляд здесь всё достаточно просто и вопросов возникнуть не должно. Если это не так – добро пожаловать в комментарии. Полный список параметров конфигурации вы можете глянуть в документации.
Всё готово, запускаем:
$ python3.5 run.py * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Прелюдия
Вы уже подумали, что сейчас мы начнём безбожно «curlить», но я вынужден вас разочаровать. Мы, со свойственным нам перфекционизмом, воспользуемся инструментом автора, который обладает чувством прекрасного:

Инструмент называется HTTPie и ставится в один клик одну команду:
$ pip install httpie
Игрища и забавы
HTTPie вызывается командой «http«. Для того, что бы отправить GET запрос к нашему API, выполним:
$ http http://0.0.0.0:5000/ HTTP/1.0 200 OK Content-Length: 99 Content-Type: application/json Date: Sun, 07 Feb 2016 18:13:33 GMT Server: Eve/0.6.1 Werkzeug/0.10.4 Python/3.5.0 < "_links": < "child": [ < "href": "users", "title": "users" >, < "href": "groups", "title": "groups" >] > >
Благодаря HATEOAS мы видим, что у нас есть 2 ресурса: users и groups. Заглянем внутрь:
» http http://0.0.0.0:5000/users HTTP/1.0 200 OK Content-Length: 166 Content-Type: application/json Date: Sun, 07 Feb 2016 18:20:41 GMT Server: Eve/0.6.1 Werkzeug/0.10.4 Python/3.5.0 X-Total-Count: 0 < "_items": [], "_links": < "parent": < "href": "/", "title": "home" >, "self": < "href": "users", "title": "users" >>, "_meta": < "max_results": 25, "page": 1, "total": 0 >>
Давайте создадим пользователя johndoe:
$ http http://0.0.0.0:5000/users username=johndoe HTTP/1.0 422 UNPROCESSABLE ENTITY Content-Length: 184 Content-Type: application/json Date: Sun, 07 Feb 2016 18:22:44 GMT Server: Eve/0.6.1 Werkzeug/0.10.4 Python/3.5.0 < "_error": < "code": 422, "message": "Insertion failure: 1 document(s) contain(s) error(s)" >, "_issues": < "firstname": "required field", "lastname": "required field" >, "_status": "ERR" >
Первое, на что стоит обратить внимание, это на нашу команду:
$ http http://0.0.0.0:5000/users username=johndoe
HTTPie увидел, что мы отправляем параметр username и превратил его в JSON:
Затем отправил нашему API методом POST. Давайте обратим внимание на ошибки:
"_issues":
Мы видим сразу весь список ошибок валидации и это здорово. Исправим их и выполним запрос повторно:
$ http http://0.0.0.0:5000/users username=johndoe firstname=John lastname=Doe HTTP/1.0 201 CREATED Content-Length: 276 Content-Type: application/json Date: Sun, 07 Feb 2016 18:34:42 GMT Server: Eve/0.6.1 Werkzeug/0.10.4 Python/3.5.0 < "_created": "Sun, 07 Feb 2016 18:34:41 GMT", "_etag": "24509359443095dd05dece6d0eb7d98cce70b076", "_id": "56b78e41cf7b35255aa5a1e6", "_links": < "self": < "href": "users/56b78e41cf7b35255aa5a1e6", "title": "User" >>, "_status": "OK", "_updated": "Sun, 07 Feb 2016 18:34:41 GMT" >
Ну вот, мы только что успешно создали нового пользователя. Давайте проверим так ли это:
$ http http://0.0.0.0:5000/users HTTP/1.0 200 OK Content-Length: 504 Content-Type: application/json Date: Sun, 07 Feb 2016 18:36:00 GMT Last-Modified: Sun, 07 Feb 2016 18:34:41 GMT Server: Eve/0.6.1 Werkzeug/0.10.4 Python/3.5.0 X-Total-Count: 1 < "_items": [ < "_created": "Sun, 07 Feb 2016 18:34:41 GMT", "_etag": "24509359443095dd05dece6d0eb7d98cce70b076", "_id": "56b78e41cf7b35255aa5a1e6", "_links": < "self": < "href": "users/56b78e41cf7b35255aa5a1e6", "title": "User" >>, "_updated": "Sun, 07 Feb 2016 18:34:41 GMT", "active": true, "firstname": "John", "lastname": "Doe", "username": "johndoe" > ], "_links": < "parent": < "href": "/", "title": "home" >, "self": < "href": "users", "title": "users" >>, "_meta": < "max_results": 25, "page": 1, "total": 1 >>
Нет никаких сомнений, что это так. Настало время попробовать перезаписать (обратите внимание, не отредактировать, а перезаписать) пользователя. Делается это с помощью метода PUT, который надо указать явно (если не указать, будет выполнен POST):
$ http put http://0.0.0.0:5000/users/56b78e41cf7b35255aa5a1e6 username=janedoe firstname="Jane" lastname="Doe" HTTP/1.0 403 FORBIDDEN Content-Length: 101 Content-Type: application/json Date: Sun, 07 Feb 2016 18:43:04 GMT Server: Eve/0.6.1 Werkzeug/0.10.4 Python/3.5.0 < "_error": < "code": 403, "message": "An etag must be provided to edit a document" >, "_status": "ERR" >
Упс, ошибка. Я выше упоминал о целостности данных. Дело в том, что может произойти ситуация, в которой кто-то уже изменил запись, которую хотите поменять вы. И когда вы её отредактируете, то будете думать, что изменили одну запись, но на самом деле уже совсем другую.
Для того, что бы мы в такой ситуации не оказались, используется идентификатор ETag. В двух словах — это уникальный идентификатор, который генерируется Eve при каждом изменении записи. Используя этот идентификатор мы можем сказать нашему API, что хотим изменить запись только определённой версии и если она с тех пор была отредактирована, то наши изменения выполнены не будут. Делается это с помощью условного запроса с HTTP заголовком «If-Match«:
$ http put http://0.0.0.0:5000/users/56b78e41cf7b35255aa5a1e6 "If-Match":"24509359443095dd05dece6d0eb7d98cce70b076" username=janedoe firstname="Jane" lastname="Doe" HTTP/1.0 200 OK Content-Length: 276 Content-Type: application/json Date: Sun, 07 Feb 2016 18:46:56 GMT ETag: 0138d193174528c205827ba9af25b7b8fb93940e Last-Modified: Sun, 07 Feb 2016 18:46:56 GMT Server: Eve/0.6.1 Werkzeug/0.10.4 Python/3.5.0 < "_created": "Sun, 07 Feb 2016 18:34:41 GMT", "_etag": "0138d193174528c205827ba9af25b7b8fb93940e", "_id": "56b78e41cf7b35255aa5a1e6", "_links": < "self": < "href": "users/56b78e41cf7b35255aa5a1e6", "title": "User" >>, "_status": "OK", "_updated": "Sun, 07 Feb 2016 18:46:56 GMT" >
Обратите внимание каким образом мы передали HTTP заголовок HTTPie. Это не единственное, для чего может использоваться идентификатор ETag и условные запросы. Я здесь не буду останавливаться на этом, но советую вам ознакомиться с этой темой, если вы этого ещё не сделали.
Настало время создать новую группу. Для начала попробуем создать группу с несуществующим пользователем:
$ http http://0.0.0.0:5000/groups title="Friends" users:='["56b77466cf7b352414deb451"]' HTTP/1.0 422 UNPROCESSABLE ENTITY Content-Length: 220 Content-Type: application/json Date: Sun, 07 Feb 2016 19:14:31 GMT Server: Eve/0.6.1 Werkzeug/0.10.4 Python/3.5.0 < "_error": < "code": 422, "message": "Insertion failure: 1 document(s) contain(s) error(s)" >, "_issues": < "users": < "0": "value '56b77466cf7b352414deb451' must exist in resource 'users', field '_id'." >>, "_status": "ERR" >
И действительно, пользователя с таким _id не существует. Обратите внимание как мы передаём список пользователей:
users:='["56b77466cf7b352414deb451"]'
Подробнее вы можете почитать в официальной документации к HTTPie, которая такая же качественная, как и сам инструмент.
На этот раз мы укажем правильный _id:
» http http://0.0.0.0:5000/groups title="Friends" users:='["56b78e41cf7b35255aa5a1e6"]' HTTP/1.0 201 CREATED Content-Length: 278 Content-Type: application/json Date: Sun, 07 Feb 2016 19:21:42 GMT Server: Eve/0.6.1 Werkzeug/0.10.4 Python/3.5.0 < "_created": "Sun, 07 Feb 2016 19:21:41 GMT", "_etag": "c6fc02a0bd4bae92a1310be0748ff8bc971ff209", "_id": "56b79945cf7b35255aa5a1e7", "_links": < "self": < "href": "groups/56b79945cf7b35255aa5a1e7", "title": "Group" >>, "_status": "OK", "_updated": "Sun, 07 Feb 2016 19:21:41 GMT" >
«Усё добра», как говорила моя прабабушка. Проверим:
$ http http://0.0.0.0:5000/groups HTTP/1.0 200 OK Content-Length: 488 Content-Type: application/json Date: Sun, 07 Feb 2016 19:24:50 GMT Last-Modified: Sun, 07 Feb 2016 19:21:41 GMT Server: Eve/0.6.1 Werkzeug/0.10.4 Python/3.5.0 X-Total-Count: 1 < "_items": [ < "_created": "Sun, 07 Feb 2016 19:21:41 GMT", "_etag": "c6fc02a0bd4bae92a1310be0748ff8bc971ff209", "_id": "56b79945cf7b35255aa5a1e7", "_links": < "self": < "href": "groups/56b79945cf7b35255aa5a1e7", "title": "Group" >>, "_updated": "Sun, 07 Feb 2016 19:21:41 GMT", "title": "Friends", "users": [ "56b78e41cf7b35255aa5a1e6" ] > ], "_links": < "parent": < "href": "/", "title": "home" >, "self": < "href": "groups", "title": "groups" >>, "_meta": < "max_results": 25, "page": 1, "total": 1 >>
Прабабушка оказалась бы права. На этом можно было бы закончить, но мы поступим иначе.
Получим группу с пользователями, которые в неё входят, в развёрнутом виде:
$ http http://0.0.0.0:5000/groups/56b79945cf7b35255aa5a1e7/\?embedded='' HTTP/1.0 200 OK Content-Length: 646 Content-Type: application/json Date: Sun, 07 Feb 2016 19:38:27 GMT ETag: c6fc02a0bd4bae92a1310be0748ff8bc971ff209 Last-Modified: Sun, 07 Feb 2016 19:21:41 GMT Server: Eve/0.6.1 Werkzeug/0.10.4 Python/3.5.0 < "_created": "Sun, 07 Feb 2016 19:21:41 GMT", "_etag": "c6fc02a0bd4bae92a1310be0748ff8bc971ff209", "_id": "56b79945cf7b35255aa5a1e7", "_links": < "collection": < "href": "groups", "title": "groups" >, "parent": < "href": "/", "title": "home" >, "self": < "href": "groups/56b79945cf7b35255aa5a1e7", "title": "Group" >>, "_updated": "Sun, 07 Feb 2016 19:21:41 GMT", "title": "Friends", "users": [ < "_created": "Sun, 07 Feb 2016 18:34:41 GMT", "_etag": "0138d193174528c205827ba9af25b7b8fb93940e", "_id": "56b78e41cf7b35255aa5a1e6", "_updated": "Sun, 07 Feb 2016 18:46:56 GMT", "active": true, "firstname": "Jane", "lastname": "Doe", "username": "janedoe" >] >
Попросим тоже самое в XML:
$ http http://0.0.0.0:5000/groups/56b79945cf7b35255aa5a1e7/\?embedded='' "Accept":"application/xml" HTTP/1.0 200 OK Content-Length: 690 Content-Type: application/xml; charset=utf-8 Date: Sun, 07 Feb 2016 19:43:36 GMT ETag: c6fc02a0bd4bae92a1310be0748ff8bc971ff209 Last-Modified: Sun, 07 Feb 2016 19:21:41 GMT Server: Eve/0.6.1 Werkzeug/0.10.4 Python/3.5.0 <_created>Sun, 07 Feb 2016 19:21:41 GMT <_etag>c6fc02a0bd4bae92a1310be0748ff8bc971ff209 <_id>56b79945cf7b35255aa5a1e7 <_updated>Sun, 07 Feb 2016 19:21:41 GMT Friends <_created>Sun, 07 Feb 2016 18:34:41 GMT <_etag>0138d193174528c205827ba9af25b7b8fb93940e <_id>56b78e41cf7b35255aa5a1e6 <_updated>Sun, 07 Feb 2016 18:46:56 GMT True Jane Doe janedoe
Попробуем изменить только имя нашего пользователя (без полной перезаписи). Для этого воспользуемся HTTP методом PATCH:
$ http patch http://0.0.0.0:5000/users/56b78e41cf7b35255aa5a1e6 firstname=John "If-Match":"0138d193174528c205827ba9af25b7b8fb93940e" HTTP/1.0 200 OK Content-Length: 276 Content-Type: application/json Date: Sun, 07 Feb 2016 19:46:48 GMT ETag: 86f3495cf1d6edf301e25563099844bd816c5a3c Server: Eve/0.6.1 Werkzeug/0.10.4 Python/3.5.0 < "_created": "Sun, 07 Feb 2016 18:34:41 GMT", "_etag": "86f3495cf1d6edf301e25563099844bd816c5a3c", "_id": "56b78e41cf7b35255aa5a1e6", "_links": < "self": < "href": "users/56b78e41cf7b35255aa5a1e6", "title": "User" >>, "_status": "OK", "_updated": "Sun, 07 Feb 2016 19:46:47 GMT" >
Что сказала бы бабуля?
» http http://0.0.0.0:5000/users/56b78e41cf7b35255aa5a1e6 HTTP/1.0 200 OK Content-Length: 431 Content-Type: application/json Date: Sun, 07 Feb 2016 19:50:06 GMT ETag: 86f3495cf1d6edf301e25563099844bd816c5a3c Last-Modified: Sun, 07 Feb 2016 19:46:47 GMT Server: Eve/0.6.1 Werkzeug/0.10.4 Python/3.5.0 < "_created": "Sun, 07 Feb 2016 18:34:41 GMT", "_etag": "86f3495cf1d6edf301e25563099844bd816c5a3c", "_id": "56b78e41cf7b35255aa5a1e6", "_links": < "collection": < "href": "users", "title": "users" >, "parent": < "href": "/", "title": "home" >, "self": < "href": "users/56b78e41cf7b35255aa5a1e6", "title": "User" >>, "_updated": "Sun, 07 Feb 2016 19:46:47 GMT", "active": true, "firstname": "John", "lastname": "Doe", "username": "janedoe" >
«Усё добра». Мне так понравилось, что я бы создавал пользователей пачками:
$ echo '[,]' | http http://0.0.0.0:5000/users HTTP/1.0 201 CREATED Content-Length: 585 Content-Type: application/json Date: Sun, 07 Feb 2016 20:01:33 GMT Server: Eve/0.6.1 Werkzeug/0.10.4 Python/3.5.0 < "_items": [ < "_created": "Sun, 07 Feb 2016 20:01:33 GMT", "_etag": "6f397b570ef12769d372c902fa6149bb7e9eaf89", "_id": "56b7a29dcf7b35255aa5a1e8", "_links": < "self": < "href": "users/56b7a29dcf7b35255aa5a1e8", "title": "User" >>, "_status": "OK", "_updated": "Sun, 07 Feb 2016 20:01:33 GMT" >, < "_created": "Sun, 07 Feb 2016 20:01:33 GMT", "_etag": "378f30b37724139c213a85079185226ab2b209f3", "_id": "56b7a29dcf7b35255aa5a1e9", "_links": < "self": < "href": "users/56b7a29dcf7b35255aa5a1e9", "title": "User" >>, "_status": "OK", "_updated": "Sun, 07 Feb 2016 20:01:33 GMT" > ], "_status": "OK" >
Найдём пользователя «John Doe» по его имени:
$ http http://0.0.0.0:5000/users\?where='' HTTP/1.0 200 OK Content-Length: 535 Content-Type: application/json Date: Sun, 07 Feb 2016 20:05:28 GMT Last-Modified: Sun, 07 Feb 2016 19:46:47 GMT Server: Eve/0.6.1 Werkzeug/0.10.4 Python/3.5.0 X-Total-Count: 1 < "_items": [ < "_created": "Sun, 07 Feb 2016 18:34:41 GMT", "_etag": "86f3495cf1d6edf301e25563099844bd816c5a3c", "_id": "56b78e41cf7b35255aa5a1e6", "_links": < "self": < "href": "users/56b78e41cf7b35255aa5a1e6", "title": "User" >>, "_updated": "Sun, 07 Feb 2016 19:46:47 GMT", "active": true, "firstname": "John", "lastname": "Doe", "username": "janedoe" > ], "_links": < "parent": < "href": "/", "title": "home" >, "self": < "href": "users?where=", "title": "users" > >, "_meta": < "max_results": 25, "page": 1, "total": 1 >>
Отсортируем пользователей по их логину в обратном порядке:
$ http http://0.0.0.0:5000/users\?sort\=-username HTTP/1.0 200 OK Content-Length: 1203 Content-Type: application/json Date: Sun, 07 Feb 2016 20:08:08 GMT Last-Modified: Sun, 07 Feb 2016 20:01:33 GMT Server: Eve/0.6.1 Werkzeug/0.10.4 Python/3.5.0 X-Total-Count: 3 < "_items": [ < "_created": "Sun, 07 Feb 2016 20:01:33 GMT", "_etag": "378f30b37724139c213a85079185226ab2b209f3", "_id": "56b7a29dcf7b35255aa5a1e9", "_links": < "self": < "href": "users/56b7a29dcf7b35255aa5a1e9", "title": "User" >>, "_updated": "Sun, 07 Feb 2016 20:01:33 GMT", "active": true, "firstname": "First", "lastname": "Last", "username": "usertwo" >, < "_created": "Sun, 07 Feb 2016 20:01:33 GMT", "_etag": "6f397b570ef12769d372c902fa6149bb7e9eaf89", "_id": "56b7a29dcf7b35255aa5a1e8", "_links": < "self": < "href": "users/56b7a29dcf7b35255aa5a1e8", "title": "User" >>, "_updated": "Sun, 07 Feb 2016 20:01:33 GMT", "active": true, "firstname": "First", "lastname": "Last", "username": "userone" >, < "_created": "Sun, 07 Feb 2016 18:34:41 GMT", "_etag": "86f3495cf1d6edf301e25563099844bd816c5a3c", "_id": "56b78e41cf7b35255aa5a1e6", "_links": < "self": < "href": "users/56b78e41cf7b35255aa5a1e6", "title": "User" >>, "_updated": "Sun, 07 Feb 2016 19:46:47 GMT", "active": true, "firstname": "John", "lastname": "Doe", "username": "janedoe" > ], "_links": < "parent": < "href": "/", "title": "home" >, "self": < "href": "users?sort=-username", "title": "users" >>, "_meta": < "max_results": 25, "page": 1, "total": 3 >>
Ну и наконец-то удалим всех пользователей:
$ http delete http://0.0.0.0:5000/users HTTP/1.0 204 NO CONTENT Content-Length: 0 Content-Type: application/json Date: Sun, 07 Feb 2016 20:10:06 GMT Server: Eve/0.6.1 Werkzeug/0.10.4 Python/3.5.0
Я бы не стал включать данную возможность в production. Указывается это в параметре RESOURCE_METHODS (стоит убрать из списка DELETE):
RESOURCE_METHODS = ['GET', 'POST', 'DELETE']
Заключение
Мы рассмотрели не все возможности Eve, но даже c учётом этого – получили законченный вариант REST API.
В данной статье я хотел обратить внимание на то, что настоящий RESTful сервис это гораздо больше, чем пара модулей для Node.js и в большинстве случаев нет необходимости разрабатывать такие вещи с нуля, а тем более писать статьи о том, как это сделать за один час. Достаточно взглянуть на историю развития проекта, что бы лишний раз убедиться в том, что пары часов/дней/недель недостаточно даже для хорошей команды.
Nicola Iarocci, автор Eve, создал прекрасный инструмент для быстрого развёртывания REST API, уделил этому достаточно внимания и сохранил простоту использования.
Ссылки
- Python Eve
- Презентация Python Eve
- HTTPie
- Код проекта из статьи в GitHub
P.S. Я ищу разработчиков в компанию, подробности у меня в профиле.