Help - POST method request

I have been gone through this link https://arduinogetstarted.com/tutorials/arduino-http-request to understand POST method request using Arduino mega with ethernet shield.

I just want to understand how code send data and read response on API call using Arduino mega with ethernet shield.


#include <SPI.h>
#include <Ethernet.h>

// replace the MAC address below by the MAC address printed on a sticker on the Arduino Shield 2
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

EthernetClient client;

int    HTTP_PORT   = 80;
String HTTP_METHOD = "GET"; // or POST
char   HOST_NAME[] = "maker.ifttt.com";
String PATH_NAME   = "/trigger";

void setup() {
  Serial.begin(9600);

  // initialize the Ethernet shield using DHCP:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to obtaining an IP address using DHCP");
    while(true);
  }

  // connect to web server on port 80:
  if(client.connect(HOST_NAME, HTTP_PORT)) {
    // if connected:
    Serial.println("Connected to server");
    // make a HTTP request:
    // send HTTP header
    client.println(HTTP_METHOD + " " + PATH_NAME + " HTTP/1.1");
    client.println("Host: " + String(HOST_NAME));
    client.println("Connection: close");
    client.println(); // end HTTP header

    while(client.connected()) {
      if(client.available()){
        // read an incoming byte from the server and print it to serial monitor:
        char c = client.read();
        Serial.print(c);
      }
    }

    // the server's disconnected, stop the client:
    client.stop();
    Serial.println();
    Serial.println("disconnected");
  } else {// if not connected:
    Serial.println("connection failed");
  }
}

void loop() {

}

And what is your question?

Please edit the heading of your message because your thread is not a Tutorial

Here is a page that covers the differences between GET and POST requests:

I want to understand how POST request will be sent to server and how will read response on API call in code

Done

I have already visited this link but I want to understand clearly.

In the API call, let's say a value = 2 is sent to the server through the post method. I want to read the response of the server, suppose the server gives me two values, one is name and one is age,

How to read response name and age in given code in first post?

The type of data returned by the HTTP Server is returned in the HTTP header it returns. The data is in some format agreed on by the Client and the Server. The format must be documented somewhere.

You have read the reply from the Server and have written it to Serial Monitor. What do you see?

The only difference between GET and POST is that with GET, the query string is part of the first line of the request, and with a POST request the query is the last line.

//GET
GET /path/to/document?some=query&string=1 HTTP/1.1
Host: foo.bar
\r\n\r\n

//POST
POST /path/to/document HTTP/1.1
Host: foo.bar
\r\n\r\n
some=query&string=1

The response received from the server is the same.

I am being confused with following line in code

String queryString = "?value1=26&value2=70";;

How to modify line if I want to send following to server

"ID": "101.1"

Hard to answer since what you want to send is not part of what you would like to extract it from. What you want to send looks like JSON, so maybe you should look for a wrapper to handle that.

1 Like

Ohh, actually i want to send data in json and want to extract in json

something like

Body Params:
{
    ""ID": "101.1"
}

Response:
{
    "msg": "success",
    "data": [
        {
            "id": 1,
        }]
		

So serialize the query JSON into the body of your PUT request and deserialize the body of the response to get the response JSON. Use the Assistant to write most of the JSON code.

Serialize query:

  StaticJsonDocument<32> query;
  query["ID"] = "101.1";
  serializeJson(query, client);

Deserialize result:

  StaticJsonDocument<96> response;
  DeserializationError error = deserializeJson(response, client);
  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.f_str());
    return;
  }
  const char* msg = response["msg"]; // "success"
  int data_0_id = response["data"][0]["id"]; // 1
1 Like

Thanks a lot, How to integrate two parts of your sample codes with my code

Body Params:
{
    ""ID": "101.1"
}

Response:
{
    "msg": "success",  "data": [ { "id": 1,}]
}

Serialize query:

StaticJsonDocument<32> query;
  query["ID"] = "101.1";
  serializeJson(query, client);

Deserialize result:

StaticJsonDocument<96> response;
  DeserializationError error = deserializeJson(response, client);
  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.f_str());
    return;
  }
  const char* msg = response["msg"]; // "success"
  int data_0_id = response["data"][0]["id"]; // 1

sketch

#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoJson.h>

// replace the MAC address below by the MAC address printed on a sticker on the Arduino Shield 2
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

IPAddress ip(192, 168, 0, 5);

EthernetClient client;

int    HTTP_PORT   = 80;
String HTTP_METHOD = "POST";
char   HOST_NAME[] = "make.GDB.com";
String PATH_NAME   = "/trigger";


void setup() {
  Serial.begin(9600);

  // initialize the Ethernet shield using the static IP address:
  Ethernet.begin(mac, ip);
}

void loop() {
  // optional, check link status
  if (Ethernet.linkStatus() == LinkON)
    Serial.println("Link status: On");
  else
    Serial.println("Link status: Off");

      // connect to web server on port 80:
  if(client.connect(HOST_NAME, HTTP_PORT)) {
    // if connected:
    Serial.println("Connected to server");
    // make a HTTP request:
    // send HTTP header
  

    // send HTTP body

    while(client.connected()) {
      if(client.available()){
        // read an incoming byte from the server and print it to serial monitor:
        char c = client.read();
        Serial.print(c);
      }
    }
  }
}

I think, This three lines in the sketch would be change

    client.println(HTTP_METHOD + " " + PATH_NAME + " HTTP/1.1");
    client.println("Host: " + String(HOST_NAME));

    // send HTTP body
    client.println(queryString);`Preformatted text`

You have to end the header and then send the query document:

    client.println(HTTP_METHOD + " " + PATH_NAME + " HTTP/1.1");
    client.println("Host: " + String(HOST_NAME));
    client.println(); // End of header

    // send HTTP body
    StaticJsonDocument<32> query;
    query["ID"] = "101.1";
    serializeJson(query, client);

