ESP8266: HTTP GET Requests

Introduction

The objective of this post is to explain how to perform HTTP GET Requests using the ESP8266. If you prefer a video explanation, you can check my YouTube channel below:

The tests from this tutorial were performed using a NodeMCU board, a very cheap and easy to use ESP8266 board.

The setup

First, we need do include some libraries. Naturally, we need the ESP8266WiFi library, which provides to us the methods to connect to a WiFi network.

Then, we need the ESP8266HTTPClient library, which provides the methods to send HTTP requests. The header file for the ESP8266HTTPClient library can be seen here.

#include <esp8266wifi.h>
#include <esp8266httpclient.h>

To be able to connect to the WiFi network, we will need its credentials. So, we will define two global variables containing the network name (SSID) and password. Note that you should replace the placeholders in the code snippet below by the credentials of your network.

const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";

On the setup function, we will connect to the WiFi Network. This is done with a call to the begin method on the WiFi extern variable and providing the previously defined network credentials. More details about how to connect to a WiFi network using the ESP8266 are explained in this previous post.

We will also start a Serial connection to print the results of our program.

The complete Arduino setup function code can be seen below.

void setup () {

  Serial.begin(115200);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {

    delay(1000);
    Serial.print("Connecting..");

  }

}

The main code

The code for the request will be specified in the Arduino main loop function. First, we declare an object of class HTTPClient, which we will simply call http. This class provides the methods to create and send the HTTP request.

HTTPClient http;

After that, we will call the begin method on the http object and pass the URL that we want to connect to and make the HTTP GET request. The destination website specified here implements a dummy REST API for testing and prototyping.

Note that the particular endpoint we are reaching will return a JSON payload as response, simulating a possible “user” data structure. You can directly access the URL and check the result in a web browser. Later, when testing the ESP8266 code, we should receive the same response.

http.begin("http://jsonplaceholder.typicode.com/users/1");

Then, we send the request by calling the GET method on the http object. This method will return the status of the operation, which is important to store for error handling. If the value is greater than 0, then it is a standard HTTP code. If the value is lesser than 0, then it is a client error, related with the connection. All available error codes for this method are listed here.

int httpCode = http.GET();

So, if the code is greater than 0, we can get the response payload by calling the getString method on the http object. The response is returned as a String, which we can directly print to the serial port.

String payload = http.getString();
Serial.println(payload);

Finally, we will call the end method. This is very important to close the TCP connection and thus free the resources.

http.end();

The final complete code is shown bellow. Note that we have added a small delay of 30 seconds between each iteration of the Arduino main loop, to avoid constantly polling the server.

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";

void setup () {

  Serial.begin(115200);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {

    delay(1000);
    Serial.print("Connecting..");

  }

}

void loop() {

  if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status

    HTTPClient http;  //Declare an object of class HTTPClient

    http.begin("http://jsonplaceholder.typicode.com/users/1");  //Specify request destination
    int httpCode = http.GET();                                  //Send the request

    if (httpCode > 0) { //Check the returning code

      String payload = http.getString();   //Get the request response payload
      Serial.println(payload);             //Print the response payload

    }

    http.end();   //Close connection

  }

  delay(30000);    //Send a request every 30 seconds
}

Testing the code

To test the code, simply compile it and upload it to your device using the Arduino IDE.

After the upload procedure finishes, open the IDE serial monitor and wait for the WiFi connection to be established. Once this procedure is done, the ESP8266 should start sending the HTTP GET requests to the server periodically.

The expected output of the program is shown in figure 1. The response printed to the serial monitor corresponds to the JSON payload returned by the server. The ESP8266 should keep doing a HTTP GET request every 30 seconds.

Output of the ESP8266 GET Request program, on the Arduino IDE serial monitor
Figure 1 – Output of the GET Request.

Finally, it’s important to take in consideration that the microcontroller has a limited amount of resources and thus it is not able to handle very large results. So, it is not expected that it will be used to make and process requests to sites that return a lot of information, as a typical browser would do.

Related Posts

Technical details

  • ESP8266 libraries: v2.3.0
  • Operating system: Windows 8.1

314 thoughts on “ESP8266: HTTP GET Requests”

    1. Hi!

      You can use the addHeader method of the HTTPClient class. Below is an example in the context of making a POST request, but it works the same way for GET:
      https://techtutorialsx.com/2016/07/21/esp8266-post-requests/

      The first argument is the name of the header and the second is the value.

      But please note that this tutorial uses HTTP, which means that the request headers are sent in plain text to the server.

      HTTP is not encrypted, HTTPS is (note the additional S at the end, from Secure).

      So this basically means that sending an API key is not secure and an attacker can easily intercept the request and steal it.

      Hope this helps 🙂

      Best regards,
      Nuno Santos

    1. Hi!
      You can use the addHeader method of the HTTPClient class. Below is an example in the context of making a POST request, but it works the same way for GET:
      https://techtutorialsx.com/2016/07/21/esp8266-post-requests/
      The first argument is the name of the header and the second is the value.
      But please note that this tutorial uses HTTP, which means that the request headers are sent in plain text to the server.
      HTTP is not encrypted, HTTPS is (note the additional S at the end, from Secure).
      So this basically means that sending an API key is not secure and an attacker can easily intercept the request and steal it.
      Hope this helps 🙂
      Best regards,
      Nuno Santos

  1. Hi there, thanks for the tutorial! Do you know if there’s a way of doing this with the Wifi Client library? Basically I am running a local server with a page connected to a remote server. The remote server returns a json file. However I am not able to retrieve in the code. I’ll post here just my void loop() since it’s a bit long (my full code is here – https://forum.arduino.cc/index.php?topic=559170.new#new – and I’d be really greatful if you could answer here since I’m not getting much help over there). Thanks!!

    void loop(){
    WiFiClient client = server.available();
    if (!client) {
    return;
    }

    // Wait until the client sends some data
    SPL(“new client”);
    while(!client.available()){
    delay(1);
    }

    //this doesn’t print the payload (which sould be the json. It works well in the browser)
    byte b;
    while (client.readBytes(&b, 1) > 0) {
    Serial.write(b);*
    }

    client.flush();

    // Prepare the response
    String s = “HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n”;
    s += page; //the html page hosted on the local server and which connects to the remote one
    s += “\n”;

    // Send the response to the client
    client.print(s);
    }

    1. Hi!

      You’re welcome 🙂

      Well that’s a complex architecture, may I ask why can’t you directly fetch the json from the remote server?

      When you mention that you are hosting a server locally, are you hosting it on a computer on the same network of the ESP8266, or are you actually hosting it in the ESP8266?

      In either cases, you should be able to do pretty much what you can with the HTTP client library with the WIFi Client library.

      HTTP works on top of sockets, and the WiFiClient basically is a socket.

      Nonetheless, it means that you need to implement everything from the HTTP protocol yourself.

      Unfortunately I don’t have code on how to use HTTP directly on top of the WiFIClient, but the Arduino core has a very simple example:
      https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/examples/WiFiClient/WiFiClient.ino

      Nonetheless, I really don’t recommend to implement HTTP on top of the WiFiClient yourself, unless you have a really good reason to do it and a good understanding about how the protocol works.

      Sending a request to a server and returning the response is something that can be achieved with a couple of lines using the HTTP Client library.

      It may seem too much work to change your code to use the HTTP Client, but in the long term it will most likely be easier to maintain and change.

      Hope this helps getting you in the right path 🙂

      Best regards,
      Nuno Santos

  2. Hi there, thanks for the tutorial! Do you know if there’s a way of doing this with the Wifi Client library? Basically I am running a local server with a page connected to a remote server. The remote server returns a json file. However I am not able to retrieve in the code. I’ll post here just my void loop() since it’s a bit long (my full code is here – https://forum.arduino.cc/index.php?topic=559170.new#new – and I’d be really greatful if you could answer here since I’m not getting much help over there). Thanks!!
    void loop(){
    WiFiClient client = server.available();
    if (!client) {
    return;
    }
    // Wait until the client sends some data
    SPL(“new client”);
    while(!client.available()){
    delay(1);
    }
    //this doesn’t print the payload (which sould be the json. It works well in the browser)
    byte b;
    while (client.readBytes(&b, 1) > 0) {
    Serial.write(b);*
    }
    client.flush();
    // Prepare the response
    String s = “HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n”;
    s += page; //the html page hosted on the local server and which connects to the remote one
    s += “\n”;
    // Send the response to the client
    client.print(s);
    }

    1. Hi!
      You’re welcome 🙂
      Well that’s a complex architecture, may I ask why can’t you directly fetch the json from the remote server?
      When you mention that you are hosting a server locally, are you hosting it on a computer on the same network of the ESP8266, or are you actually hosting it in the ESP8266?
      In either cases, you should be able to do pretty much what you can with the HTTP client library with the WIFi Client library.
      HTTP works on top of sockets, and the WiFiClient basically is a socket.
      Nonetheless, it means that you need to implement everything from the HTTP protocol yourself.
      Unfortunately I don’t have code on how to use HTTP directly on top of the WiFIClient, but the Arduino core has a very simple example:
      https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/examples/WiFiClient/WiFiClient.ino
      Nonetheless, I really don’t recommend to implement HTTP on top of the WiFiClient yourself, unless you have a really good reason to do it and a good understanding about how the protocol works.
      Sending a request to a server and returning the response is something that can be achieved with a couple of lines using the HTTP Client library.
      It may seem too much work to change your code to use the HTTP Client, but in the long term it will most likely be easier to maintain and change.
      Hope this helps getting you in the right path 🙂
      Best regards,
      Nuno Santos

  3. Hi there, I only receive -1 as httpCode, no matter which website I try (even http://www.google.com). How can it be? I’m running this inside the setup since I only need it once. Thanks!

    HTTPClient http;
    http.begin(“http://www.google.com”);
    int httpCode = http.GET();

    Serial.print(“HTTP CODE: “);
    Serial.println(httpCode); //prints out HTTP CODE: -1

    if(httpCode > 0){ //doesn’t print and payload is empty
    String payload = http.getString();
    Serial.print(“PAYLOAD: “);
    Serial.println(payload);
    }

    http.end();

    1. Hi!

      Did you previously connect the device to a WiFi network and waited for the connection to complete?

      If you test the code exactly like it is on this post, does it also return -1 in every call?

      Let me know some more details so I can try to help 🙂

      Best regards,
      Nuno Santos

  4. Hi there, I only receive -1 as httpCode, no matter which website I try (even http://www.google.com). How can it be? I’m running this inside the setup since I only need it once. Thanks!
    HTTPClient http;
    http.begin(“http://www.google.com”);
    int httpCode = http.GET();
    Serial.print(“HTTP CODE: “);
    Serial.println(httpCode); //prints out HTTP CODE: -1
    if(httpCode > 0){ //doesn’t print and payload is empty
    String payload = http.getString();
    Serial.print(“PAYLOAD: “);
    Serial.println(payload);
    }
    http.end();

    1. Hi!
      Did you previously connect the device to a WiFi network and waited for the connection to complete?
      If you test the code exactly like it is on this post, does it also return -1 in every call?
      Let me know some more details so I can try to help 🙂
      Best regards,
      Nuno Santos

  5. Hi, I’m using the script to download a binary firmware file, which I then need to pass to the upload library as ‘Stream &data’. I can check the headers and content-type using http.collecteHeaders, but can’t workout how to pass the received file into the stream – using .getString() returns an empty string.

    1. Hi!

      I haven’t yet worked with streams and HTTP on the ESP8266, so I cannot help much.

      My suggestion is to ask around the ESP8266 Arduino core, so maybe someone there has already done it and can help 🙂

      Best regards,
      Nuno Santos

  6. Hi, I’m using the script to download a binary firmware file, which I then need to pass to the upload library as ‘Stream &data’. I can check the headers and content-type using http.collecteHeaders, but can’t workout how to pass the received file into the stream – using .getString() returns an empty string.

    1. Hi!
      I haven’t yet worked with streams and HTTP on the ESP8266, so I cannot help much.
      My suggestion is to ask around the ESP8266 Arduino core, so maybe someone there has already done it and can help 🙂
      Best regards,
      Nuno Santos

  7. Hey,

    Im trying to get your sketch uploaded to the ESP-01 which is connected to my Arduino. I have done the connections properly(http://www.teomaragakis.com/wp-content/uploads/2015/10/uno_esp_connection.png) and also the sketch compiles successfully. The issue occurs when I try to upload the sketch. The following errors are displayed:

    warning: espcomm_sync failed
    error: espcomm_open failed
    error: espcomm_upload_mem failed
    error: espcomm_upload_mem failed

    Please do check the link and let me know if the connections are right.
    Would be great if you can help me out!Thanks cheers!

    1. Hi,

      Were you able to upload any other sketches in the past with the same hardware configuration or is it the first time that you try?

      Unfortunately I never tried to upload code to the ESP8266 using an Arduino, so I cannot help much.

      Nonetheless, here is the hardware configuration needed to directly upload code to the ESP-01, without the need of using Arduino. Note that this post already has some time, but I think it is still working 🙂
      https://techtutorialsx.com/2016/02/28/esp8266-uploading-code-from-arduino-ide/

      Best regards,
      Nuno Santos

  8. Hey,
    Im trying to get your sketch uploaded to the ESP-01 which is connected to my Arduino. I have done the connections properly(http://www.teomaragakis.com/wp-content/uploads/2015/10/uno_esp_connection.png) and also the sketch compiles successfully. The issue occurs when I try to upload the sketch. The following errors are displayed:
    warning: espcomm_sync failed
    error: espcomm_open failed
    error: espcomm_upload_mem failed
    error: espcomm_upload_mem failed
    Please do check the link and let me know if the connections are right.
    Would be great if you can help me out!Thanks cheers!

    1. Hi,
      Were you able to upload any other sketches in the past with the same hardware configuration or is it the first time that you try?
      Unfortunately I never tried to upload code to the ESP8266 using an Arduino, so I cannot help much.
      Nonetheless, here is the hardware configuration needed to directly upload code to the ESP-01, without the need of using Arduino. Note that this post already has some time, but I think it is still working 🙂
      https://techtutorialsx.com/2016/02/28/esp8266-uploading-code-from-arduino-ide/
      Best regards,
      Nuno Santos

Leave a Reply