We continue with the ESP8266 and the ESP32 and we start to get into “serious” matters, as we have 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 for the ESP32, adjusting the name of the libraries. At the end, you have the code for both the ESP8266 and the ESP32.
In the last 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 how to use the ESP8266 as an HTTP client in its day.
As we have mentioned in this series of posts to communicate two devices through HTTP, the server has to provide a certain API through endpoints. Currently the most common thing is to use a REST API and the information exchange is done through Json files.
Being the trend to follow, it is logical that in our projects with ESP8266 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 a server in IoT to act on the different servers.
For this post, we will use our usual sample REST API that we saw in this post, which runs on NodeJs. We will also use Json files so we recommend that you read the post about Json in Arduino.
With all that, we have the components to make our example of ESP8266 as a client of a REST API. How complicated is it? Don’t worry, not too much if we are organized. So let’s get to work!
First of all, our main loop. It is similar to the example of an Http client, but we have added a reference to ‘ArduinoJson.h’ and to a ‘API.hpp’ file that will contain the functions to be called to act 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, which illustrate the usual requests for Get, Replace, Update, and Delete, each with their methods and with the necessary parameters, either in the URL or in the body of the request encoded as Json.
On the other hand, we have the ‘processResponse(…)’ function that is responsible for collecting the server responses and performing the appropriate actions with them. In this case, we simply show them through the serial port. In a real project, we would interpret the received data (probably another Json file) and perform 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 that they are launched only once and illustrate their use. Of course, in a project we would call them where we need them in our code.
Result
If we run the code, we will see that all the requests to the REST API served on our NodeJS server are executed correctly, and that we are obtaining the responses sent by the server.
We also verify that in the console of the NodeJS server we are receiving the requests.
Wasn’t it too complicated, right? Now we know how to interact with the ESP8266 as a client, with a REST API correctly and standardized.
In the next post, we will put “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 the ESP8266: https://github.com/luisllamasbinaburo/ESP8266-Examples
Version for the ESP32: https://github.com/luisllamasbinaburo/ESP32-Examples