REST Client Library for Spark

I’ve been working on a project that requires multiple REST calls and unfortunately didn’t see the work going on here: https://community.spark.io/t/spark-core-http-client-library/3251

So I ported the simple RestClient for Arduino library to work with the Spark Core:

It is very simple to use.

#include "rest_client.h"

RestClient client = RestClient("your-rest-server.com");

//Setup
void setup() {
  Serial.begin(9600);
  Serial.println("starting...");

}

String response;
void loop(){
  response = ""; 
  int statusCode = client.get("/path", &response);
  Serial.print("Status code from server: ");
  Serial.println(statusCode);
  Serial.print("Response body from server: ");
  Serial.println(response);
  delay(1000);
}

More complex usage can be found here:

6 Likes

Looks very useful @mwdll thanks for porting this! I wonder if the POST method is working well with real data? Is there a way to do JSON formatting or is it only FORM-URLENCODED? This example looks like the latter:
statusCode = client.post("/", "foo=bar", &response);

This wraps things up nicely for GET and POST… and apparently strips off the HEADER info on the response for you?

Do you know if it processes CHUNKED data properly?

You can safely remove these from your examples:

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

@BDub Thanks. It is a simple library. You can set custom headers so you can set the content type to JSON and send it along as char pointer/array – should work but I haven’t tested. The default content type is form-urlencoded.

On the response, it grabs just the message body and puts that in the response string you pass by reference and returns the status as an int. It drops the headers.

I haven’t updated the examples from the repo that I forked, but when I get some time will drop those includes.

3 Likes

Excellent! Thank you very much for this. One question: It seems that this lib only returns the first line of the server answer. What changes would be needed to read a “full document”, that is, beyond the first line feed?

1 Like

Awesome!, thanks for sharing @mwdll.

1 Like

@akrusen glad you like it. All HTTP responses end with a new line AKA \n character. So the code looks for the end of the header section (two new lines in a row) and then reads until it encounters the next new line.

For the REST API cases I’ve needed to access, the new line character has worked fine. Most ones I’ve come across respond with JSON, which typically doesn’t have new lines characters.

Fully detecting the end of an http response is a lot more work than this library handles, especially if you get into chunked responses.

To get better, we could parse the content length out of the header and then use that to determine the end – that doesn’t work for chunks. Alternatively, you can read until the connection is closed, as @nmattisson looks to be doing in his library discussed here: https://community.spark.io/t/spark-core-http-client-library/3251

I will probably head toward the connection closed approach if I have a use case.

1 Like

Thank you, this is very helpful. I am just reading your code, and have a simple question in this regard:

Let’s assume I would want to go the “read as long as client.connected()” route with your code. Wouldn’t that work if I just removed line 203 to 206 from your current rest_client.cpp code?

(Return code & response on first \n)

Would I potentially run into trouble?

Your help is greatly appreciated!

Hi @mwdll!
We’re doing chunked reads in HttpClient, and you can probably copy the approach if you want to for your library.
Here is how it’s done (straight from the code comments):
The first value of client.available() might not represent the whole response, so after the first chunk of data is received instead of terminating the connection there is a delay and another attempt to read data.
The loop exits when the connection is closed, or if there is a timeout or an error.

Not that it matters too much, both of our libraries are pretty thin, but from a purely aesthetic standpoint I’d say it makes sense for a REST library to utilise an HTTP library, and not for them to sit next to one another. (Performance may be another matter). If you want to use HttpClient I’m more than happy to help you should you need! We’ve since moved on a bit for our prototyping, HTTP was quick and easy but now we’re switching over to CoAP.

Perfekt! Thank you very much for this Library. Sorry, my english is not good but I dry it.

My url in a browser response this json:

array(1) { ["color"]=> array(3) { [0]=> int(255) [1]=> int(100) [2]=> int(100) } }

If I send a get to my API the REST Client for Spark show me this:

 Status code from server: 200
 Response body from server: 71

71 is the body of the response. Is it possible to save the values to variables?

This is awesome! I’d been struggling on and off with getting my Core to make HTTP requests repeatedly (triggered by a button) and this has made it so easy. Thanks @mwdll!

Is this library working for local URLs. I always get connection error when I try to get a response from the REST API of openhab. I can get http://httbin.org/get however without any problem? any Idea what this might be?

I’m trying to use this library on a Photon. I wanted to test it out with the simple_GET.ino example. It flashed ok, the Photon restarts, connects to the cloud but then gives me the red SOS LED followed by one red blink. Anyone else have this issue?

More tests and comments here about the REST Client Library with the Photon. It’s currently still not working (with firm. v0.4.4-rc2) due to an issue with the TCPClient library on the Photon.