NuriaProject Framework  0.1
The NuriaProject Framework
Public Member Functions | Protected Member Functions | Friends | List of all members
Nuria::RestfulHttpNode Class Reference

The RestfulHttpNode class makes it easy to write RESTful APIs. More...

#include <restfulhttpnode.hpp>

Inheritance diagram for Nuria::RestfulHttpNode:
Nuria::HttpNode

Public Member Functions

 RestfulHttpNode (void *object, MetaObject *metaObject, const QString &resourceName, HttpNode *parent=0)
 
 RestfulHttpNode (const QString &resourceName=QString(), HttpNode *parent=0)
 
 ~RestfulHttpNode ()
 
void setRestfulHandler (HttpClient::HttpVerbs verbs, const QString &path, const QStringList &argumentNames, const Callback &callback, bool waitForRequestPostBody=true)
 
void setRestfulHandler (const QString &path, const QStringList &argumentNames, const Callback &callback, bool waitForRequestPostBody=true)
 
- Public Member Functions inherited from Nuria::HttpNode
 HttpNode (const QString &resourceName, HttpNode *parent=0)
 
 HttpNode (QObject *parent=0)
 
 ~HttpNode ()
 
bool addNode (HttpNode *node)
 
SlotInfo connectSlot (const QString &name, const Callback &callback)
 
SlotInfo connectSlot (const QString &name, QObject *receiver, const char *slot)
 
bool disconnectSlot (const QString &name)
 
bool isChild () const
 
HttpNodeparentNode () const
 
const QString & resourceName () const
 
const QDir & staticResourceDir () const
 
StaticResourcesMode staticResourceMode () const
 
bool setResourceName (const QString &name)
 
void setStaticResourceDir (QDir path)
 
void setStaticResourceMode (StaticResourcesMode mode)
 
bool hasNode (const QString &name)
 
bool hasSlot (const QString &name)
 
HttpNodefindNode (const QString &name) const
 

Protected Member Functions

virtual void conversionFailure (const QVariant &variant, HttpClient *client)
 
virtual QVariant convertArgumentToVariant (const QString &argumentData, int targetType)
 
virtual QByteArray generateResultData (const QVariant &result, HttpClient *client)
 
bool invokePath (const QString &path, const QStringList &parts, int index, HttpClient *client) override
 
virtual QVariant serializeVariant (const QVariant &variant)
 
- Protected Member Functions inherited from Nuria::HttpNode
virtual bool allowAccessToClient (const QString &path, const QStringList &parts, int index, HttpClient *client)
 
virtual bool callSlotByName (const QString &name, HttpClient *client)
 
bool sendStaticResource (const QString &name, HttpClient *client)
 
bool sendStaticResource (const QStringList &path, int indexInPath, HttpClient *client)
 

Friends

class RestfulHttpNodePrivate
 

Additional Inherited Members

- Public Types inherited from Nuria::HttpNode
enum  StaticResourcesMode { NoStaticResources = 0, UseStaticResources = 1, UseNestedStaticResources = 2 }
 

Detailed Description

The RestfulHttpNode class makes it easy to write RESTful APIs.

This class was designed to be as flexible as possible when it comes to convenience from a remote API standpoint. You use this just like a HttpNode, with the exception that slots are allowed to return something.

Usage of this class
To expose your own service in a RESTful manner, all you need to do is to sub-class this class and tag it with NURIA_INTROSPECT as usual for Tria to pick up annotations. Also make sure that the Q_OBJECT macro is in place.
Warning
Not doing so will output an error message and likely crash the application.

If you don't want to sub-class RestfulHttpNode, you can use the constructor which takes a object pointer and a MetaObject instance.

Regardless which option you choose, you can then annotate methods you want to expose using NURIA_RESTFUL() (and optionally with NURIA_RESTFUL_VERBS()). When using this route all handlers (i.e. NURIA_RESTFUL methods) are registered automatically when the first invocation on the node happens.

See also
setRestfulHandler()
Request types
By default, a handler is invoked regardless of the HTTP verb used by the client. You can register multiple methods on the same path while distinguishing between the different verbs using NURIA_RESTFUL_VERBS(). The same is possible using setRestfulHandler().
RESTful arguments
The path string may contain names enclosed in curly braces ("{}") to mark variable parts. These names are expected to directly match those in the parameter list of the method. The value extracted from the invoked path must be compatible to the argument type - This means that the value must be convertible from a QString to the type.

If the method has a argument of type 'Nuria::HttpClient*', the HttpClient behind the request will be passed as value for this parameter.

To validate arguments prior calling, use the generic NURIA_REQUIRE() approach.

You can also completely alter this behaviour by reimplementing

Note
When using Tria, suitable conversion facilities are already in place if your type offers conversion methods of some kind.
See also
Variant::registerConversion
Sending replies to the client
To send a response, you can choose to either directly write() something to the client (See previous paragraph on how to obtain the HttpClient instance), or your method can return the result. The result type must be convertible to QByteArray or QString. If a QVariantMap or QVariantList is returned, then it will be serialized to JSON formatted data and sent as response.

It's also possible to return a custom type if Nuria::Serializer is able to serialize it to a QVariantMap.

You can change the behaviour of this by reimplementing convertVariantToData(). If you want to customize the behaviour when conversion fails, reimplement conversionFailure().

See also
convertVariantToData conversionFailure

Constructor & Destructor Documentation

Nuria::RestfulHttpNode::RestfulHttpNode ( void *  object,
MetaObject metaObject,
const QString &  resourceName,
HttpNode parent = 0 
)
explicit

Constructor. The node will operate on object of type metaObject. Ownership of object is not transferred. If you want to do this, you could e.g. connect to the destroyed() signal of this instance to deleteLater() of object, if object is a QObject. Another option would be connecting a lambda which destroys object to destroyed().

Nuria::RestfulHttpNode::RestfulHttpNode ( const QString &  resourceName = QString(),
HttpNode parent = 0 
)
explicit

Constructor.

Nuria::RestfulHttpNode::~RestfulHttpNode ( )

Destructor.

Member Function Documentation

virtual void Nuria::RestfulHttpNode::conversionFailure ( const QVariant &  variant,
HttpClient client 
)
protectedvirtual

Called if the conversion for variant failed. When this happens the reply is pretty much lost to the client. The default implementation loggs this as a error message and sends a 500 reply code to client.

virtual QVariant Nuria::RestfulHttpNode::convertArgumentToVariant ( const QString &  argumentData,
int  targetType 
)
protectedvirtual

Takes argumentData and returns a QVariant of type targetType. Returns a invalid QVariant on failure. The behaviour of the default implementation is outlined in the class documentation above.

virtual QByteArray Nuria::RestfulHttpNode::generateResultData ( const QVariant &  result,
HttpClient client 
)
protectedvirtual

Converts result to a QByteArray. A empty QByteArray is treated as error. Also responsible for setting response headers specific to the format, e.g. Content-Type for JSON.

Note
Override serializeVariant() instead for easier use if you want to change how a specific type in a QVariant is converted.
bool Nuria::RestfulHttpNode::invokePath ( const QString &  path,
const QStringList &  parts,
int  index,
HttpClient client 
)
overrideprotectedvirtual

Does the invocation.

Reimplemented from Nuria::HttpNode.

virtual QVariant Nuria::RestfulHttpNode::serializeVariant ( const QVariant &  variant)
protectedvirtual

Takes variant and tries to convert it to a QVariant only consisting out of POD- and some Qt types.

Allowed types:

  • QVariantMap, QVariantList (And everything convertable to those)
  • QString, QByteArray, QDateTime, QTime, QDate
  • bool, int, long long, etc. (Except for pointer types)

When re-implementing this method call the default implementation if you don't handle this type:

return HttpNode::convertVariantToData (variant);

If the result is invalid the conversion failed.

void Nuria::RestfulHttpNode::setRestfulHandler ( HttpClient::HttpVerbs  verbs,
const QString &  path,
const QStringList &  argumentNames,
const Callback callback,
bool  waitForRequestPostBody = true 
)

Manually registers a RESTful handler which will be invoked when path is requested with a HTTP verb in verbs. In this case, arguments are read from the requested path as defined in path and are passed to callback in the order defined by argumentNames.

When dealing with POST/PUT bodies, the default is to wait for the whole body to be received and then invoke the handler. This can be overriden by passing false for waitForRequestPostBody.

Note
When callback expects a argument of type 'Nuria::HttpClient*', the name of this argument is expected to be omitted in argumentNames!
void Nuria::RestfulHttpNode::setRestfulHandler ( const QString &  path,
const QStringList &  argumentNames,
const Callback callback,
bool  waitForRequestPostBody = true 
)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. Does the same as the other setRestfulHandler(), but assumes a value of HttpClient::AllVerbs for verbs.


The documentation for this class was generated from the following file: