Статьи

Руководство для начинающих по HTTP и REST

Протокол передачи гипертекста (HTTP) — это жизнь Интернета. Он используется каждый раз, когда вы переносите документ или делаете запрос AJAX . Но HTTP удивительно относительно неизвестен среди некоторых веб-разработчиков.

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

В Envato Market также есть тысячи полезных кодовых скриптов, плагинов и приложений, которые помогут вам в веб-разработке, таких как Premium URL Shortener , PHP-скрипт, который вы можете установить на свой сервер для создания пользовательских сокращенных URL-адресов.

Премиум URL Shortener

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


REST — это простой способ организации взаимодействия между независимыми системами.

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

Альтернативой является построение относительно сложных соглашений поверх HTTP. Часто это принимает форму совершенно новых языков на основе XML. Самый яркий пример — SOAP . Вы должны изучить совершенно новый набор соглашений, но вы никогда не используете HTTP в полной мере. Поскольку REST был вдохновлен HTTP и играет на своих сильных сторонах, это лучший способ узнать, как работает HTTP.

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


HTTP — это протокол, который позволяет отправлять документы назад и вперед в Интернете.

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

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

HTTP-сообщения состоят из заголовка и тела. Тело часто может оставаться пустым; он содержит данные, которые вы хотите передать по сети, чтобы использовать их в соответствии с инструкциями в заголовке. Заголовок содержит метаданные, такие как информация о кодировании; но, в случае запроса, он также содержит важные методы HTTP. В стиле REST вы обнаружите, что данные заголовка часто более значимы, чем тело.


Если вы используете Chrome Developer Tools или Firefox с установленным расширением Firebug , щелкните панель « Net и установите для нее значение « enabled . После этого у вас будет возможность просматривать детали HTTP-запросов во время серфинга. Например:

Снимок экрана с панелью Firebug Net

Еще один полезный способ познакомиться с HTTP — использовать выделенный клиент, такой как cURL.

cURL — это инструмент командной строки , который доступен во всех основных операционных системах.

После установки cURL введите:

1
curl -v google.com

Это покажет полный HTTP-разговор. Запросам предшествует > , а ответам предшествует < .


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

1
/clients

определит всех клиентов, пока

1
/clients/jim

идентифицирует клиента по имени «Джим», предполагая, что он единственный с таким именем.

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

1
2
3
GET /clients/jim HTTP/1.1
 
Host: example.com

Ресурсы лучше всего считать существительными. Например, следующее не является RESTful:

1
/clients/add

Это потому, что он использует URL для описания действия. Это довольно фундаментальный момент для отличия RESTful от не RESTful систем.

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

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


Каждый запрос указывает определенный HTTP-глагол или метод в заголовке запроса. Это первое заглавное слово в заголовке запроса. Например,

1
GET / HTTP/1.1

означает, что метод GET используется, в то время как

1
DELETE /clients/anne HTTP/1.1

означает, что используется метод DELETE .

Глаголы HTTP говорят серверу, что делать с данными, указанными в URL.

Глаголы HTTP говорят серверу, что делать с данными, указанными в URL. Запрос может дополнительно содержать в своем теле дополнительную информацию, которая может потребоваться для выполнения операции — например, данные, которые вы хотите сохранить с ресурсом. Вы можете предоставить эти данные в cURL с опцией -d .

Если вы когда-либо создавали HTML-формы, вы знакомы с двумя наиболее важными HTTP-глаголами: GET и POST . Но есть намного больше доступных глаголов HTTP. Наиболее важными для построения RESTful API являются GET , POST , PUT и DELETE . Доступны другие методы, такие как HEAD и OPTIONS , но они встречаются реже (если вы хотите узнать обо всех других методах HTTP, официальным источником является IETF ).

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

Запрос PUT используется, когда вы хотите создать или обновить ресурс, указанный в URL. Например,

1
PUT /clients/robin

может создать клиента с именем Robin на сервере. Вы заметите, что REST полностью независим от бэкэнда; в запросе нет ничего, что информировало бы сервер о том, как должны быть созданы данные — только то, что он должен. Это позволяет вам легко менять внутреннюю технологию, если в этом возникнет необходимость. Запросы PUT содержат данные для использования при обновлении или создании ресурса в теле. В cURL вы можете добавить данные в запрос с помощью ключа -d .

1
curl -v -X PUT -d «some text»

DELETE должен выполнить противоположное PUT ; его следует использовать, когда вы хотите удалить ресурс, указанный в URL-адресе запроса.

1
curl -v -X DELETE /clients/anne

Это приведет к удалению всех данных, связанных с ресурсом, которые идентифицированы как /clients/anne .

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

Простыми словами:

1
POST /clients/

