Request response in one word

This guide explains how to make an HTTP GET request to an external API from a smart contract using Chainlink’s Request & Receive Data cycle and receive a single response.

Example

This example shows how to:

  • Fetch a single word response in a single call.

The Cryptocompare GET /data/pricemultifull API returns the current trading info (price, vol, open, high, low) of any list of cryptocurrencies in any other currency that you need. To check the response, you can directly paste the following URL in your browser https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD or run this command in your terminal:

curl -X 'GET' 
  'https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD' 
  -H 'accept: application/json'

The response should be similar to the following example:

{
  "RAW": {
    "ETH": {
      "USD": {
        "TYPE": "5",
        "MARKET": "CCCAGG",
        "FROMSYMBOL": "ETH",
        "TOSYMBOL": "USD",
        "FLAGS": "2049",
        "PRICE": 2867.04,
        "LASTUPDATE": 1650896942,
        "MEDIAN": 2866.2,
        "LASTVOLUME": 0.16533939,
        "LASTVOLUMETO": 474.375243849,
        "LASTTRADEID": "1072154517",
        "VOLUMEDAY": 195241.78281014622,
        "VOLUMEDAYTO": 556240560.4621655,
        "VOLUME24HOUR": 236248.94641103,
        ...
}

To consume an API with multiple responses, your contract must import ChainlinkClient. This contract exposes a struct called Chainlink.Request, which your contract should use to build the API request. The request should include the following parameters:

  • Link token address
  • Oracle address
  • Job id
  • Request fee
  • Task parameters
  • Callback function signature

Assume that a user wants to call the API above and retrieve only the 24h ETH trading volume from the response.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import "@chainlink/contracts/src/v0.8/ChainlinkClient.sol";
import "@chainlink/contracts/src/v0.8/ConfirmedOwner.sol";

/**
 * Request testnet LINK and ETH here: https://faucets.chain.link/
 * Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/
 */

/**
 * THIS IS AN EXAMPLE CONTRACT WHICH USES HARDCODED VALUES FOR CLARITY.
 * THIS EXAMPLE USES UN-AUDITED CODE.
 * DO NOT USE THIS CODE IN PRODUCTION.
 */

contract APIConsumer is ChainlinkClient, ConfirmedOwner {
    using Chainlink for Chainlink.Request;

    uint256 public volume;
    bytes32 private jobId;
    uint256 private fee;

    event RequestVolume(bytes32 indexed requestId, uint256 volume);

    /**
     * @notice Initialize the link token and target oracle
     *
     * Sepolia Testnet details:
     * Link Token: 0x779877A7B0D9E8603169DdbD7836e478b4624789
     * Oracle: 0x6090149792dAAeE9D1D568c9f9a6F6B46AA29eFD (Chainlink DevRel)
     * jobId: ca98366cc7314957b8c012c72f05aeeb
     *
     */
    constructor() ConfirmedOwner(msg.sender) {
        setChainlinkToken(0x779877A7B0D9E8603169DdbD7836e478b4624789);
        setChainlinkOracle(0x6090149792dAAeE9D1D568c9f9a6F6B46AA29eFD);
        jobId = "ca98366cc7314957b8c012c72f05aeeb";
        fee = (1 * LINK_DIVISIBILITY) / 10; // 0,1 * 10**18 (Varies by network and job)
    }

    /**
     * Create a Chainlink request to retrieve API response, find the target
     * data, then multiply by 1000000000000000000 (to remove decimal places from data).
     */
    function requestVolumeData() public returns (bytes32 requestId) {
        Chainlink.Request memory req = buildChainlinkRequest(
            jobId,
            address(this),
            this.fulfill.selector
        );

        // Set the URL to perform the GET request on
        req.add(
            "get",
            "https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD"
        );

        // Set the path to find the desired data in the API response, where the response format is:
        // {"RAW":
        //   {"ETH":
        //    {"USD":
        //     {
        //      "VOLUME24HOUR": xxx.xxx,
        //     }
        //    }
        //   }
        //  }
        // request.add("path", "RAW.ETH.USD.VOLUME24HOUR"); // Chainlink nodes prior to 1.0.0 support this format
        req.add("path", "RAW,ETH,USD,VOLUME24HOUR"); // Chainlink nodes 1.0.0 and later support this format

        // Multiply the result by 1000000000000000000 to remove decimals
        int256 timesAmount = 10 ** 18;
        req.addInt("times", timesAmount);

        // Sends the request
        return sendChainlinkRequest(req, fee);
    }

    /**
     * Receive the response in the form of uint256
     */
    function fulfill(
        bytes32 _requestId,
        uint256 _volume
    ) public recordChainlinkFulfillment(_requestId) {
        emit RequestVolume(_requestId, _volume);
        volume = _volume;
    }

    /**
     * Allow withdraw of Link tokens from the contract
     */
    function withdrawLink() public onlyOwner {
        LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress());
        require(
            link.transfer(msg.sender, link.balanceOf(address(this))),
            "Unable to transfer"
        );
    }
}

To use this contract:

  1. Open the contract in Remix.

  2. Compile and deploy the contract using the Injected Provider environment. The contract includes all the configuration variables for the Sepolia testnet. Make sure your wallet is set to use Sepolia. The constructor sets the following parameters:

    • The Chainlink Token address for Sepolia by calling the setChainlinkToken function.
    • The Oracle contract address for Sepolia by calling the setChainlinkOracle function.
    • The jobId: A specific job for the oracle node to run. In this case, you must call a job that is configured to call a public API, parse a number from the response and remove any decimals from it. We are going to use a generic GET>uint256 job that can be found here.
  3. Fund your contract with 0.1 LINK. To learn how to send LINK to contracts, read the Fund Your Contracts page.

  4. Call the volume function to confirm that the volume state variable is equal to zero.

  5. Run the requestVolumeData function. This builds the Chainlink.Request using the correct parameters:

    • The req.add("get", "<cryptocompareURL>") request parameter provides the oracle node with the URL from which to fetch ETH-USD trading info.
    • The req.add('path', 'RAW,ETH,USD,VOLUME24HOUR') request parameter tells the oracle node where to fetch the 24h ETH volume in the json response. It uses a JSONPath expression with comma(,) delimited string for nested objects. For example: 'RAW,ETH,USD,VOLUME24HOUR'.
    • The req.addInt('times', timesAmount) request parameter provides the oracle node with the multiplier timesAmount by which the fetched volume is multiplied. Use this to remove any decimals from the volume. Note: The times parameter is mandatory. If the API that you call returns a number without any decimals then provide 1as timesAmount.
      The APIConsumer in the example above is flexible enough to call any public API as long as the URL in get, path, and timesAmounnt are correct.
  6. After few seconds, call the volume function. You should get a non-zero response.

Response Types

Make sure to choose an oracle job that supports the data type that your contract needs to consume. Multiple data types are available such as:

  • uint256 — Unsigned integers
  • int256 — Signed integers
  • bool — True or False values
  • string — String
  • bytes32 — Strings and byte values. If you need to return a string, use bytes32. Here’s one method of converting bytes32 to string. Currently, any return value must fit within 32 bytes. If the value is bigger than that, make multiple requests.
  • bytes — Arbitrary-length raw byte data

Setting the LINK token address, Oracle, and JobId

The setChainlinkToken function sets the LINK token address for the network you are deploying to. The setChainlinkOracle function sets a specific Chainlink oracle that a contract makes an API call from. The jobId refers to a specific job for that node to run.

Each job is unique and returns different types of data. For example, a job that returns a bytes32 variable from an API would have a different jobId than a job that retrieved the same data, but in the form of a uint256 variable.

Check the Find Existing Jobs page to learn how to find a job suitable to your use case.

What’s next

  • › Multi-Variable Responses
  • › Fetch data from an Array
  • › Large Responses
  • › Make an Existing Job Request
  • › API Reference
  • › Testnet Oracles

Whether you are a user or a website owner, the one word you might come across when browsing is HTTP. It is important to get the basics of HTTP to understand how Internet works and the details sent and received between your browser and the web server. Here is a beginners guide to HTTP attempting to explain the basics.

A Beginners Guide to HTTP

In the following sections, we have explained how HTTP works, structure of request/response, status codes and checking the details using Chrome browser.

1. What is HTTP?

HTTP stands for HyperText Transfer Protocol. This is a basis for data communication in the internet. The data communication starts with a request sent from a client and ends with the response received from a web server.

  • A website URL starting with “http://” is entered in a web browser from a computer (client). The browser can be a Chrome, Firefox, Edge, Safari, Opera or anything else.
  • Browser sends a request sent to the web server that hosts the website.
  • The web server then returns a response as a HTML page or any other document format to the browser.
  • Browser displays the response from the server to the user.

The symbolic representation of a HTTP communication process is shown in the below picture:

HTTP Request and Response Over Web

The web browser is called as a User Agent and other example of a user agent is the crawlers of search engines like Googlebot.

2. HTTP Request Structure from Client

A simple request message from a client computer consists of the following components:

  • A request line to get a required resource, for example a request GET /content/page1.html is requesting a resource called /content/page1.html from the server.
  • Headers (Example – Accept-Language: EN).
  • An empty line.
  • A message body which is optional.

All the lines should end with a carriage return and line feed. The empty line should only contains carriage return and line feed without any spaces.

3. HTTP Response Structure from Web Server

A simple response from the server contains the following components:

  • HTTP Status Code (For example HTTP/1.1 301 Moved Permanently, means the requested resource was permanently moved and redirecting to some other resource).
  • Headers (Example – Content-Type: html)
  • An empty line.
  • A message body which is optional.

All the lines in the server response should end with a carriage return and line feed. Similar to request, the empty line in a response also should only have carriage return and line feed without any spaces.

4. Example of HTTP Session

Let us take an example that you want to open a page “home.html” from the site “yoursite.com”. Below is how the request from the client browser should look like to get a “home.html” page from “yoursite.com”.

GET /home.html HTTP/1.1
Host: www.yoursite.com

The response from the web server should look like below:

HTTP/1.1 200 OK
Date: Sun, 28 Jul 2013 15:37:37 GMT
Server: Apache
Last-Modified: Sun, 07 Jul 2013 06:13:43 GMT
Transfer-Encoding: chunked
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
Webpage Content

Chunked transfer encoding is a method in which the server responds with a data in chunks and this used in place of Content-Length header. The communication is stopped when a zero length of chunk is received and this method is used in HTTP Version 1.1.

5. What is that HTTPS?

Now you understand HTTP then what is that HTTPS? HTTPS is the secured HTTP protocol required to send and receive information securely over internet. Nowadays it is mandatory for all websites to have HTTPS protocol to have secured internet. Browsers like Google Chrome will show an alert with “Not Secure” message in the address bar if the site is not served over HTTPS.

Besides the security and encryption, the communication structure of HTTPS protocol remains same as HTTP protocol as explained above.

Warning: We do not recommend using confidential information like credit card details on HTTP sites. Ensure the financial transactions happens through HTTPS protocol.

6. How to Check HTTP Request and Response on Chrome?

Well, it’s time to practical. Let us take Google Chrome the popular browser, but the process remains same in all other browsers to view the details.

  • Open a webpage in Google Chrome and go to “View > Developer > Developer Tools” menu.
  • You can also open the developer console by right clicking on the page and choose “Inspect” option.
  • Go to “Network” tab and then reload the page. Now you will see the loading time for each single component on the page.
  • Click on the “Show Overview” icon to remove the timeline so that you can view other details clearly.
  • Click the page URL on the left bar and go to “Response” tab. (You can also view the same details under “Preview” tab).
Viewing HTTP Request and Response in Google Chrome
Viewing HTTP Request and Response in Google Chrome

You can see the details of request and responses as exactly we have explained in the above sections. The “Headers” tab will show you the details of HTTP header information for request and response for the selected item.

7. HTTP Header Checker Tool

Similar to Chrome, there are also many other free tools available to check the response code received in HTTP headers. For example, go to this HTTP header checker tool, enter any of the URL you wanted to check and click the submit button.

You will see the complete details of the header like below:

HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Sun, 25 Feb 2018 16:32:55 GMT
Content-Type: text/html; charset=iso-8859-1
Connection: keep-alive
Location: https://www.webnots.com/
Cache-Control: max-age=3600
Expires: Sun, 25 Feb 2018 17:32:55 GMT
HTTP/1.1 200 OK
Server: nginx
Date: Sun, 25 Feb 2018 16:32:55 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
X-Frame-Options: SAMEORIGIN
X-Powered-By: W3 Total Cache/0.9.6
Link: ; rel="https://api.w.org/", ; rel=shortlink
Vary: X-Forwarded-Proto,User-Agent
Cache-Control: max-age=3600
Expires: Sun, 25 Feb 2018 17:32:55 GMT
Host-Header: 192fc2e7e50945beb8231a492d6a8024

8. Troubleshooting with HTTP Status Codes

There are many reasons, a request from browser will not get required response from web server. In such failure cases, the response information from the web server is important for troubleshooting. The status codes returned by the server can be seen in Chrome Developer Tools section clearly. In the above screenshot, line 4 – HTTP/1.1  200 OK code indicates the server successfully returned the requested resource without any problem. You can get these detail using HTTP header check tool as explained above.

The three digits code returned from the server is called HTTP status code, though some people refer it as error code though it is not an error. It is merely a status response and helps you to find the reason for the communication failure. Remember that the communication failure can also happen due to the browser and computer problems like local network issues. In these cases, modern browsers like Chrome will show browser errors like “err_network_changed“, “err_internet_disconnected“, etc.

9. Details of HTTP Status Codes

The HTTP status codes are developed as per the Internet standards defined by Internet Engineering Task Force (IETF). They are classified into five different categories as below:

  • 1xx series – Informational Message
  • 2xx – Success Message
  • 3xx – Redirection Message
  • 4xx – Error Messages Related to Client
  • 5xx – Error Messages Related to Server

9.1. Informational Series – 1xx

These are the informational codes send by the server indicating that the request is received from the client successfully and the same is under processing at the server end. This is a provisional response from the server normally contains only the status line and optional headers and is terminated with an empty line. Learn more about each 1xx status codes in detail.

9.2. Success Series – 2xx

These are the success codes send by the server indicating that the request is received and processed successfully. Learn more about each 2xx status codes in detail.

9.3. Redirection – 3xx

These are the status codes for redirection. When a user agent (a web browser or a crawler) requesting URL1 is redirected to another resource URL2 then 2xx codes are returned as a response. These codes are not seen in the browser window since browsers are auto redirected to another URL. Learn more about each 3xx status codes in detail.

9.4. Client Errors – 4xx

These are the errors from the client side which the server could not resolve. Simple and well known example is a “404 – Page Not Found” error displayed in the browser window when an unavailable URL is requested by the browser. Learn more about each 4xx status codes in detail.

9.5. Server Errors Series – 5xx

When a web server can’t fulfill a valid request from a client it sends a 5xx error code in the response. An example is “504 – Gateway Timeout” error where the web server1 is acting as a proxy to get a response from another web server2  but failed to receive a timely response. Learn more about each 5xx status codes in detail.

10. Download HTTP Status Codes Guide

You can download the complete HTTP status codes guide for offline reference and learn more about each code in detail.

Final Words

We recommend all Internet users and website owners learn the basic concepts of HTTP. This will really help in troubleshooting the connection failure related issues. Hope we have covered all required details for a beginner level user in this guide. If you see any important details are missed, just drop in a comment. We will try to update this guide for the benefit of all readers.

HTTP messages are how data is exchanged between a server and a client. There are two types of messages: requests sent by the client to trigger an action on the server, and responses, the answer from the server.

HTTP messages are composed of textual information encoded in ASCII, and span over multiple lines. In HTTP/1.1, and earlier versions of the protocol, these messages were openly sent across the connection. In HTTP/2, the once human-readable message is now divided up into HTTP frames, providing optimization and performance improvements.

Web developers, or webmasters, rarely craft these textual HTTP messages themselves: software, a Web browser, proxy, or Web server, perform this action. They provide HTTP messages through config files (for proxies or servers), APIs (for browsers), or other interfaces.

From a user-, script-, or server- generated event, an HTTP/1.x msg is generated, and if HTTP/2 is in use, it is binary framed into an HTTP/2 stream, then sent.

The HTTP/2 binary framing mechanism has been designed to not require any alteration of the APIs or config files applied: it is broadly transparent to the user.

HTTP requests, and responses, share similar structure and are composed of:

  1. A start-line describing the requests to be implemented, or its status of whether successful or a failure. This start-line is always a single line.
  2. An optional set of HTTP headers specifying the request, or describing the body included in the message.
  3. A blank line indicating all meta-information for the request has been sent.
  4. An optional body containing data associated with the request (like content of an HTML form), or the document associated with a response. The presence of the body and its size is specified by the start-line and HTTP headers.

The start-line and HTTP headers of the HTTP message are collectively known as the head of the requests, whereas its payload is known as the body.

Requests and responses share a common structure in HTTP

HTTP Requests

Start line

HTTP requests are messages sent by the client to initiate an action on the server. Their start-line contain three elements:

  1. An HTTP method, a verb (like GET, PUT or POST) or a noun (like HEAD or OPTIONS), that describes the action to be performed. For example, GET indicates that a resource should be fetched or POST means that data is pushed to the server (creating or modifying a resource, or generating a temporary document to send back).
  2. The request target, usually a URL, or the absolute path of the protocol, port, and domain are usually characterized by the request context. The format of this request target varies between different HTTP methods. It can be
    • An absolute path, ultimately followed by a '?' and query string. This is the most common form, known as the origin form, and is used with GET, POST, HEAD, and OPTIONS methods.
      • POST / HTTP/1.1
      • GET /background.png HTTP/1.0
      • HEAD /test.html?query=alibaba HTTP/1.1
      • OPTIONS /anypage.html HTTP/1.0
    • A complete URL, known as the absolute form, is mostly used with GET when connected to a proxy.
      GET https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages HTTP/1.1
    • The authority component of a URL, consisting of the domain name and optionally the port (prefixed by a ':'), is called the authority form. It is only used with CONNECT when setting up an HTTP tunnel.
      CONNECT developer.mozilla.org:80 HTTP/1.1
    • The asterisk form, a simple asterisk ('*') is used with OPTIONS, representing the server as a whole.
      OPTIONS * HTTP/1.1
  3. The HTTP version, which defines the structure of the remaining message, acting as an indicator of the expected version to use for the response.

HTTP headers from a request follow the same basic structure of an HTTP header: a case-insensitive string followed by a colon (':') and a value whose structure depends upon the header. The whole header, including the value, consists of one single line, which can be quite long.

Many different headers can appear in requests. They can be divided in several groups:

  • General headers, like Via, apply to the message as a whole.
  • Request headers, like User-Agent or Accept, modify the request by specifying it further (like Accept-Language), by giving context (like Referer), or by conditionally restricting it (like If-None).
  • Representation headers like Content-Type that describe the original format of the message data and any encoding applied (only present if the message has a body).

Example of headers in an HTTP request

Body

The final part of the request is its body. Not all requests have one: requests fetching resources, like GET, HEAD, DELETE, or OPTIONS, usually don’t need one. Some requests send data to the server in order to update it: as often the case with POST requests (containing HTML form data).

Bodies can be broadly divided into two categories:

  • Single-resource bodies, consisting of one single file, defined by the two headers: Content-Type and Content-Length.
  • Multiple-resource bodies, consisting of a multipart body, each containing a different bit of information. This is typically associated with HTML Forms.

HTTP Responses

Status line

The start line of an HTTP response, called the status line, contains the following information:

  1. The protocol version, usually HTTP/1.1.
  2. A status code, indicating success or failure of the request. Common status codes are 200, 404, or 302
  3. A status text. A brief, purely informational, textual description of the status code to help a human understand the HTTP message.

A typical status line looks like: HTTP/1.1 404 Not Found.

HTTP headers for responses follow the same structure as any other header: a case-insensitive string followed by a colon (':') and a value whose structure depends upon the type of the header. The whole header, including its value, presents as a single line.

Many different headers can appear in responses. These can be divided into several groups:

  • General headers, like Via, apply to the whole message.
  • Response headers, like Vary and Accept-Ranges, give additional information about the server which doesn’t fit in the status line.
  • Representation headers like Content-Type that describe the original format of the message data and any encoding applied (only present if the message has a body).

Example of headers in an HTTP response

Body

The last part of a response is the body. Not all responses have one: responses with a status code that sufficiently answers the request without the need for corresponding payload (like 201 Created or 204 No Content) usually don’t.

Bodies can be broadly divided into three categories:

  • Single-resource bodies, consisting of a single file of known length, defined by the two headers: Content-Type and Content-Length.
  • Single-resource bodies, consisting of a single file of unknown length, encoded by chunks with Transfer-Encoding set to chunked.
  • Multiple-resource bodies, consisting of a multipart body, each containing a different section of information. These are relatively rare.

HTTP/2 Frames

HTTP/1.x messages have a few drawbacks for performance:

  • Headers, unlike bodies, are uncompressed.
  • Headers are often very similar from one message to the next one, yet still repeated across connections.
  • No multiplexing can be done. Several connections need opening on the same server: and warm TCP connections are more efficient than cold ones.

HTTP/2 introduces an extra step: it divides HTTP/1.x messages into frames which are embedded in a stream. Data and header frames are separated, which allows header compression. Several streams can be combined together, a process called multiplexing, allowing more efficient use of underlying TCP connections.

HTTP/2 modify the HTTP message to divide them in frames (part of a single stream), allowing for more optimization.

HTTP frames are now transparent to Web developers. This is an additional step in HTTP/2, between HTTP/1.1 messages and the underlying transport protocol. No changes are needed in the APIs used by Web developers to utilize HTTP frames; when available in both the browser and the server, HTTP/2 is switched on and used.

Conclusion

HTTP messages are the key in using HTTP; their structure is simple, and they are highly extensible. The HTTP/2 framing mechanism adds a new intermediate layer between the HTTP/1.x syntax and the underlying transport protocol, without fundamentally modifying it: building upon proven mechanisms.

Время на прочтение
4 мин

Количество просмотров 840K

Этот пост — ответ на вопрос, заданный в комментарии к одной из моих статей.

В статье я хочу рассказать, что же из себя представляют HTTP-методы GET/POST/PUT/DELETE и другие, для чего они были придуманы и как их использовать в соответствии с REST.

HTTP

Итак, что же представляет из себя один из основных протоколов интернета? Педантов отправлю к RFC2616, а остальным расскажу по-человечески :)

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

Стартовые строки для запроса и ответа имеют различный формат — нам интересна только стартовая строка запроса, которая выглядит так:

METHOD URI HTTP/VERSION,

где METHOD — это как раз метод HTTP-запроса, URI — идентификатор ресурса, VERSION — версия протокола (на данный момент актуальна версия 1.1).

Заголовки — это набор пар имя-значение, разделенных двоеточием. В заголовках передается различная служебная информация: кодировка сообщения, название и версия браузера, адрес, с которого пришел клиент (Referrer) и так далее.

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

Пример HTTP-взаимодействия

Рассмотрим пример.

Запрос:

GET /index.php HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9b5) Gecko/2008050509 Firefox/3.0b5
Accept: text/html
Connection: close

Первая строка — это строка запроса, остальные — заголовки; тело сообщения отсутствует

Ответ:

HTTP/1.0 200 OK
Server: nginx/0.6.31
Content-Language: ru
Content-Type: text/html; charset=utf-8
Content-Length: 1234
Connection: close

... САМА HTML-СТРАНИЦА ...

Ресурсы и методы

Вернемся к стартовой строке запроса и вспомним, что в ней присутствует такой параметр, как URI. Это расшифровывается, как Uniform Resource Identifier — единообразный идентификатор ресурса. Ресурс — это, как правило, файл на сервере (пример URI в данном случае ‘/styles.css’), но вообще ресурсом может являться и какой-либо абстрактный объект (‘/blogs/webdev/’ — указывает на блок «Веб-разработка», а не на конкретный файл).

Тип HTTP-запроса (также называемый HTTP-метод) указывает серверу на то, какое действие мы хотим произвести с ресурсом. Изначально (в начале 90-х) предполагалось, что клиент может хотеть от ресурса только одно — получить его, однако сейчас по протоколу HTTP можно создавать посты, редактировать профиль, удалять сообщения и многое другое. И эти действия сложно объединить термином «получение».

Для разграничения действий с ресурсами на уровне HTTP-методов и были придуманы следующие варианты:

  • GET — получение ресурса
  • POST — создание ресурса
  • PUT — обновление ресурса
  • DELETE — удаление ресурса

