I'm trying to write some code for the Arduino Uno WiFi Rev2 board. Specifically, I'd like to send some data, using a POST HTTP request, to an API Endpoint that I wrote. I've tested this endpoint with Postman, and it works fine. However, when I try POSTing my data using the WiFiNina library (https://www.arduino.cc/en/Reference/WiFiNINA), the request never makes it to my endpoint.
My Arduino sketch consists of two files. The first is my "main" file that serves as the entrypoint for my code and deals with most of my code's functionality. In this file, I setup the WiFiClient as instructed in Arduino's documentation:
#define URL "myappdomain.azurewebsites.net"
...
WiFiClient client;
int status = WL_IDLE_STATUS;
...
void setup(){
...
status = WiFi.begin(WifiSSID, WifiPassword);
while (WiFi.status() != WL_CONNECTED) { //Wait for the WiFI connection completion
delay(500);
Serial.println("Waiting for connection");
}
...
}
...
void loop(){
...
String requestBody =
"{\n \"clientReadings\": {\n \"sensorA\": [],\n \"sensorB\": []\n },\n \"deviceId\": 1,\n \"millilitersConsumed\" : 999\n}";
//send the request
postData(requestBody);
...
}
In my second file, here's the part of my code that handles this API request:
void postData(String body){
if(WiFi.status()== WL_CONNECTED){ //Check WiFi connection status
if (client.connect(URL, 80)){
client.println("POST /api/PGWC HTTP/1.1");
client.print("Host: ");
client.println(URL);
client.println("Content-type: application/json");
client.println("Accept: */*");
client.println("Cache-Control: no-cache");
client.print("Host: ");
client.println(URL);
client.println("Accept-Encoding: gzip, deflate");
client.print("Content-Length: ");
client.println(body.length());
client.println("Connection: close");
client.println();
client.println(body);
}else{
Serial.println("Error connecting to server");
}
}
}
I've structured this request based off examples and documentation I've found online for the WiFiNina library. (Here's one example: https://www.arduino.cc/en/Reference/WiFiNINAClient). The header information and the body are based off the requests I've sent through Postman, so I believe that the content of my request is accurate. I believe that I'm able to connect to the server via the "client.connect" line because I never see the error message printed to the Serial monitor, but I have seen the Serial Monitor display the contents of "Serial.println" statements that I placed prior to my "client.println" statements. However, the Azure Function App that hosts the API endpoints shows no indication that the API endpoint was hit. When I send this same data with Postman, the function app logs the connection just fine.
When I try printing the contents of the body, URL, and body.length() to the Serial monitor from within the postData function, everything appears as expected. Further, I've tried different options on the "Connection: close" line to no avail.
For reference, here's the content that Postman tells me it's sending when it successfully hits the API endpoint. I've also tried port 443. It works fine in Postman, but, again, not in the Arduino.
Host: myappdomain.azurewebsites.net:80
Content-Type: application/json
User-Agent: PostmanRuntime/7.17.1
Accept: */*
Cache-Control: no-cache
Postman-Token: [some UUID, some other UUID]
Host: myappdomain.azurewebsites.net:80
Accept-Encoding: gzip, deflate
Content-Length: 130
Connection: keep-alive
cache-control: no-cache
{
"clientReadings": {
"sensorA": [],
"sensorB": []
},
"deviceId": 1,
"millilitersConsumed" : 123
}```
(I've changed the domain for this post, so this request won't work if you try to plug it into Postman because myappdomain.azurewebsites.net is not my real domain)
EDIT: figured it out.
turns out
wifi.println("Content-Length: " + body.length());
is not the same as
wifi.println("Content-Length: " + String(body.length()));
the body length var needs to be wrapped as a string then it works fine
What confused me was seeing the OP write it as
I did not think it needed to be wrapped as a String, but I guess when concatenating strings its different.
Also it was curious I needed this header to begin with (the REST app didn't require it to work) and to have a correct body value, using something like 200 caused the connection to hang (but on the REST app setting it to something generic like 200 worked fine as well)
END EDIT ...leaving original content below for reference
I am trying to figure this out as well, so this is an extended comment rather than an answer.
When I use an app like postman (rested) it works I get 200 response, but from arduino uno wifi rev2 it fails with
HTTP/1.1 422 Unprocessable Entity
{"reason":"Unprocessable Entity","error":true}
my json is just
String body = "{\n \"value\": 500\n}";
and inside
if (wifi.connect(serverAddress, port)) {
I call
fwiw a get request works fine