не должен вызывать изменение ресурса в /clients/ , сам по себе, но ресурс, URL которого начинается с / clients/ . Например, он может добавить нового клиента в список с id сгенерированным сервером.

1
/clients/some-unique-id

PUT запросы легко используются вместо POST запросов и наоборот. Некоторые системы используют только одну, некоторые используют POST для операций создания и PUT для операций обновления (поскольку при запросе PUT вы всегда предоставляете полный URL-адрес), некоторые даже используют POST для обновлений и PUT для создания.

Часто запросы POST используются для запуска операций на сервере, которые не вписываются в парадигму Create/Update/Delete ; но это, однако, выходит за рамки REST . В нашем примере мы будем придерживаться PUT до конца.


Безопасные и небезопасные методы:

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

Идемпотентные методы:

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

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


HTTP-клиент и HTTP-сервер обмениваются информацией о ресурсах, идентифицированных URL-адресами.

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

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

Заголовки HTTP, которые содержат метаданные, строго определены в спецификации HTTP; они могут содержать только простой текст и должны быть отформатированы определенным образом.

Тело может содержать данные в любом формате, и именно здесь мощь HTTP действительно сияет. Вы знаете, что можете отправлять простой текст, изображения, HTML и XML на любом человеческом языке. С помощью метаданных запроса или разных URL-адресов вы можете выбирать между разными представлениями для одного и того же ресурса. Например, вы можете отправить веб-страницу в браузеры и JSON для приложений.

HTTP-ответ должен указывать тип содержимого тела. Это делается в заголовке, в поле Content-Type ; например:

1
Content/Type: application/json

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


cURL чаще всего является предпочтительным HTTP-клиентом для разработчиков PHP.

Чтобы поэкспериментировать с различными методами запроса, вам нужен клиент, который позволяет вам указать, какой метод использовать. К сожалению, формы HTML не отвечают всем требованиям, так как они позволяют вам только выполнять запросы GET и POST. В реальной жизни API-интерфейсы доступны программно через отдельное клиентское приложение или через JavaScript в браузере.

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

Очень популярная клиентская библиотека HTTP, опять же, cURL. Вы уже были знакомы с командой cURL из ранее в этом руководстве. cURL включает в себя как отдельную программу командной строки, так и библиотеку, которая может использоваться различными языками программирования. В частности, cURL чаще всего является предпочтительным решением HTTP-клиента для разработчиков PHP. Другие языки, такие как Python, предлагают больше собственных клиентских библиотек HTTP.


Я хочу максимально раскрыть функциональность низкого уровня.

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

Чтобы запустить пример приложения, вам нужно установить PHP5 и веб-сервер с некоторым механизмом для запуска PHP. Текущая версия должна быть не ниже версии 5.2, чтобы иметь доступ к функциям json_encode() и json_decode() .

Что касается серверов, то наиболее распространенным выбором по-прежнему является Apache с mod_php , но вы можете свободно использовать любые альтернативы, которые вам удобны. Существует пример конфигурации Apache, которая содержит правила перезаписи, чтобы помочь вам быстро настроить приложение. Все запросы к любому URL, начиная с / clients /, должны быть направлены в наш файл server.php .

В Apache вам нужно включить mod_rewrite и поместить предоставленную конфигурацию mod_rewrite где-нибудь в вашей конфигурации Apache или в ваш файл .htacess . Таким образом, server.php будет отвечать на все запросы, поступающие с сервера. То же самое должно быть достигнуто с помощью Nginx или любого другого альтернативного сервера, который вы решите использовать.


Есть два ключа для обработки запросов способом REST. Первый ключ должен инициировать различную обработку, в зависимости от метода HTTP — даже когда URL-адреса одинаковы. В PHP есть переменная в глобальном массиве $ _SERVER , которая определяет, какой метод был использован для выполнения запроса:

1
$_SERVER[‘REQUEST_METHOD’]

Эта переменная содержит имя метода в виде строки, например, « GET », « PUT » и т. Д.

Другой ключ должен знать, какой URL был запрошен. Для этого мы используем другую стандартную переменную PHP:

1
$_SERVER[‘REQUEST_URI’]

Эта переменная содержит URL, начиная с первой косой черты. Например, если имя хоста « example.com », « http://example.com/ » вернет « / », а « http://example.com/test/ » вернет « /test/ » ,

Давайте сначала попробуем определить, какой URL был вызван. Мы рассматриваем только URL-адреса, начинающиеся с « clients ». Все остальные недействительны.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
$resource = array_shift($paths);
 
if ($resource == ‘clients’) {
    $name = array_shift($paths);
 
    if (empty($name)) {
        $this->handle_base($method);
    } else {
        $this->handle_name($method, $name);
    }
 
} else {
    // We only handle resources under ‘clients’
    header(‘HTTP/1.1 404 Not Found’);
}

