Hi there,
I want to build a RESTful webservice. I could use some advice on my draft.
I found an example on how to build a soap-webservice here and used the structure of it.
Here's the interface of an resource:
#include <QString>
#include <QxtWebServiceDirectory>
#include <QxtWebRequestEvent>
class IResource : public QxtWebServiceDirectory
{
Q_OBJECT
public:
IResource
(QString name, QxtAbstractWebSessionManager
* sm,
QObject* parent
= 0): QxtWebServiceDirectory(sm, parent),
name(name)
{
}
virtual ~IResource()
{
}
protected:
void indexRequested(QxtWebRequestEvent *event)
{
if (event->method.compare("GET") == 0)
{
doGET(event);
}
else if (event->method.compare("PUT") == 0)
{
doPUT(event);
}
else if (event->method.compare("POST") == 0)
{
doPOST(event);
}
else if (event->method.compare("DELETE") == 0)
{
doDELETE(event);
}
else
{
// not implemented - status code: 501
}
}
private:
void doGET(QxtWebRequestEvent *event)
{
// for now just say your name
postEvent(new QxtWebPageEvent(event->sessionID, event->requestID, name.toAscii()));
}
void doPUT(QxtWebRequestEvent *event)
{
}
void doPOST(QxtWebRequestEvent *event)
{
}
void doDELETE(QxtWebRequestEvent *event)
{
}
};
#include <QString>
#include <QxtWebServiceDirectory>
#include <QxtWebRequestEvent>
class IResource : public QxtWebServiceDirectory
{
Q_OBJECT
public:
IResource(QString name, QxtAbstractWebSessionManager* sm, QObject* parent = 0):
QxtWebServiceDirectory(sm, parent),
name(name)
{
}
virtual ~IResource()
{
}
protected:
void indexRequested(QxtWebRequestEvent *event)
{
if (event->method.compare("GET") == 0)
{
doGET(event);
}
else if (event->method.compare("PUT") == 0)
{
doPUT(event);
}
else if (event->method.compare("POST") == 0)
{
doPOST(event);
}
else if (event->method.compare("DELETE") == 0)
{
doDELETE(event);
}
else
{
// not implemented - status code: 501
}
}
private:
void doGET(QxtWebRequestEvent *event)
{
// for now just say your name
postEvent(new QxtWebPageEvent(event->sessionID, event->requestID, name.toAscii()));
}
void doPUT(QxtWebRequestEvent *event)
{
}
void doPOST(QxtWebRequestEvent *event)
{
}
void doDELETE(QxtWebRequestEvent *event)
{
}
QString name;
};
To copy to clipboard, switch view to plain text mode
Each resource should implement the Http-methods (to do something useful)
A session manager or as I called it a "dispatcher" handles the requests (sorry about the naming confusion):
#include <QxtHttpSessionManager>
#include "IResource.h"
class WebserviceDispatcher : public QxtHttpSessionManager
{
Q_OBJECT
public:
WebserviceDispatcher
(const QHostAddress &host , quint16 port
) {
QxtHttpSessionManager(this);
rootService = new IResource("root", this, this);
setPort(port);
setListenInterface(host);
setConnector(HttpServer);
setStaticContentService(rootService);
qDebug() << "WebServer Started!";
}
virtual ~WebserviceDispatcher()
{
delete this->rootService;
}
void addService
(QString uri, IResource
* newService
) {
rootService->addService(uri, newService);
}
protected:
void incomingRequest
(quint32 requestID,
const QHttpRequestHeader & header, QxtWebContent
*deviceContent
) {
QxtHttpSessionManager::incomingRequest(requestID, header, deviceContent);
qDebug() << "Request: "<< requestID;
qDebug() << "Method: " << header.method();
qDebug() << "URI: " << header.path();
}
private:
IResource* rootService;
};
#include <QxtHttpSessionManager>
#include "IResource.h"
class WebserviceDispatcher : public QxtHttpSessionManager
{
Q_OBJECT
public:
WebserviceDispatcher(const QHostAddress &host , quint16 port)
{
QxtHttpSessionManager(this);
rootService = new IResource("root", this, this);
setPort(port);
setListenInterface(host);
setConnector(HttpServer);
setStaticContentService(rootService);
qDebug() << "WebServer Started!";
}
virtual ~WebserviceDispatcher()
{
delete this->rootService;
}
void addService(QString uri, IResource* newService)
{
rootService->addService(uri, newService);
}
protected:
void incomingRequest(quint32 requestID, const QHttpRequestHeader & header, QxtWebContent *deviceContent)
{
QxtHttpSessionManager::incomingRequest(requestID, header, deviceContent);
qDebug() << "Request: "<< requestID;
qDebug() << "Method: " << header.method();
qDebug() << "URI: " << header.path();
}
private:
IResource* rootService;
};
To copy to clipboard, switch view to plain text mode
finally main looks like this:
#include <QtCore/QCoreApplication>
#include "WebserviceDispatcher.h"
#include "IResource.h"
int main(int argc, char *argv[])
{
WebserviceDispatcher
* myDispatcher
= new WebserviceDispatcher
(QHostAddress("localhost"),
8080);
IResource* service1 = new IResource("service1", myDispatcher, 0);
IResource* service2 = new IResource("service2", myDispatcher, 0);
IResource* subService1 = new IResource("subService1", myDispatcher, service1);
IResource* subService2 = new IResource("subService2", myDispatcher, service2);
service1->addService("sub1", subService1);
myDispatcher->addService("service1", service1);
service2->addService("sub2", subService2);
myDispatcher->addService("service2", service2);
myDispatcher->start();
return a.exec();
}
#include <QtCore/QCoreApplication>
#include "WebserviceDispatcher.h"
#include "IResource.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
WebserviceDispatcher* myDispatcher = new WebserviceDispatcher(QHostAddress("localhost"), 8080);
IResource* service1 = new IResource("service1", myDispatcher, 0);
IResource* service2 = new IResource("service2", myDispatcher, 0);
IResource* subService1 = new IResource("subService1", myDispatcher, service1);
IResource* subService2 = new IResource("subService2", myDispatcher, service2);
service1->addService("sub1", subService1);
myDispatcher->addService("service1", service1);
service2->addService("sub2", subService2);
myDispatcher->addService("service2", service2);
myDispatcher->start();
return a.exec();
}
To copy to clipboard, switch view to plain text mode
this example is working and lets you navigate to the uris:
The service shall provide and accept json objects.
I am not an expert on the topic so any opinion is appreciated (more precisely: is that the intended use of the qxt-classes? Has anyone done that better already and is willing to share ideas?)
Thanks
Bookmarks