A web service is a set of web-based components that helps in the exchange of data between the application or systems which also includes open protocols and standards. It can be published, used and found on the web.
Web services are of various types like RWS (RESTfUL Web Service), WSDL, SOAP and many more.
A type of remote access protocol, which, transfers state from client to server which can be used to manipulate state instead of calling remote procedures.
Does not define any specific encoding or structure and ways of returning useful error messages.
Uses HTTP "verbs" to perform state transfer operations.
The resources are uniquely identified using URL.
It is not an API but instead an API transport layer.
REST maintains the nomenclature of resources on a network and provides unified mechanism to perform operations on these resources. Each resource is identified by at least one identifier. If the REST infrastructure is implemented with the base of HTTP, then these identifiers are termed as Uniform Resource Identifiers (URIs).
The following are the two common subsets of the URI set −
Subset | Full form | Example |
---|---|---|
URL | Uniform Resource Locator | http://www.gmail.com/ |
URN | Uniform Resource Name | urn:isbn:0-201-71088-9 urn:uuid:13e8cf26-2a25-11db-8693-000ae4ea7d46 |
Before understanding the implementation of CherryPy architecture, let’s focus on the architecture of CherryPy.
CherryPy includes the following three components −
cherrypy.engine − It controls process startup/teardown and event handling.
cherrypy.server − It configures and controls the WSGI or HTTP server.
cherrypy.tools − A toolbox of utilities that are orthogonal to processing an HTTP request.
RESTful web service implements each section of CherryPy architecture with the help of the following −
Authentication helps in validating the users with whom we are interacting. CherryPy includes tools to handle each authentication method.
def authenticate(): if not hasattr(cherrypy.request, 'user') or cherrypy.request.user is None: # < Do stuff to look up your users > cherrypy.request.authorized = False # This only authenticates. Authz must be handled separately. cherrypy.request.unauthorized_reasons = [] cherrypy.request.authorization_queries = [] cherrypy.tools.authenticate = \ cherrypy.Tool('before_handler', authenticate, priority=10)
The above function authenticate() will help to validate the existence of the clients or users. The built-in tools help to complete the process in a systematic way.
Authorization helps in maintaining the sanity of the process via URI. The process also helps in morphing objects by user token leads.
def authorize_all(): cherrypy.request.authorized = 'authorize_all' cherrypy.tools.authorize_all = cherrypy.Tool('before_handler', authorize_all, priority=11) def is_authorized(): if not cherrypy.request.authorized: raise cherrypy.HTTPError("403 Forbidden", ','.join(cherrypy.request.unauthorized_reasons)) cherrypy.tools.is_authorized = cherrypy.Tool('before_handler', is_authorized, priority = 49) cherrypy.config.update({ 'tools.is_authorized.on': True, 'tools.authorize_all.on': True })
The built-in tools of authorization help in handling the routines in a systematic way, as mentioned in the previous example.
Maintaining a structure of API helps in reducing the work load of mapping the URI of application. It is always necessary to keep API discoverable and clean. The basic structure of API for CherryPy framework should have the following −
Encapsulation helps in creating API which is lightweight, human readable and accessible to various clients. The list of items along with Creation, Retrieval, Update and Deletion requires encapsulation of API.
This process manages errors, if any, if API fails to execute at the particular instinct. For example, 400 is for Bad Request and 403 is for unauthorized request.
Consider the following as an example for database, validation, or application errors.
import cherrypy import json def error_page_default(status, message, traceback, version): ret = { 'status': status, 'version': version, 'message': [message], 'traceback': traceback } return json.dumps(ret) class Root: _cp_config = {'error_page.default': error_page_default} @cherrypy.expose def index(self): raise cherrypy.HTTPError(500, "Internal Sever Error") cherrypy.quickstart(Root())
The above code will produce the following output −
Management of API (Application Programming Interface) is easy through CherryPy because of the built-in access tools.
The list of HTTP methods which operate on the resources are as follows −
S.No | HTTP Method & Operation |
---|---|
1. | HEAD Retrieves the resource metadata. |
2. | GET Retrieves the resource metadata and content. |
3. | POST Requests the server to create a new resource using the data enclosed in the request body. |
4. | PUT Requests the server to replace an existing resource with the one enclosed in the request body. |
5. | DELETE Requests the server to remove the resource identified by that URI. |
6. | OPTIONS Requests the server to return details about capabilities either globally or specifically towards a resource. |
APP has arisen from the Atom community as an application-level protocol on top of HTTP to allow the publishing and editing of web resources. The unit of messages between an APP server and a client is based on the Atom XML-document format.
The Atom Publishing Protocol defines a set of operations between an APP service and a user-agent using HTTP and its mechanisms and the Atom XML-document format as the unit of messages.
APP first defines a service document, which provides the user agent with the URI of the different collections served by the APP service.
Let us take an example to demonstrate how APP works −
<?xml version = "1.0" encoding = "UTF-8"?> <service xmlns = "http://purl.org/atom/app#" xmlns:atom = "http://www.w3.org/2005/Atom"> <workspace> <collection href = "http://host/service/atompub/album/"> <atom:title> Albums</atom:title> <categories fixed = "yes"> <atom:category term = "friends" /> </categories> </collection> <collection href = "http://host/service/atompub/film/"> <atom:title>Films</atom:title> <accept>image/png,image/jpeg</accept> </collection> </workspace> </service>
APP specifies how to perform the basic CRUD operations against a member of a collection or the collection itself by using HTTP methods as described in the following table −
Operation | HTTP Method | Status Code | Content |
---|---|---|---|
Retrieve | GET | 200 | An Atom entry representing the resource |
Create | POST | 201 | The URI of the newly created resource via the Location and Content-Location headers |
Update | PUT | 200 | An Atom entry representing the resource |
Delete | DELETE | 200 | None |