HTTP is not only a theoretical concept. In real applications, we use HTTP requests to send and receive data between devices, applications, and servers.
In our IoT projects, the ESP32 can use HTTP to communicate with our Laravel API.
A simple IoT communication flow is:
ESP32 → Wi-Fi → HTTP Request → Laravel API → Database
In this tutorial, we will see practical examples of the four important HTTP methods:
- GET
- POST
- PUT
- DELETE
1. GET Request Example
The GET method is used to retrieve data from a server.
Suppose our Laravel API provides this endpoint:
GET /api/sensors/1
The client is asking:
"Give me the information of sensor 1."
Example Response
The server may return:
{
"id": 1,
"name": "Garden Sensor",
"moisture": 320
}
Laravel Example
In routes/api.php:
use Illuminate\Support\Facades\Route;
Route::get('/sensors/{id}', function ($id) {
return response()->json([
'id' => $id,
'name' => 'Garden Sensor',
'moisture' => 320
]);
});
Now if we open:
http://127.0.0.1:8000/api/sensors/1
the API can return:
{
"id": 1,
"name": "Garden Sensor",
"moisture": 320
}
ESP32 GET Example
The ESP32 can request this data using the HTTPClient library.
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "YOUR_WIFI_NAME";
const char* password = "YOUR_WIFI_PASSWORD";
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting...");
}
Serial.println("WiFi Connected");
HTTPClient http;
http.begin("http://192.168.1.100:8000/api/sensors/1");
int httpCode = http.GET();
if (httpCode > 0) {
Serial.print("HTTP Status: ");
Serial.println(httpCode);
String response = http.getString();
Serial.println("Server Response:");
Serial.println(response);
} else {
Serial.print("GET Error: ");
Serial.println(http.errorToString(httpCode));
}
http.end();
}
void loop() {
}
Here:
sends a GET request.
The server sends the response back to the ESP32.
2. POST Request Example
The POST method is commonly used to send new data to a server.
This is extremely important for IoT because sensors continuously produce data.
Suppose our soil moisture sensor gives:
Moisture = 320
The ESP32 can send this data to Laravel.
API Endpoint
Data Sent to Server
{
"device_id": "ESP32-01",
"moisture": 320
}
Laravel Example
In routes/api.php:
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::post('/soil-data', function (Request $request) {
return response()->json([
'message' => 'Data received successfully',
'device_id' => $request->device_id,
'moisture' => $request->moisture
]);
});
If the ESP32 sends:
{
"device_id": "ESP32-01",
"moisture": 320
}
Laravel can respond with:
{
"message": "Data received successfully",
"device_id": "ESP32-01",
"moisture": 320
}
ESP32 POST Example
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "YOUR_WIFI_NAME";
const char* password = "YOUR_WIFI_PASSWORD";
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting...");
}
Serial.println("WiFi Connected");
HTTPClient http;
http.begin("http://192.168.1.100:8000/api/soil-data");
http.addHeader("Content-Type", "application/json");
String jsonData = R"({
"device_id": "ESP32-01",
"moisture": 320
})";
int httpCode = http.POST(jsonData);
Serial.print("HTTP Status: ");
Serial.println(httpCode);
if (httpCode > 0) {
String response = http.getString();
Serial.println("Server Response:");
Serial.println(response);
}
http.end();
}
void loop() {
}
The important line is:
This sends the JSON data to Laravel.
3. POST with a Real Soil Moisture Sensor
Now let's make the example more realistic.
Suppose the soil moisture sensor is connected to:
The ESP32 reads the sensor:
int moisture = analogRead(34);
Then it sends the real value to Laravel.
Complete Example
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "YOUR_WIFI_NAME";
const char* password = "YOUR_WIFI_PASSWORD";
const int moisturePin = 34;
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting...");
}
Serial.println("WiFi Connected");
}
void loop() {
int moisture = analogRead(moisturePin);
Serial.print("Moisture: ");
Serial.println(moisture);
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin("http://192.168.1.100:8000/api/soil-data");
http.addHeader("Content-Type", "application/json");
String jsonData =
"{\"device_id\":\"ESP32-01\",\"moisture\":" +
String(moisture) +
"}";
int httpCode = http.POST(jsonData);
Serial.print("HTTP Status: ");
Serial.println(httpCode);
if (httpCode > 0) {
String response = http.getString();
Serial.println(response);
}
http.end();
}
delay(10000);
}
Now the complete flow is:
Soil Sensor → ESP32 → analogRead() → JSON → HTTP POST → Laravel
For example, if the sensor reads:
the ESP32 sends:
{
"device_id": "ESP32-01",
"moisture": 397
}
4. PUT Request Example
The PUT method is commonly used to update an existing resource.
Suppose we have a sensor:
We want to change its name to:
We can send:
with:
{
"name": "Greenhouse Sensor"
}
Laravel Example
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::put('/sensors/{id}', function (Request $request, $id) {
return response()->json([
'message' => 'Sensor updated successfully',
'id' => $id,
'name' => $request->name
]);
});
If we send:
{
"name": "Greenhouse Sensor"
}
the server may return:
{
"message": "Sensor updated successfully",
"id": 1,
"name": "Greenhouse Sensor"
}
ESP32 PUT Example
#include <WiFi.h>
#include <HTTPClient.h>
void setup() {
Serial.begin(115200);
WiFi.begin("YOUR_WIFI_NAME", "YOUR_WIFI_PASSWORD");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
HTTPClient http;
http.begin("http://192.168.1.100:8000/api/sensors/1");
http.addHeader("Content-Type", "application/json");
String data = R"({
"name": "Greenhouse Sensor"
})";
int httpCode = http.PUT(data);
Serial.print("HTTP Status: ");
Serial.println(httpCode);
if (httpCode > 0) {
Serial.println(http.getString());
}
http.end();
}
void loop() {
}
The important function is:
5. DELETE Request Example
The DELETE method is used to remove an existing resource.
Suppose we want to delete sensor ID 1.
We send:
Laravel Example
use Illuminate\Support\Facades\Route;
Route::delete('/sensors/{id}', function ($id) {
return response()->json([
'message' => 'Sensor deleted successfully',
'id' => $id
]);
});
The server can respond:
{
"message": "Sensor deleted successfully",
"id": 1
}
ESP32 DELETE Example
#include <WiFi.h>
#include <HTTPClient.h>
void setup() {
Serial.begin(115200);
WiFi.begin("YOUR_WIFI_NAME", "YOUR_WIFI_PASSWORD");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
HTTPClient http;
http.begin("http://192.168.1.100:8000/api/sensors/1");
int httpCode = http.sendRequest("DELETE");
Serial.print("HTTP Status: ");
Serial.println(httpCode);
if (httpCode > 0) {
Serial.println(http.getString());
}
http.end();
}
void loop() {
}
Here:
http.sendRequest("DELETE");
sends the DELETE request.
6. Using Postman to Test HTTP APIs
Before connecting the ESP32, it is a good idea to test our Laravel API using Postman.
For example, for GET:
GET http://127.0.0.1:8000/api/sensors/1
For POST:
POST http://127.0.0.1:8000/api/soil-data
Body:
{
"device_id": "ESP32-01",
"moisture": 320
}
For PUT:
PUT http://127.0.0.1:8000/api/sensors/1
Body:
{
"name": "Greenhouse Sensor"
}
For DELETE:
DELETE http://127.0.0.1:8000/api/sensors/1
Testing the API with Postman first makes debugging much easier.
7. Complete HTTP CRUD Example
A common application uses all four methods together.
Suppose we have a sensors resource.
Create Sensor
Data:
{
"name": "Garden Sensor"
}
Read Sensors
Read One Sensor
Update Sensor
Data:
{
"name": "Greenhouse Sensor"
}
Delete Sensor
This is commonly referred to as CRUD:
Create → POST
Read → GET
Update → PUT
Delete → DELETE
8. HTTP Status Code Example
Suppose the ESP32 sends sensor data:
If Laravel successfully receives and creates the data, it might return:
If the request is successful but simply retrieves data:
If the requested sensor does not exist:
If the data sent by the ESP32 is invalid:
If there is a problem on the Laravel server:
500 Internal Server Error
9. The Complete IoT Example
Let's combine everything into one practical scenario.
Our project contains:
Soil Moisture Sensor
↓
ESP32
↓
Wi-Fi
↓
Laravel API
↓
MySQL Database
The ESP32 reads:
It sends:
with:
{
"device_id": "ESP32-01",
"moisture": 397
}
Laravel stores the reading.
The web dashboard wants to display it.
It sends:
GET /api/soil-data/latest
Laravel returns:
{
"device_id": "ESP32-01",
"moisture": 397
}
The user changes the device configuration.
The dashboard sends:
PUT /api/devices/ESP32-01
The user later removes the device.
The application sends:
DELETE /api/devices/ESP32-01
This is how HTTP methods become part of a real IoT system.
Quick Revision
GET
Used to retrieve data.
Example:
POST
Used to send or create data.
Example:
PUT
Used to update existing data.
Example:
DELETE
Used to remove data.
Example: