REST, or REpresentational State Transfer, is an architectural style for providing standards between computer systems on the web, making it easier for systems to communicate with each other. Web services that conform to the REST architectural style, called RESTful Web services, are characterized by how they are stateless and separate the concerns of client and server.
In the REST architecture, clients send requests to retrieve or modify resources, and servers send responses to these requests. There are four basic types of requests a client can make to a server:
GET
POST
PUT
DELETE
We will write a simple REST application which can perform all the above four requests for calculating the square of a number.
Save the below code in a file named 'rest_app.py'.
import cherrypy
class application:
def GET(self):
return cherrypy.session['ans']
def POST(self, number=2):
answer = str(int(number)**2)
cherrypy.session['ans'] = answer
return cherrypy.session['ans']
def PUT(self, number):
cherrypy.session['ans'] = number
def DELETE(self):
cherrypy.session.pop('ans', None)
if __name__ == '__main__':
conf = {
'/': {
'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
'tools.sessions.on': True,
'tools.response_headers.on': True,
'tools.response_headers.headers': [('Content-Type', 'text/plain')],
}
}
cherrypy.quickstart(application(), '/', conf)
Here we can see the methods describing the four HTTP requests.
Before we see it in action, let's explain a few things. Until now, CherryPy was creating a tree of exposed methods that were used to match URLs. In the case of our REST application, we want to stress the role played by the actual requests' HTTP methods.
However, we must then switch from the default mechanism of matching URLs to method for one that is aware of the REST architecture. This is why we create a MethodDispatcher instance by setting the 'request.dispatch' attribute of our configurations to 'cherrypy.dispatch.MethodDispatcher()'.
Then we force the responses content-type to be text/plain and we finally ensure that GET requests will only be responded to the clients that accept that content-type by having a Accept: text/plain header set in their request.
Run the code through the Terminal/Command Line as follows:
python3 rest_app.py
For testing this we would need Python's request module. Install it by writing the following command on a Terminal/Command Line.
pip3 install requests
Then open the Python interpreter on a Terminal window by typing 'python3' and try the following commands.
import requests
s = requests.Session()
url = 'http://127.0.0.1:8080/'
r = s.get(url)
r.status_code
500
r = s.post(url)
r.status_code, r.text
(200, '4')
r = s.get(url)
r.status_code, r.text
(200, '4')
r = s.get(url, headers={'Accept': 'application/json'})
r.status_code
406
r = s.post(url, params={'number': '5'})
r.status_code, r.text
(200, '25')
r = s.put(url, params={'number': '100'})
r = s.get(url)
r.status_code, r.text
(200, '100')
r = s.delete(url)
r = s.get(url)
r.status_code
500
The first and last 500 responses stem from the fact that, in the first case, we haven't yet generated a string through POST yet and, in the latter case, that it doesn't exist after we've deleted it.
Lines 13-15 show how the application reacted when our client requested the generated string as a JSON format. Since we configured the app to only support plain text, it returns the appropriate HTTP error code.
Comments