We continue with the ESP8266 and ESP32 and start getting into “serious matters” for real, as it’s time to see how to use the ESP8266 as a REST API client that provides information through Json files.
We will refer to the ESP8266, but the same code is compatible with the ESP32, adjusting the library names. At the end, you have the code for both the ESP8266 and the ESP32.
In recent posts, we have seen multiple ways to connect an ESP8266 as a server with a web page served to the client. Thus, we saw Ajax and asynchronous Websockets. We also saw some time ago how to use the ESP8266 as an HTTP client.
As we have mentioned in this series of posts, to communicate two devices via HTTP, the server has to provide a certain API through endpoints. Currently, the most common practice is to use a REST API and the information exchange is done using Json files.
Since this is the trend to follow, it is logical that in our ESP8266 projects we are able to interact and obtain data from a REST API. This is precisely what we are going to do in this first post, seeing how to act as a client. In the next one, we will see how to serve a REST API from the ESP8266.
Imagine, for example, that you have a Raspberry Pi that exposes an API where we can read or save sensor values. Or that we act with an IoT server to interact with the different servers.
For this post, we will use our usual example REST API that we saw in this post, which runs on NodeJs. We will also use Json files, so we recommend you read the post about Json in Arduino.
With all that, we have the components for our example of ESP8266 as a REST API client. How complicated is it? Don’t worry, not too much if we are organized. So, let’s get to work!
First, our main loop. It is similar to the example as an HTTP client, but we have added the reference to ‘ArduinoJson.h’ and to a file ‘API.hpp’ that will contain the functions to call to interact with the REST API.
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include "config.h" // Replace with your network data
#include "API.hpp"
#include "ESP8266_Utils.hpp"
void setup()
{
Serial.begin(115200);
ConnectWiFi_STA();
GetAll();
GetItem(1);
GetQuery("ABC");
Create("New item");
ReplaceById(2, "New item");
UpdateById(2, "New item");
DeleteById(5);
}
void loop()
{
}
On the other hand, we have the ‘API.hpp’ file that contains the functions that interact with the REST API. Here we have one function for each endpoint exposed by our example REST API, and they illustrate the usual requests for Get, Replace, Update and Delete, each with its methods and with the necessary parameters, either in the URL or in the request body encoded as Json.
On the other hand, we have the ‘processResponse(…)’ function that is responsible for collecting the server’s responses and performing the appropriate actions with them. In this case, we simply display them via serial port. In a real project, we would interpret the received data (probably another Json file) and execute the appropriate actions.
String ApiHost = "http://192.168.1.1:8080";
void processResponse(int httpCode, HTTPClient& http)
{
if (httpCode > 0) {
Serial.printf("Response code: %d\t", httpCode);
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
Serial.println(payload);
}
}
else {
Serial.printf("Request failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
}
void GetAll()
{
HTTPClient http;
http.begin(ApiHost + "/item");
int httpCode = http.GET();
processResponse(httpCode, http);
}
void GetItem(int id)
{
HTTPClient http;
http.begin(ApiHost + "/item/" + id);
int httpCode = http.GET();
processResponse(httpCode, http);
}
void GetQuery(String filter)
{
HTTPClient http;
http.begin(ApiHost + "/item?filter=" + filter);
int httpCode = http.GET();
processResponse(httpCode, http);
}
void Create(String newData)
{
HTTPClient http;
http.begin(ApiHost + "/item");
http.addHeader("Content-Type", "application/json");
String message = "";
StaticJsonDocument<300> jsonDoc;
jsonDoc["data"] = newData;
serializeJson(jsonDoc, message);
int httpCode = http.POST(message);
processResponse(httpCode, http);
}
void ReplaceById(int id, String newData)
{
HTTPClient http;
http.begin(ApiHost + "/item/" + id);
http.addHeader("Content-Type", "application/json");
String message = "";
StaticJsonDocument<300> jsonDoc;
jsonDoc["data"] = newData;
serializeJson(jsonDoc, message);
int httpCode = http.PUT(message);
processResponse(httpCode, http);
}
void UpdateById(int id, String newData)
{
HTTPClient http;
http.begin(ApiHost + "/item/" + id);
http.addHeader("Content-Type", "application/json");
String message = "";
StaticJsonDocument<300> jsonDoc;
jsonDoc["data"] = newData;
serializeJson(jsonDoc, message);
int httpCode = http.PATCH(message);
processResponse(httpCode, http);
}
void DeleteById(int id)
{
HTTPClient http;
http.begin(ApiHost + "/item/" + id);
int httpCode = http.sendRequest("DELETE");
processResponse(httpCode, http);
}
In this example, for simplicity, we execute the functions in the ‘Setup’ so they run only once to illustrate their use. Of course, in a project, we would call them where needed in our code.
Result
If we run the code, we will see that all requests to the REST API served on our NodeJS server are executed correctly, and we are getting the responses sent by the server.

We also verify that in the NodeJS server console we are receiving the requests.

It wasn’t too complicated, was it? Now we know how to interact with the ESP8266 as a client, with a REST API in a correct and standardized way.
In the next one, we will add “the icing on the cake” by seeing how to serve a REST API from the ESP8266 itself. This is starting to get interesting! See you soon.
Download the Code
All the code from this post is available for download on Github.
Version for ESP8266: https://github.com/luisllamasbinaburo/ESP8266-Examples
Version for ESP32: https://github.com/luisllamasbinaburo/ESP32-Examples