У нас есть два возможных результата:

  • Ресурс — это клиенты, в этом случае мы возвращаем полный листинг
  • Есть еще один идентификатор

Если есть еще один идентификатор, мы предполагаем, что это имя клиента, и, опять же, перенаправляем его в другую функцию, в зависимости от method . Мы используем оператор switch , которого следует избегать в реальном приложении:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
switch($method) {
 case ‘PUT’:
     $this->create_contact($name);
     break;
 
 case ‘DELETE’:
     $this->delete_contact($name);
     break;
 
 case ‘GET’:
     $this->display_contact($name);
     break;
 
 default:
     header(‘HTTP/1.1 405 Method Not Allowed’);
     header(‘Allow: GET, PUT, DELETE’);
     break;
 }

Коды ответа HTTP стандартизируют способ информирования клиента о результате его запроса.

Вы могли заметить, что пример приложения использует PHP header() , передавая несколько странно выглядящих строк в качестве аргументов. Функция header () печатает headers HTTP и обеспечивает их правильное форматирование. Заголовки должны быть первыми в ответе, поэтому вы не должны выводить что-либо еще, прежде чем закончите с заголовками. Иногда ваш HTTP-сервер может быть настроен на добавление других заголовков, помимо тех, которые вы указали в своем коде.

Заголовки содержат все виды метаинформации; например, кодировка текста, используемая в теле сообщения, или MIME-тип содержимого тела. В этом случае мы явно указываем коды ответов HTTP. Коды ответа HTTP стандартизируют способ информирования клиента о результате его запроса. По умолчанию PHP возвращает код ответа 200 , что означает, что ответ успешен.

Сервер должен вернуть наиболее подходящий код ответа HTTP; таким образом, клиент может попытаться исправить свои ошибки, предполагая, что они есть. Большинство людей знакомы с общим кодом ответа 404 Not Found , однако существует гораздо больше доступных для решения самых разных ситуаций.

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

Вот некоторые коды ответов HTTP, которые часто используются с REST:

Этот код ответа указывает, что запрос был успешным.

Это указывает на то, что запрос был успешным и ресурс был создан. Он используется для подтверждения успеха запроса PUT или POST .

Запрос был искажен. Это особенно касается запросов POST и PUT , когда данные не проходят проверку или имеют неправильный формат.

Этот ответ указывает, что требуемый ресурс не может быть найден. Обычно это возвращается всем запросам, которые указывают на URL без соответствующего ресурса.

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

Используемый метод HTTP не поддерживается для этого ресурса.

Это указывает на конфликт. Например, вы используете запрос PUT для создания одного и того же ресурса дважды.

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


Давайте начнем с простого извлечения информации из приложения. Нам нужны подробности о клиенте ‘ jim ‘, поэтому давайте отправим простой GET на URL этого ресурса:

1
curl -v http://localhost:80/clients/jim

Это отобразит полные заголовки сообщений. Последняя строка в ответе будет телом сообщения; в этом случае это будет JSON, содержащий адрес Джима (помните, что пропуск имени метода приведет к GET запросу; также замените localhost:80 на имя сервера и порт, который вы используете).

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

1
curl -v http://localhost:80/clients/

Чтобы создать нового клиента по имени Пол …

1
curl -v -X PUT http://localhost:80/clients/paul -d ‘{«address»:»Sunset Boulevard» }

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

Наконец, чтобы удалить клиента:

1
curl -v -X DELETE http://localhost:80/clients/anne

Вы обнаружите, что возвращенный JSON больше не содержит никаких данных об Анне.

Если вы попытаетесь получить несуществующий клиент, например:

1
curl -v http://localhost:80/clients/jerry

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

curl -v -X PUT http: // localhost: 80 / clients / anne

Вместо этого вы получите ошибку 409.


В общем, чем меньше допущений помимо HTTP вы делаете, тем лучше.

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

Я использовал PHP в этом уроке, потому что это, скорее всего, язык, наиболее знакомый читателям Nettuts +. Тем не менее, PHP, хотя и предназначен для Интернета, вероятно, не лучший язык для использования при работе в режиме REST, поскольку он обрабатывает запросы PUT совершенно иначе, чем GET и POST .

Помимо PHP, вы можете рассмотреть следующее:

  • Различные фреймворки Ruby ( Rails и Sinatra )
  • В Python есть отличная поддержка REST. Обычный Django и WebOb , или Werkzeug должны работать
  • node.js имеет отличную поддержку REST

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

И не забудьте проверить выбор скриптов кода, плагинов и приложений на Envato Market.

Веселиться!

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