Обратите внимание на тот факт, что спецификация HTTP не обязывает сервер понимать все методы (которых на самом деле гораздо больше, чем 4) — обязателен только GET, а также не указывает серверу, что он должен делать при получении запроса с тем или иным методом. А это значит, что сервер в ответ на запрос DELETE /index.php HTTP/1.1 не обязан удалять страницу index.php на сервере, так же как на запрос GET /index.php HTTP/1.1 не обязан возвращать вам страницу index.php, он может ее удалять, например :)

В игру вступает REST

REST (REpresentational State Transfer) — это термин был введен в 2000-м году Роем Филдингом (Roy Fielding) — одним из разработчиков протокола HTTP — в качестве названия группы принципов построения веб-приложений. Вообще REST охватывает более широкую область, нежели HTTP — его можно применять и в других сетях с другими протоколами. REST описывает принципы взаимодействия клиента и сервера, основанные на понятиях «ресурса» и «глагола» (можно понимать их как подлежащее и сказуемое). В случае HTTP ресурс определяется своим URI, а глагол — это HTTP-метод.

REST предлагает отказаться от использования одинаковых URI для разных ресурсов (то есть адреса двух разных статей вроде /index.php?article_id=10 и /index.php?article_id=20 — это не REST-way) и использовать разные HTTP-методы для разных действий. То есть веб-приложение, написанное с использованием REST подхода будет удалять ресурс при обращении к нему с HTTP-методом DELETE (разумеется, это не значит, что надо давать возможность удалить всё и вся, но любой запрос на удаление в приложении должен использовать HTTP-метод DELETE).

