Отправить put запрос в браузере
Мечта, ради которой создавалась Сеть – это общее информационное пространство, в котором мы общаемся, делясь информацией. Его универсальность является его неотъемлемой частью: ссылка в гипертексте может вести куда угодно, будь то персональная, локальная или глобальная информация, черновик или выверенный текст.
Тим Бернес-Ли, Всемирная паутина: Очень короткая личная история
Протокол
Сервер отвечает по тому же соединению:
Браузер берёт ту часть, что идёт за ответом после пустой строки и показывает её в виде HTML-документа.
Информация, отправленная клиентом, называется запросом. Он начинается со строки:
Первое слово – метод запроса. GET означает, что нам нужно получить определённый ресурс. Другие распространённые методы – DELETE для удаления, PUT для замещения и POST для отправки информации. Заметьте, что сервер не обязан выполнять каждый полученный запрос. Если вы выберете случайный сайт и скажете ему DELETE главную страницу – он, скорее всего, откажется.
Ответ сервера также начинается с версии протокола, за которой идёт статус ответа – сначала код из трёх цифр, затем строчка.
За первой строкой запроса или ответа может идти любое число строк заголовка. Это строки в виде “имя: значение”, которые обозначают дополнительную информацию о запросе или ответе. Эти заголовки были включены в пример:
Content-Length: 65585
Content-Type: text/html
Last-Modified: Wed, 09 Apr 2014 10:48:09 GMT
Тут определяется размер и тип документа, полученного в ответ. В данном случае это HTML-документ размером 65’585 байт. Также тут указано, когда документ был изменён последний раз.
По большей части клиент или сервер определяют, какие заголовки необходимо включать в запрос или ответ, хотя некоторые заголовки обязательны. К примеру, Host, обозначающий имя хоста, должен быть включён в запрос, потому что один сервер может обслуживать много имён хостов на одном ip-адресе, и без этого заголовка сервер не узнает, с каким хостом клиент пытается общаться.
Как мы видели в примере, браузер отправляет запрос, когда мы вводим URL в адресную строку. Когда в полученном HTML документе содержатся упоминания других файлов, такие, как картинки или файлы JavaScript, они тоже запрашиваются с сервера.
Веб-сайт средней руки легко может содержать от 10 до 200 ресурсов. Чтобы иметь возможность запросить их побыстрее, браузеры делают несколько запросов одновременно, а не ждут окончания запросов одного за другим. Такие документы всегда запрашиваются через запросы GET.
На страницах HTML могут быть формы, которые позволяют пользователям вписывать информацию и отправлять её на сервер. Вот пример формы:
Начало строки запроса обозначено знаком вопроса. После этого идут пары имён и значений, соответствующие атрибуту name полей формы и содержимому этих полей. Амперсанд (&) используется для их разделения.
В следующей главе мы вернёмся к формам и поговорим про то, как мы можем делать их при помощи JavaScript.
И всё же имя не полностью бессмысленное. Интерфейс позволяет разбирать вам ответы, как если бы это были документы XML. Смешивать две разные вещи (запрос и разбор ответа) в одну – это, конечно, отвратительный дизайн, но что поделаешь.
Отправка запроса
Можно получить из объекта response и другую информацию. Код статуса доступен в свойстве status, а текст статуса – в statusText. Заголовки можно прочесть из getResponseHeader.
Названия заголовков не чувствительны к регистру. Они обычно пишутся с заглавной буквы в начале каждого слова, например “Content-Type”, но “content-type” или “cOnTeNt-TyPe” будут описывать один и тот же заголовок.
Браузер сам добавит некоторые заголовки, такие, как “Host” и другие, которые нужны серверу, чтобы вычислить размер тела. Но вы можете добавлять свои собственные заголовки методом setRequestHeader. Это нужно для особых случаев и требует содействия сервера, к которому вы обращаетесь – он волен игнорировать заголовки, которые он не умеет обрабатывать.
Асинхронные запросы
В примере запрос был окончен, когда заканчивается вызов send. Это удобно потому, что свойства вроде responseText становятся доступными сразу. Но это значит, что программа наша будет ожидать, пока браузер и сервер общаются меж собой. При плохой связи, слабом сервере или большом файле это может занять длительное время. Это плохо ещё и потому, что никакие обработчики событий не сработают, пока программа находится в режиме ожидания – документ перестанет реагировать на действия пользователя.
Если третьим аргументом open мы передадим true, запрос будет асинхронным. Это значит, что при вызове send запрос ставится в очередь на отправку. Программа продолжает работать, а браузер позаботиться об отправке и получении данных в фоне.
Но пока запрос обрабатывается, мы не получим ответ. Нам нужен механизм оповещения о том, что данные поступили и готовы. Для этого нам нужно будет слушать событие “load”.
Так же, как вызов requestAnimationFrame в главе 15, этот код вынуждает нас использовать асинхронный стиль программирования, оборачивая в функцию тот код, который должен быть выполнен после запроса, и устраивая вызов этой функции в нужное время. Мы вернёмся к этому позже.
Получение данных XML
Мы можем получить такой файл следующим образом:
Документы XML можно использовать для обмена с сервером структурированной информацией. Их форма – вложенные теги – хорошо подходит для хранения большинства данных, ну или по крайней мере лучше, чем текстовые файлы. Интерфейс DOM неуклюж в плане извлечения информации, и XML документы получаются довольно многословными. Обычно лучше общаться при помощи данных в формате JSON, которые проще читать и писать – как программам, так и людям.
Это может мешать разработке систем, которым надо иметь доступ к разным доменам по уважительной причине. К счастью, сервер может включать в ответ следующий заголовок, поясняя браузерам, что запрос может прийти с других доменов:
Абстрагируем запросы
В главе 10 в нашей реализации модульной системы AMD мы использовали гипотетическую функцию backgroundReadFile. Она принимала имя файла и функцию, и вызывала эту функцию после прочтения содержимого файла. Вот простая реализация этой функции:
Аргумент callback (обратный вызов) – термин, часто использующийся для описания подобных функций. Функция обратного вызова передаётся в другой код, чтобы он мог позвать нас обратно позже.
Основная проблема с приведённой обёрткой – обработка ошибок. Когда запрос возвращает код статуса, обозначающий ошибку (от 400 и выше), он ничего не делает. В некоторых случаях это нормально, но представьте, что мы поставили индикатор загрузки на странице, показывающий, что мы получаем информацию. Если запрос не удался, потому что сервер упал или соединение прервано, страница будет делать вид, что она чем-то занята. Пользователь подождёт немного, потом ему надоест и он решит, что сайт какой-то дурацкий.
Обработка ошибок в асинхронном коде ещё сложнее, чем в синхронном. Поскольку нам часто приходится отделять часть работы и размещать её в функции обратного вызова, область видимости блока try теряет смысл. В следующем коде исключение не будет поймано, потому что вызов backgroundReadFile возвращается сразу же. Затем управление уходит из блока try, и функция из него не будет вызвана.
Чтобы обрабатывать неудачные запросы, придётся передавать дополнительную функцию в нашу обёртку, и вызывать её в случае проблем. Другой вариант – использовать соглашение, что если запрос не удался, то в функцию обратного вызова передаётся дополнительный аргумент с описанием проблемы. Пример:
Мы добавили обработчик события error, который сработает при проблеме с вызовом. Также мы вызываем функцию обратного вызова с аргументом error, когда запрос завершается со статусом, говорящим об ошибке.
Код, использующий getURL, должен проверять не возвращена ли ошибка, и обрабатывать её, если она есть.
С исключениями это не помогает. Когда мы совершаем последовательно несколько асинхронных действий, исключение в любой точке цепочки в любом случае (если только вы не обернули каждый обработчик в свой блок try/catch) вывалится на верхнем уровне и прервёт всю цепочку.
Обещания
Тяжело писать асинхронный код для сложных проектов в виде простых обратных вызовов. Очень легко забыть проверку на ошибку или позволить неожиданному исключению резко прервать программу. Кроме того, организация правильной обработки ошибок и проход ошибки через несколько последовательных обратных вызовов очень утомительна.
Предпринималось множество попыток решить эту проблему дополнительными абстракциями. Одна из наиболее удачных попыток называется обещаниями (promises). Обещания оборачивают асинхронное действие в объект, который может передаваться и которому нужно сделать какие-то вещи, когда действие завершается или не удаётся. Такой интерфейс уже стал частью текущей версии JavaScript, а для старых версий его можно использовать в виде библиотеки.
Для создания объекта promises мы вызываем конструктор Promise, задавая ему функцию инициализации асинхронного действия. Конструктор вызывает эту функцию и передаёт ей два аргумента, которые сами также являются функциями. Первая должна вызываться в удачном случае, другая – в неудачном.
И вот наша обёртка для запросов GET, которая на этот раз возвращает обещание. Теперь мы просто назовём его get.
Заметьте, что интерфейс к самой функции упростился. Мы передаём ей URL, а она возвращает обещание. Оно работает как обработчик для выходных данных запроса. У него есть метод then, который вызывается с двумя функциями: одной для обработки успеха, другой – для неудачи.
Пока это всё ещё один из способов выразить то же, что мы уже сделали. Только когда у вас появляется цепь событий, становится видна заметная разница.
Вызов then производит новое обещание, чей результат (значение, передающееся в обработчики успешных результатов) зависит от значения, возвращаемого первой переданной нами в then функцией. Эта функция может вернуть ещё одно обещание, обозначая что проводится дополнительная асинхронная работа. В этом случае обещание, возвращаемое then само по себе будет ждать обещания, возвращённого функцией-обработчиком, и успех или неудача произойдут с таким же значением. Когда функция-обработчик возвращает значение, не являющееся обещанием, обещание, возвращаемое then, становится успешным, в качестве результата используя это значение.
Значит, вы можете использовать then для изменения результата обещания. К примеру, следующая функция возвращает обещание, чей результат – содержимое с данного URL, разобранное как JSON:
Последний вызов then не обозначил обработчик неудач. Это допустимо. Ошибка будет передана в обещание, возвращаемое через then, а ведь это нам и надо – getJSON не знает, что делать, когда что-то идёт не так, но есть надежда, что вызывающий её код это знает.
В качестве примера, показывающего использование обещаний, мы напишем программу, получающую число JSON-файлов с сервера, и показывающую во время исполнения запроса слово «загрузка». Файлы содержат информацию о людях и ссылки на другие файлы с информацией о других людях в свойствах типа отец, мать, супруг.
Можно представлять себе, что интерфейс обещаний – это отдельный язык для асинхронной обработки исполнения программы. Дополнительные вызовы методов и функций, которые нужны для его работы, придают коду несколько странный вид, но не настолько неудобный, как обработка всех ошибок вручную.
При создании системы, в которой программа на JavaScript в браузере (клиентская) общается с серверной программой, можно использовать несколько вариантов моделирования такого общения.
Общепринятый метод – удалённые вызовы процедур. В этой модели общение идёт по шаблону обычных вызовов функций, только функции эти выполняются на другом компьютере. Вызов заключается в создании запроса на сервер, в который входят имя функции и аргументы. Ответ на запрос включает возвращаемое значение.
Данные путешествуют по интернету по длинному и опасному пути. Чтобы добраться до пункта назначения, им надо попрыгать через всякие места, начиная от Wi-Fi сети кофейни до сетей, контролируемых разными организациями и государствами. В любой точке пути их могут прочитать или даже поменять.
Упражнения
Согласование содержания (content negotiation)
Наконец, попробуйте запросить содержимое типа application/rainbows+unicorns и посмотрите, что произойдёт.
Ожидание нескольких обещаний
У конструктора Promise есть метод all, который, получая массив обещаний, возвращает обещание, которое ждёт завершения всех указанных в массиве обещаний. Затем он выдаёт успешный результат и возвращает массив с результатами. Если какие-то из обещаний в массиве завершились неудачно, общее обещание также возвращает неудачу (со значением неудавшегося обещания из массива).
Попробуйте сделать что-либо подобное, написав функцию all.
Заметьте, что после завершения обещания (когда оно либо завершилось успешно, либо с ошибкой), оно не может заново выдать ошибку или успех, и дальнейшие вызовы функции игнорируются. Это может упростить обработку ошибок в вашем обещании.
Is there any functionality in Chrome and/or Firefox that I'm missing?
Whilst an add on is necessary, the close is niitpicking nonsense. He was asking for functionality in chrome or firefox , or iif it needs a plugin. That it might require a specifed or unspecified plugin is not the point
The post is closed incorrectly. It does not ask for a tool, but for a functionality in the tools the author already is working with. This way we have to close all questions about how to do this or that on some tool - and it will be a good on-tenth of SO.
I noticed this feature on Firefox when you open the network tab and choose a random request you can Edit and Resend it which is pretty cool.
17 Answers 17
I have been making a Chrome app called Postman for this type of stuff. All the other extensions seemed a bit dated so made my own. It also has a bunch of other features which have been helpful for documenting our own API here.
Postman now also has native apps (i.e. standalone) for Windows, Mac and Linux! It is more preferable now to use native apps, read more here.
Tool might be useful, but a 3rd party app doesn't answer the question, which asks for doing this through Chrome or Firefox.
CURL is awesome to do what you want! It's a simple, but effective, command line tool.
REST implementation test commands:
I'm upvoting this even though it's a wrong answer to the question: it's what I needed to know instead.
This doesn't work for me, I can't use single quotes on OSX with zsh and bash, shell is turning into quote> mode. I need to use -d "
Yeah, curl is awesome, you almost always already have it on Unix, and it's really lightweight for Windows. No registration or SMS! ;)
Windows cmd.exe also doesn't like the single quotes, so for my POST I used: curl -i -X POST -H "Content-Type: application/json" -d "" localhost:60524 \"name\":>
Firefox
Open Network panel in Developer Tools by pressing Ctrl+Shift+E or by going Menubar -> Tools -> Web Developer -> Network. Then Click on small door icon on top-right (in expanded form in the screenshot, you'll find it just left of the highlighted Headers), second row (if you don't see it then reload the page) -> Edit and resend whatever request you want
Is this feature broken for anyone else? When editing the parameters in the "Query String" box, after altering a single character, it refuses to alter the request any further. The only way to do it beyond that is to edit the entire URL/request (which is difficult because it's all smooshed together)
@Coldblackice Can you post a screenshot or problem steps recorder please? I can edit query string just fine. To add a new query string, I either use &= or just start a new line. To edit, change individual k,v or I just delete and start over.
@dima-lituiev, The screenshots above are for Firefox and I've confirmed it works in firefox version 88.0.1
I've also confirmed it works in Firefox 88.0.1 - However, in my case, the "Edit and Resend" button is not showing up. I have to right-click on the request then click "Open in Network Panel". From there, I am able to click the "Resend" dropdown in the upper right and select "Edit and Resend". Kudos to this solution going strong years later. You even have an option for it to create a fetch() command for the request to use in the console like OP was initially requesting.
If you insist on a browser extension then:
Chrome:
Firefox:
@akostadinov i am unable to use resource test addon in mozilla the tool does not appear (even after installaion and restart) to me under developer tools in the lastest version of firefox.
Just tried REST Easy. Uninstalled on the spot: the interface does way too much hand-holding and forces the user into rigid use cases. Not good for API development.
Having been greatly inspired by Postman for Chrome, I decided to write something similar for Firefox.
REST Easy* is a restartless Firefox add-on that aims to provide as much control as possible over requests. The add-on is still in an experimental state (it hasn't even been reviewed by Mozilla yet) but development is progressing nicely.
Seems nice, but lacks the ability to control the request body fully. Currently, it offers key/value abilities, but full control of the post body would be nice.
@Pacerier: it's a feature I'm currently working on and am about 90% complete. Hopefully it will be released before the end of the year. There does seem to be a backlog getting addons approved by Mozilla.
After over a month of waiting, the new version has been approved. PUT and DELETE support has arrived! And in that month, I've also made a ton of other new changes that will show up soon in the next release. (Hopefully it gets approved sooner this time.)
You specifically asked for "extension or functionality in Chrome and/or Firefox", which the answers you have already received provide, but I do like the simplicity of oezi's answer to the closed question "How can I send a POST request with a web browser?" for simple parameters. oezi says:
With a form, just set method to "post"
I.e., build yourself a very simple page to test the POST actions.
I will add, for the ones that don't know: what you specify as action is the resource you want to get (which can include GET-style query parameters), and value specifies the POST's data body. E.g. action="api/ids?name=John" and value="hello" will make a POST request to
Here's the Advanced REST Client extension for Chrome.
It works great for me -- do remember that you can still use the debugger with it. The Network pane is particularly useful; it'll give you rendered JSON objects and error pages.
For Firefox there is also an extension called RESTClient which is quite nice:
Some of the advantages of the fetch command are really precious: It's simple, short, fast, available and even as a console command it stored on your chrome console and can be used later.
The simplicity of pressing F12 , write the command in the console tab (or press the up key if you used it before) then press Enter , see it pending and returning the response is what making it really useful for simple POST requests tests.
Of course, the main disadvantage here is that, unlike Postman, this won't pass the cross-origin-policy, but still I find it very useful for testing in local environment or other environments where I can enable CORS manually.
Я хотел бы знать, что окончательный (?) ответ заключается в том, как делать другие вещи, а затем публиковать/получать из браузера - либо HTML-форму, либо Ajax, поскольку я слышу смешанные отчеты о том, какие браузеры позволяют что (в частности, на стороне ajax).
при построении задней части в стиле RESTful приятно использовать правильные глаголы, такие как PUT, HEAD, OPTIONS и т. д. в rails скрытое поле формы называется метод (IIRC?) используется для имитации этого, а на заднем конце отправка в соответствующий контроллер для глагола. Это сейчас (в конце 2009 года) нужна? какие условности?
похоже, что большинство браузеров не поддерживают другие методы, кроме GET и POST, поскольку это ограничение HTML-форм. Вот еще один вопрос на эту тему:
для имитации PUT, DELETE и т. д. методы, вы можете добавить скрытый ввод в обычную форму GET / POST с помощью псевдо-метода и заставить ваше приложение перевести его так, чтобы ваши контроллеры видели его, как если бы он как вы упомянули, это была настоящая просьба. Я видел этот метод, используемый в Google sitebricks (в java - извините, у меня нет ссылки на rails, но это может по крайней мере дать вам представление) в этот код. Я думаю, что это, вероятно, метод, с которым мы застряли, пока что-то в спецификации HTML не изменится (и браузеры с ним)
однако GET, POST, PUT и DELETE поддерживаются в AJAX основными браузерами, поэтому не должно быть необходимости в скрытом вводе, если вы не опираясь на HTML-форму.
HTTP имеет 4 GET, POST, PUT, UPDATE. Но большинство браузеров поддерживают только GET и POST. PUT и UPDATE моделируются путем отправки дополнительных параметров в запросе. В rails это _method= "PUT"или _method="UPDATE".
например,Амайя веб-браузер позволяет редактировать документы в интернете и сохранять их непосредственно на сервере, используя PUT метод. Есть плагины для этого в других браузерах и несколько веб-графических редакторов, таких как Dreamweaver также поддерживает WebDAV.
это то, что беспокоило меня некоторое время.. Я создаю RESTful API, который должен получать файлы в некоторых случаях.
вот как я в настоящее время читаю данные по запросу PUT:
(который отлично работает, пока нет файлов, опубликованных)
когда я затем вывожу rawData, он показывает
Я пробовал только вышеуказанный метод, на самом деле не имею понятия о том, что я могу сделать еще.
Я не получил никаких ошибок с помощью этого метода, кроме того, что я не получаю желаемый результат опубликованных данных и файлов.
===== решение =====
теперь я переместил передачу formdata из тела в строку запроса url. Тело теперь содержит содержимое одного файла.
дополнительные информация, прочитал ответ Даверандома. Это эпично.
по сути, я говорю, что это не ваш код для получения файл, который неверен, это код, который делает запрос-код клиента неверен, а не код, который вы показываете здесь (хотя parse_str() call-бессмысленное упражнение).
если вы объясните, что такое клиент (браузер, скрипт на другом сервере и т. д.), Я могу помочь вам сделать это дальше. Как бы то ни было, соответствующий метод запроса для тела запроса, которое вы изображаете, - это POST, а не PUT.
история
переходите уже к делу
URI-это расположение на сервере запрашиваемого нами ресурса. В общем, это состоит из путь компонент, и дополнительно строку запроса. Есть обстоятельства там, где могут присутствовать и другие компоненты, но для простоты мы пока их проигнорируем.
запрос URI разбивается на две части-все слева вопросительного знака ? - это путь, все справа от него-это строку запроса.
Методы Запроса
метод OPTIONS редко используется. Он предназначен как механизм для определения того, какую функциональность поддерживает сервер, прежде чем пытаться использовать сервис, который может предоставить сервер.
это, безусловно, самый распространенный метод в повседневном использовании. Каждый раз, когда вы загружаете обычный документ в свой веб-браузер, это будет запрос GET.
метод GET запрашивает, чтобы сервер вернул определенный документ. Единственные данные, которые должны быть переданы на сервер, - это информация, необходимая серверу для определения документ должен быть возвращен. Это может включать информацию, которую сервер может использовать для динамического создания документа, который отправляется в виде заголовков и / или строки запроса в URI запроса. Пока мы находимся в теме-Cookies отправляются в заголовках запроса.
этот метод идентичен методу GET, с одним отличием-сервер не будет возвращать запрошенный документ, если будет возвращать только заголовки, которые будут включены в ответ. Это полезно для определения, например, если конкретный документ существует без необходимости передачи и обработки всего документа.
это второй наиболее часто используемый метод, и, пожалуй, самый сложный. Запросы метода POST почти исключительно используются для вызова некоторых действий на сервере, которые могут изменить его состояние.
многие HTML-формы используют метод POST. Чтобы загрузить файлы из браузера, вам нужно будет использовать метод POST для вашей формы.
метод POST семантически несовместим с RESTful APIs, потому что он не идемпотентных. То есть второй идентичный запрос POST может привести к дальнейшему изменению состояния сервера. Это противоречит "" ограничение отдыха без гражданства.
это непосредственно дополняет GET. Если запрос GET указывает, что сервер должен вернуть документ в расположение, указанное URI запроса в теле ответа, метод PUT указывает, что сервер должен хранить данные в теле запроса по адресу расположение, указанное URI запроса.
вот решение, которое я нашел наиболее полезным.
$put = array(); parse_str(file_get_contents('php://input'), $put);
просто следуйте тому, что он говорит в DOC:
этой должны прочитайте весь файл, который находится в потоке PUT и сохраните его локально, тогда вы можете делать с ним все, что хотите.
используйте POST и включите X - заголовок, чтобы указать фактический метод (в этом случае). Обычно так работает брандмауэр, который не позволяет использовать другие методы, кроме GET и POST. Просто объявите PHP багги (так как он отказывается обрабатывать многопартийные PUT полезные нагрузки, это багги) и относитесь к нему, как к устаревшему/драконовскому брандмауэру.
Эта статья — одна из обещанных коротких заметок по ходу цикла статей Автоматизация Для Самых Маленьких.
Поскольку основным способом взаимодействия с IPAM-системой будет RESTful API, я решил рассказать о нём отдельно.
Воздаю хвалы архитекторам современного мира — у нас есть стандартизированные интерфейсы. Да их много — это минус, но они есть — это плюс.
Эти интерфейсы взаимодействия обрели имя API — Application Programming Interface.
Одним из таких интерфейсов является RESTful API, который и используется для работы с NetBox.
Если очень просто, то API даёт клиенту набор инструментов, через которые тот может управлять сервером. А клиентом может выступать по сути что угодно: веб-браузер, командная консоль, разработанное производителем приложение, или вообще любое другое приложение, у которого есть доступ к API.
Например, в случае NetBox, добавить новое устройство в него можно следующими способами: через веб-браузер, отправив curl'ом запрос в консоли, использовать Postman, обратиться к библиотеке requests в питоне, воспользоваться SDK pynetbox или перейти в Swagger.
Таким образом, один раз написав единый интерфейс, производитель навсегда освобождает себя от необходимости с каждым новым клиентом договариваться как его подключать (хотя, это самую малость лукавство).
Ниже я дам очень упрощённое описание того, что такое REST.
Начнём с того, что RESTful API — это именно интерфейс взаимодействия, основанный на REST, в то время как сам REST (REpresentational State Transfer) — это набор ограничений, используемых для создания WEB-сервисов.
О каких именно ограничениях идёт речь, можно почитать в главе 5 диссертации Роя Филдинга Architectural Styles and the Design of Network-based Software Architectures. Мне же позвольте привести только три наиболее значимых (с моей точки зрения) из них:
- В REST-архитектуре используется модель взаимодействия Клиент-Сервер.
- Каждый REST-запрос содержит всю информацию, необходимую для его выполнения. То есть сервер не должен помнить ничего о предыдущих запросах клиента, что, как известно, характеризуется словом Stateless — не храним информацию о состоянии.
- Единый интерфейс. Реализация приложения отделена от сервиса, который оно предоставляет. То есть пользователь знает, что оно делает и как с ним взаимодействовать, но как именно оно это делает не имеет значения. При изменении приложения, интерфейс остаётся прежним, и клиентам не нужно подстраиваться.
А API, который предоставляют RESTful WEB-сервисы, называется RESTful API.
Адрес назначения (или иным словом — объект, или ещё иным — эндпоинт) — это привычный нам URI.
Формат передаваемых данных — XML или JSON.
На чтение права не требуются, но если хочется попробовать читать с токеном, то можно воспользоваться этим: API Token: 90a22967d0bc4bdcd8ca47ec490bbf0b0cb2d9c8.
Давайте интереса ради сделаем один запрос:
Или чуть более академически: GET возвращает типизированный объект devices, являющийся параметром объекта DCIM.
Этот запрос можете выполнить и вы — просто скопируйте себе в терминал.
URL, к которому мы обращаемся в запросе, называется Endpoint. В некотором смысле это конечный объект, с которым мы будем взаимодействовать.
Например, в случае netbox'а список всех endpoint'ов можно получить тут.
Вот что мы получим в ответ:
Это JSON (как мы и просили), описывающий device с ID 1: как называется, с какой ролью, какой модели, где стоит итд.
Так будет выглядеть ответ:
А теперь разберёмся, что же мы натворили.
Стартовая строка
Заголовки
В них указано, что
В них указано, что
- Тип сервера: nginx на Ubuntu,
- Время формирования ответа,
- Формат данных в ответе: JSON
- Длина данных в ответе: 1638 байтов
- Соединение не нужно закрывать — ещё будут данные.
Тело используется для передачи собственно данных.
Между заголовками и телом должна быть как минимум одна пустая строка.
А вот например, при POST уже и в запросе будет тело. Давайте о методах и поговорим теперь.
Давайте на примере NetBox разберёмся с каждым из них.
Это метод для получения информации.
Так, например, мы забираем список устройств:
Метод GET безопасный (safe), поскольку не меняет данные, а только запрашивает.
Он идемпотентный с той точки зрения, что один и тот же запрос всегда возвращает одинаковый результат (до тех пор, пока сами данные не поменялись).
Тело возвращается в формате JSON или XML.
Давайте ещё пару примеров. Теперь мы запросим информацию по конкретному устройству по его имени.
Если нужно задать пару условий, то запрос будет выглядеть так:
Здесь мы запросили все устройства с ролью leaf, расположенные на сайте mlg.
То есть два условия отделяются друг от друга знаком "&".
Из любопытного и приятного — если через "&" задать два условия с одним именем, то между ними будет на самом деле не логическое «И», а логическое «ИЛИ».
То есть вот такой запрос и в самом деле вернёт два объекта: mlg-leaf-0 и mlg-spine-0
Попробуем обратиться к несуществующему URL.
POST используется для создания нового объекта в наборе объектов. Или более сложным языком: для создания нового подчинённого ресурса.
То есть, если есть набор devices, то POST позволяет создать новый объект device внутри devices.
Выберем тот же Endpoint и с помощью POST создадим новое устройство.
Здесь уже появляется заголовок Authorization, содержащий токен, который авторизует запрос на запись, а после директивы -d расположен JSON с параметрами создаваемого устройства:
Теперь новым запросом с методом GET можно его увидеть в выдаче:
POST, очевидно, не является ни безопасным, ни идемпотентным — он наверняка меняет данные, и дважды выполненный запрос приведёт или к созданию второго такого же объекта, или к ошибке.
Это метод для изменения существующего объекта. Endpoint для PUT выглядит иначе, чем для POST — в нём теперь содержится конкретный объект.
PUT может возвращать коды 201 или 200.
Важный момент с этим методом: нужно передавать все обязательные атрибуты, поскольку PUT замещает собой старый объект.
Поэтому, если например, просто попытаться добавить атрибут asset_tag нашему новому устройству, то получим ошибку:
Но если добавить недостающие поля, то всё сработает:
Этот метод используется для частичного изменения ресурса.
WAT? Спросите вы, а как же PUT?
PUT — изначально существовавший в стандарте метод, предполагающий полную замену изменяемого объекта. Соответственно в методе PUT, как я и писал выше, придётся указать даже те атрибуты объекта, которые не меняются.
А PATCH был добавлен позже и позволяет указать только те атрибуты, которые действительно меняются.
Здесь также в URL указан ID устройства, но для изменения только один атрибут serial.
Очевидно, удаляет объект.
Метод DELETE идемпотентен с той точки зрения, что повторно выполненный запрос уже ничего не меняет в списке ресурсов (но вернёт код 404 (NOT FOUND).
Curl — это, конечно, очень удобно для доблестных воинов CLI, но есть инструменты получше.
Postman
Postman позволяет в графическом интерфейсе формировать запросы, выбирая методы, заголовки, тело, и отображает результат в удобочитаемом виде.
Кроме того запросы и URI можно сохранять и возвращаться к ним позже.
Так мы можем сделать GET:
Здесь указан Token в GET только для примера.
Postman служит только для работы с RESTful API.
Один из приятных бонусов специфицированного API в том, что вы можете в Postman импортировать все эндпоинты и их методы как коллекцию.
Далее, всё, что только можно, вы найдёте в коллекциях.
Python+requests
Но даже через Postman вы, скорее всего, не будете управлять своими Production-системами. Наверняка, у вас будут внешние приложения, которые захотят без вашего участия взаимодействовать с ними.
Снова добавим новое устройство:
Python+NetBox SDK
В случае NetBox есть также Python SDK — Pynetbox, который представляет все Endpoint'ы NetBox в виде объекта и его атрибутов, делая за вас всю грязную работу по формированию URI и парсингу ответа, хотя и не бесплатно, конечно.
Например, сделаем то же, что и выше, использую pynetbox.
Список всех устройств:
Добавить новое устройство:
SWAGGER
За что ещё стоит поблагодарить ушедшее десятилетие, так это за спецификации API. Если вы перейдёте по этому пути, то попадёте в Swagger UI — документацию по API Netbox.
На этой странице перечислены все Endpoint'ы, методы работы с ними, возможные параметры и атрибуты и указано, какие из них обязательны. Кроме того описаны ожидаемые ответы.
На этой же странице можно выполнять интерактивные запросы, кликнув на Try it out.
По какой-от причине swagger в качестве Base URL берёт имя сервера без порта, поэтому функция Try it out не работает в моих примерах со Swagger'ом. Но вы можете попробовать это на собственной инсталляции.
При нажатии на Execute Swagger UI сформирует строку curl, с помощью которой можно аналогичный запрос сделать из командной строки.
В Swagger UI можно даже создать объект:
Для этого достаточно быть авторизованным пользователем, обладающим нужными правами.
То, что мы видим на этой странице — это Swagger UI — документация, сгенерированная на основе спецификации API.
С трендами на микросервисную архитектуру всё более важным становится иметь стандартизированный API для взаимодействия между компонентами, эндпоинты и методы которого легко определить как человеку, так и приложению, не роясь в исходном коде или PDF-документации.
Поэтому разработчики сегодня всё чаще следуют парадигме API First, когда сначала задумываются об API, а уже потом о реализации.
В этом дизайне сначала специфицируется API, а затем из него генерируются документация, клиентское приложение, серверная часть и необходимы тесты.
Swagger — это фреймворк и язык спецификации (который ныне переименован в OpenAPI 2.0), позволяющие реализовать эту задачу.
Углубляться в него я не буду.
За бо́льшими деталями сюда:
Существует и такая, да. Не всё в том мире 2000-го года так уже радужно.
Не являясь экспертом, не берусь предметно раскрывать вопрос, но дам ссылку на небесспорную статью на Хабре.
Альтернативным интерфейсом взаимодействия компонентов системы сегодня является gRPC. Ему же пророчат большое будущее на ниве новых подходов к работе с сетевым оборудованием. Но о нём мы поговорим когда-то в будущем, когда придёт его черёд.
Можно также взглянуть на многообещающий GraphQL, но нам опять же нет нужды с ним работать пока, поэтому остаётся на самостоятельное изучение.
Важно
Токен a9aae70d65c928a554f9a038b9d4703a1583594f был использован только в демонстрационных целях и больше не работает.
Прямое указание токенов в коде программы недопустимо и сделано здесь мной только в интересах упрощения примеров.
Читайте также: