RESTful WEB Services

REST is an acronym for REpresentational State Transfer, this term is coined by Roy Fielding in his Ph.D. dissertation to describe an architecture design of networked systems. Below Roy Fielding’s explanation of the meaning of REST:

Representational State Transfer is intended to evoke an image of how a well-designed Web application behaves: a network of web pages (a virtual state-machine), where the user progresses through an application by selecting links (state transitions), resulting in the next page (representing the next state of the application) being transferred to the user and rendered for their use.

As you see, REST is an approach, not a standard, and he does not deal with implementation details. REST is one of architectural Web Services design. So, REST defines a set of architectural principles by witch you can build WS oriented resource. REST become in last year the predominant WS design model used in the globe, because it’s the simplest one.

Note that RESTful WS does not mean that the output should be in JSON format. This is a big conflict, the result can be in any format as JSON, XML. Personally, I prefer always to use JSON format.

REST Principles

A REST Web service is any Web service that follows four basic design principles:

In the following sections, I will try to explain each of these principles.

Use HTTP methods explicitly

REST Web services should using HTTP methods explicitly following the protocol definition. So, our web service should be consistent with the protocol definition. In fact we should use the appropriate HTTP method for every CRUD operations:

  • To create a resource on the server, use POST.
  • To retrieve a resource, use GET.
  • To change the state of a resource or to update it, use PUT.
  • To remove or delete a resource, use DELETE.

Be stateless

Each request from the client should contains all the information needed for the Web service to understand it. This constraint improve the visibility, reliability, and scalability. This means that third-party as proxies in communication patterns (and this will increase scalability). Unfortunately, this will decrease network performance by increasing the repetitive data (per-interaction overhead) sent in a series of requests, since that data cannot be left on the server in a shared context.

Expose directory structure-like URIs

REST Web service URIs should be so intuitive that we can easily to guess, it should be self-documented. This type of URI should be hierarchical, rooted at a single path, and branching from it are subpaths that expose the service’s main areas. It’s also recommended to follow this guidelines:

  • Hide the server-side scripting technology file extensions (.jsp, .php, .asp)
  • Keep everything lowercase (even it’s inconsistent with W3C rule).
  • Substitute spaces with hyphens or underscores.
  • Avoid query strings as much as you can.

Transfer XML, JavaScript Object Notation

A resource representation should be in a standard format. The most format used in REST Web services are: XML, JSON, and HTML. This is where it really pays to keep things simple, and human-readable.

Advertisements

SOLID Principles: Part One

Nowadays, Object Oriented Programming (OOP) is the most commonly software design used by a huge numbers of  software engineer and developers under the whole world. Most of us are familiar with several OOPs concepts as classes, objects, inheritance, etc. Did you have properly designed your software? Did your software is maintainable over time? Did your software is scalable? Many nightmares vanishes when our design follow SOLID design principles and best practices.

SOLID is an mnemonic acronym for five object-oriented design principles defined by Robert C, Martin (aka Uncle Bob):

  • Single Responsibility Principle
  • Open Closed Principle
  • Liskov Substitution Principle
  • Interface Segregation Principle
  • Dependency Inversion Principle

Single Responsibility Principle (SRP)

THERE SHOULD NEVER BE MORE THAN ONE REASON FOR A CLASS TO CHANGE.

This means that a class should have one, and only one, responsibility: A class should do only one thing, because if a class have more than one responsibility, implementing a change would be more difficult than implementing the same on a class that have only one responsibility.

So let’s consider the following example that defines how activities are handled in an issue tracking system.

class ActivityHandler(object):
    def __init__(self, db, query_engine, email_sender):
        self.db = db
        self.query_engine = query_engine
        self.email_sender = email_sender

    def add_activity(self, activity):
        self.db.add(activity)

    def update_activity(self, activity):
        self.db.update(activity)

    def delete_activity(self, activity):
        self.db.delete(activity)

    def notify(self, activity):
        self.email_sender.send(str(activity), activity.user.email)

    def get_all_activities(self, user):
        return self.query_engine.run("SELECT * FROM activity WHERE assigned = " + user.id)

So, What’s do our class ?

  • Basic CRUD operations, We could find in the near future that we should do validation on this methods
  • listing jobs for a specific user, adding some enhancements like search, pagination, sort could be very complex operation
  • Notifying user about activity

This is a lot of responsibilities for one class. Let’s design it properly: A good solution should be like that:

class ActivityRepository(object):
    def __init__(self, db):
        self.db = db

    # CRUD operations here
    def add_activity(self, activity):
        ...

class ActivitySearchQuery(object):
    def __init__(self, query_engine):
        self.query_engine = query_engine

    def get_all_activities(self, user):
        return self.query_engine.run("SELECT * FROM activity WHERE assigned =" + user.id)

class ActivityMonitor(object):
    def __init__(self, email_sender):
        self.email_sender = email_sender

    def notify(self, activity):
        self.email_sender.send(activity, activity.user.email)

So the advantage of SRP are:

  • increase reusability
  • decrease the cohesion between modules: To add a new requirement, fixbug, etc I had to make my changes in only one place.
  • Classes are in understandable units
  • avoid unwanted side-effects: 1 requirement ==> 1 place
  • increase testability

Dbus | C API (Part 1)

My first experience with Dbus started in 2010. My challenge was to manage the communication between the differents parts as: decoder (C), UI (C++), the xosd interface, and the remote controller interface  (C).

What’s Dbus ?

Dbus is a message bus system, it allows applications to communicate to each other in a simple way. Currently the communicating applications are on one computer, or through unencrypted TCP/IP suitable for use behind a firewall with shared NFS home directories. It is simultaneously an Inter-Process Communication (IPC) and Remote Procedure Calling (RPC) mechanism. In Dbus we have two kind of sessions:

  • A “system bus” for communicating between system applications and user sessions
  • A “session bus” for exchanging data between applications in a desktop environments

Code

Let’s go now to the real life: To connect to Dbus you should

  • Initialize the errors

DBusError err;
DBusConnection* conn;
int ret;
// initialize the errors
dbus_error_init(&err);

  • Connect to the dbus

conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
if (dbus_error_is_set(&err)) {
 fprintf(stderr, "Connection Error (%s)\n", err.message);
 dbus_error_free(&err);
}
if (NULL == conn) {
 exit(1);
}

    • Now, you need to request a name on the bus

ret = dbus_bus_request_name(conn, "test.method.server",
                            DBUS_NAME_FLAG_REPLACE_EXISTING
                            , &err);
if (dbus_error_is_set(&err)) {
  fprintf(stderr, "Name Error (%s)\n", err.message);
  dbus_error_free(&err);
}
if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
  exit(1);
}

  • After you have finished with the bus, you should close the connection:
dbus_connection_close(conn);
  1. Sending a signal

This is the simplest operation, the below code do the entirely operation

dbus_uint32_t serial = 0; // unique number to associate replies with requests
DBusMessage* msg;
DBusMessageIter args;

// create a signal and check for errors
msg = dbus_message_new_signal("/test/signal/Object", // object name of the signal
"test.signal.Type", // interface name of the signal
"Test"); // name of the signal
if (NULL == msg)
{
fprintf(stderr, "Message Null\n");
exit(1);
}

// append arguments onto signal
dbus_message_iter_init_append(msg, &args);
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &sigvalue)) {
fprintf(stderr, "Out Of Memory!\n");
exit(1);
}

// send the message and flush the connection
if (!dbus_connection_send(conn, msg, &serial)) {
fprintf(stderr, "Out Of Memory!\n");
exit(1);
}
dbus_connection_flush(conn);

// free the message
dbus_message_unref(msg);
  1. Receiving a signal

These operation requires reading message from the bus. To receive a signal you have to tell the bus what signals you are interested in so they are sent to your application, then you read messages off the bus and can check what type they are and what interfaces and signal names each signal represents.

// add a rule for which messages we want to see
dbus_bus_add_match(conn,
"type='signal',interface='test.signal.Type'",
&err); // see signals from the given interface
dbus_connection_flush(conn);
if (dbus_error_is_set(&err)) {
fprintf(stderr, "Match Error (%s)\n", err.message);
exit(1);
}
// loop listening for signals being emmitted
while (true) {
// non blocking read of the next available message
dbus_connection_read_write(conn, 0);
msg = dbus_connection_pop_message(conn);

// loop again if we haven't read a message
if (NULL == msg) {
sleep(1);
continue;
}

// check if the message is a signal from the correct interface and with the correct name
if (dbus_message_is_signal(msg, "test.signal.Type", "Test")) {
// read the parameters
if (!dbus_message_iter_init(msg, &args))
fprintf(stderr, "Message has no arguments!\n");
else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args))
fprintf(stderr, "Argument is not string!\n");
else {
dbus_message_iter_get_basic(&args, &sigvalue);
printf("Got Signal with value %s\n", sigvalue);
}
}

// free the message
dbus_message_unref(msg);
 }

I hope that will be a good light introduction to the Dbus system.