Working with JSON data

The Request and Response classes both implement the Arduino Stream interface. This makes it possible to directly forward them to Arduino JSON libraries for parsing and serializing.

The example uses the aJSON library. The app has two routes: one or reading the JSON encoded data and one for updating it.

#include <WiFi.h>
#include <aJSON.h>
#include "aWOT.h"

WiFiServer server(80);
Application app;

char* userFilter[3] = {"name", "password", NULL};
aJsonObject* user = aJson.parse("{\"name\":\"John Smith\",\"password\":\"secret\"}");

void readUser(Request & req, Response & res) {
  res.set("Content-Type", "application/json");
  aJsonStream stream(&res);
  aJson.print(user, &stream);
}

void updateUser(Request & req, Response & res) {
  aJsonStream stream(&req);

  aJsonObject* newUser = aJson.parse(&stream, userFilter);
  if (!newUser) {
    return res.sendStatus(400);
  }

  aJsonObject* name = aJson.getObjectItem(newUser, "name");
  if (!name || name->type != aJson_String) {
    return res.sendStatus(400);
  }

  aJsonObject* password = aJson.getObjectItem(newUser, "password");
  if (!password || password->type != aJson_String) {
    return res.sendStatus(400);
  }

  aJson.deleteItem(user);
  user = newUser;

  return readUser(req, res);
}

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

  WiFi.begin("network", "password");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(WiFi.localIP());

  app.get("/user", &readUser);
  app.put("/user", &updateUser);

  server.begin();
}

void loop() {
  WiFiClient client = server.available();

  if (client.connected()) {
    app.process(&client);
  }
}

You can test the api with curl. To read the current data:

$ curl 'http://192.168.1.140/user' -v
*   Trying 192.168.1.140...
* TCP_NODELAY set
* Connected to 192.168.1.140 (192.168.1.140) port 80 (#0)
> GET /user HTTP/1.1
> Host: 192.168.1.140
> User-Agent: curl/7.54.0
> Accept: */*
> 
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Content-Type: application/json
< 
* Closing connection 0
{"name":"John Smith","password":"secret"}

And to update:

$ curl 'http://192.168.1.140/user' -X PUT -H "Content-Type: application/json" -d '{"name":"4N0NYM0U5", "password":"pwn3d"}' -v
*   Trying 192.168.1.140...
* TCP_NODELAY set
* Connected to 192.168.1.140 (192.168.1.140) port 80 (#0)
> PUT /user HTTP/1.1
> Host: 192.168.1.140
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 40
> 
* upload completely sent off: 40 out of 40 bytes
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Content-Type: application/json
< 
* Closing connection 0
{"name":"4N0NYM0U5","password":"pwn3d"}