REST дает программистам возможность писать стандартизованные и чуть более красивые веб-приложения, чем раньше. Используя REST, URI для добавления нового юзера будет не /user.php?action=create (метод GET/POST), а просто /user.php (метод строго POST).

В итоге, совместив имеющуюся спецификацию HTTP и REST-подход наконец-то обретают смысл различные HTTP-методы. GET — возвращает ресурс, POST — создает новый, PUT — обновляет существующий, DELETE — удаляет.

Проблемы?

Да, есть небольшая проблема с применением REST на практике. Проблема эта называется HTML.

PUT/DELETE запросы можно отправлять посредством XMLHttpRequest, посредством обращения к серверу «вручную» (скажем, через curl или даже через telnet), но нельзя сделать HTML-форму, отправляющую полноценный PUT/DELETE-запрос.

Дело в том, спецификация HTML не позволяет создавать формы, отправляющие данные иначе, чем через GET или POST. Поэтому для нормальной работы с другими методами приходится имитировать их искусственно. Например, в Rack (механизм, на базе которого Ruby взаимодействует с веб-сервером; с применением Rack сделаны Rails, Merb и другие Ruby-фреймворки) в форму можно добавить hidden-поле с именем «_method», а в качестве значения указать название метода (например, «PUT») — в этом случае будет отправлен POST-запрос, но Rack сможет сделать вид, что получил PUT, а не POST.

Like this post? Please share to your friends:
  • Repugnant type of word
  • Represent in other word
  • Reports samples in word
  • Reports in microsoft excel
  • Reports in excel sheet