19.3.2015

foto Petr Bravenec

Petr Bravenec
Twitter: @BravenecPetr
+420 777 566 384
petr.bravenec@hobrasoft.cz

Few weeks ago I described simple http server for Qt. How we use the server?

You can find overview of http server here: Our work - Http Server for C++ and Qt

We use the server for embedded application built on BeagleBone Black. Of course, we do not want to generate HTML code in C++ so we try to make it simple and all pages have unified structure.

HTTP page structure

  • Static html part. Common parts (header, footer) are server-side includes. All forms are empty, tables contains only headers - all variable data are leaved empty and identified with there id only.
  • JavaScript - every page has its own code which obtains JSON data from server and includes data to html page.
  • Applications often show their current inner state - if someone press a button, the web interface must show such information immediately. We use HTML5 event stream for this job.
  • Sometime it is needed to modify data and pass the changes to application. Web forms passes the data in JSON structures, JavaScript converts the form data to JSON.
  • Some application must be accessible not only from web browser but also from other information system. Universal and unified interface is a plus.

API is not direct part of server. It can be found in an example bundled with server. Brief description can be found in class documentation AbstractController.

Most data structures and access to applications data are made in the same manner. Application shows simple list of items, clicking the item form is opened, clicking to "Save" button the changes are stored, clicking to "Delete" the item is deleted.

How the API looks?

Requests served by AbstractController class look uniformly:

GET     http://localhost:8086/room                  // Returns rooms list
GET     http://localhost:8086/room/events           // Event stream, all rooms
GET     http://localhost:8086/room/e40f2a           // Returns room id=e40f2a
GET     http://localhost:8086/room/e40f2a/events    // Event stream, only single room

To access data also other HTTP methods can be used: GET, PUT, POST and DELETE. Methods PUT a POST are used to store items, method DELETE is used to delete the item:

PUT     http://localhost:8086/room/e40f2a           // Stores passed data
DELETE  http://localhost:8086/room/e40f2a           // Deletes room id=e40f2a

Derived class implementation

Following virtual methods can be overloaded in the class AbstractController:

  • serviceList()
  • serviceEvents()
  • serviceIdEvents()
  • serviceIdGet()
  • serviceIdDelete()
  • serviceIdPut()
  • serviceIdPost()

Is is sufficient to derive only such method which you want to use. Implementation can be very simple:

void ControllerRoom::serviceIdGet(
            HobrasoftHttp::HttpRequest *request, 
            HobrasoftHttp::HttpResponse *response, 
            const QString& id
            ) {
    // Check is not needed
    // ROOMSLIST is an object with list of all rooms
    // Method room(id) return the room class instance
    serviceOK(request, response, ROOMSLIST->room(id))
}

Method serviceOK() requests the abstract class to return HTTP reply "200 OK" with passed data. Data structure is described bellow. All data are converted to JSON format.

If you want to send an error message instead of "200 OK", use the serviceError() method.

But is is not needed to make basic check. Abstract class cares about basic checks - you only have to reimplement the exists() method - it should return true, if the ID exists:

bool ControllerRoom::exists(const QString& id) {
    return ROOMSLIST->contains(id);
}

It is not needed to reimplement methods which are not used actually. Default implementation return error 501.

Data structures

Data are passed in structured container QVariantMap. You can create the structure like this:

QVariantMap data;
data["ID"] = "e40f2a";
data["Description"] = "Name of the room";
QVariantList list;
list << "abc" << "xyz";
data["List"] = list;

Corresponding JSON structure look like this:

{ "ID" : "e40f2a", "Description" : "Name of the room", "List" : [ "abc", "xyz" ] }

Conclusion

Are you interested in HTTP C++ server? Stay tuned, watch our twitter or this blog. We have prepared article about HTML5 event stream for you.

Hobrasoft s.r.o. | Contact