When you read the response, you read until you find the empty line that marks the end of the header and then do the deserialize.

1 Like

Am I doing deserialize correctly in my sketch ?

#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoJson.h>

// replace the MAC address below by the MAC address printed on a sticker on the Arduino Shield 2
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

IPAddress ip(192, 168, 0, 5);

EthernetClient client;

int    HTTP_PORT   = 80;
String HTTP_METHOD = "POST";
char   HOST_NAME[] = "make.GDB.com";
String PATH_NAME   = "/trigger";


void setup() {
  Serial.begin(9600);

  // initialize the Ethernet shield using the static IP address:
  Ethernet.begin(mac, ip);
}

void loop() {
  // optional, check link status
  if (Ethernet.linkStatus() == LinkON)
    Serial.println("Link status: On");
  else
    Serial.println("Link status: Off");

  // connect to web server on port 80:
  if (client.connect(HOST_NAME, HTTP_PORT)) {
    // if connected:
    Serial.println("Connected to server");
    // make a HTTP request:
    // send HTTP header

    client.println(HTTP_METHOD + " " + PATH_NAME + " HTTP/1.1");
    client.println("Host: " + String(HOST_NAME));
    client.println(); // End of header

    // send HTTP body
    StaticJsonDocument<32> query;
    query["ID"] = "101.1";
    serializeJson(query, client);


    StaticJsonDocument<96> response;
    DeserializationError error = deserializeJson(response, client);
    if (error) {
      Serial.print(F("deserializeJson() failed: "));
      Serial.println(error.f_str());
      return;
    }
    const char* msg = response["msg"]; // "success"
    int data_0_id = response["data"][0]["id"]; // 1

    while (client.connected()) {
      if (client.available()) {
        // read an incoming byte from the server and print it to serial monitor:
        char c = client.read();
        Serial.print(c);
      }
    }
  }
}

No, you are not processing response headers.

First you have to "read until you find the empty line that marks the end of the header". Otherwise, you are telling the JSON library to read the response headers and try to interpret them as JSON. That will fail.

1 Like

@johnwasser as you know this library is not suitable for my ethernet shield

I am trying with UIPEthernet library

How to make header request in the sketch ?

#include <UIPEthernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 10, 0, 0, 177 };
char server[] = { "www.simple.com"}; //

EthernetClient client;

void setup()
{
  Serial.begin(9600);

  Ethernet.begin(mac, ip);

  client.connect(server, 80);
  delay(1000);

  Serial.println("connecting...");

  if (client.connected()) {
    Serial.println("connected");
    client.println("POST / HTTP/1.1");

  }
  else {
    Serial.println("connection failed");
  }
}

void loop()
{
  

}

what i need to write in following line to post header request

` client.println("POST / HTTP/1.1");`

String PATH_NAME = "/trigger";

The rest of the request header, same as you were doing before:

    client.println("Host: " + String(HOST_NAME));
    client.println("Connection: close");
    client.println(); // end HTTP header

I have changed name HOST_NAME because I was getting following error

error: expected unqualified-id before string constant
#define HOST_NAME "ENC28J"

I am using HOST_NAME1

#include <UIPEthernet.h>
#include <ArduinoJson.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 10, 0, 0, 177 };

int    HTTP_PORT   = 80;
String HTTP_METHOD = "POST";
char HOST_NAME1[] = { "www.simple.com"}; //
String PATH_NAME   = "/trigger";

EthernetClient client;

void setup()
{
  Serial.begin(9600);

  Ethernet.begin(mac, ip);

  client.connect(HOST_NAME1, HTTP_PORT );
  delay(1000);

  Serial.println("connecting...");

  if (client.connected()) {
    Serial.println("connected");
   
    client.println(HTTP_METHOD + " " + PATH_NAME + " HTTP/1.1");
    client.println("Host: " + String(HOST_NAME1));
    client.println(); // End of header

    // send HTTP body
    StaticJsonDocument<32> query;
    query["ID"] = "101.1";
    serializeJson(query, client);

    
    StaticJsonDocument<96> response;
    DeserializationError error = deserializeJson(response, client);
    if (error) {
      Serial.print(F("deserializeJson() failed: "));
      Serial.println(error.f_str());
      return;
    }
    const char* msg = response["msg"]; // "success"
    int data_0_id = response["data"][0]["id"]; // 1

     while (client.connected()) {
      if (client.available()) {
        // read an incoming byte from the server and print it to serial monitor:
        char c = client.read();
        Serial.print(c);
      }
    }

  }
  else {
    Serial.println("connection failed");
  }
}

void loop()
{
  

}

How to find empty line that marks the end of the header ?
Is this what you said ?

  if (client.connected()) {
    Serial.println("connected");
   
    client.println(HTTP_METHOD + " " + PATH_NAME + " HTTP/1.1");
    client.println("Host: " + String(HOST_NAME1));
    client.println(); // End of header

    // send HTTP body
    StaticJsonDocument<32> query;
    query["ID"] = "101.1";
    serializeJson(query, client);

    
    StaticJsonDocument<96> response;
    DeserializationError error = deserializeJson(response, client);
    if (error) {
      Serial.print(F("deserializeJson() failed: "));
      Serial.println(error.f_str());
      return;
    }
    const char* msg = response["msg"]; // "success"
    int data_0_id = response["data"][0]["id"]; // 1

     while (client.connected()) {
      if (client.available()) {
        // read an incoming byte from the server and print it to serial monitor:
        char c = client.read();
        Serial.print(c);
        if (c == " ")
        {
          break;
        }
      }
    }