Build a REST API with Bottle Python Web Framework - Part 1
Welcome to the course!
Let's be masters of RESTful API architectures and implement one using Python and Bottle Web Framework
As always in software we have to go through this boring part of setting up our system. The principle is the same: Every time you start something new it is more difficult than continuing something that we are already familiar with. This applies to both to humans and computers. Humans have more difficulty to learn something new rather than learn something in comparison to what they already know and computers can have higher performance when running the same program in comparison to when switching context between hundreds of programs that run in the background. This tip will come in handy when you become senior later on and you will need to do proper project management.
First install the latest version of bottle web framework using this command: pip install bottle
Keep open the reference to the full documentation of Bottle Web Framework: https://bottlepy.org/docs/dev/ as we go through this course
Feel free to choose any Python Editor (IDE) you prefer but my suggestion is that you use PyCharm (Community version) for all your Python development: https://www.jetbrains.com/pycharm/download/
Requests and responses is the way a client-server system works. The client sends a request and the server responds. You might not know it yet but every time you hit http://www.somewebpage.com you are actually sending a request to some server and you get back the response which is the content of the webpage. This is called a GET request. GET is one of the verbs used in REST architecture. However there are more things you can do with the rest of the verbs (POST, PUT, etc.) and your web browser is not capable to send these requests by default. In order to try and test REST APIs we need to install a Google Chrome app called Postman. Install Postman chrome app following this link: https://chrome.google.com/webstore/detail/postman/...
This completes the configuration but in order to make things easier and more concrete we are not going to start from scratch, rather we will use some boilerplate code, a skeleton and build on that.
Execute git clone https://github.com/pligor/vu_webtech_example_code
to clone the repository
Open the cloned directory with Pycharm to open the skeleton of the project.
The file that we are going to be working with is server.py.
Also keep open a command-line window at this directory in order to be able and execute the server with this command: python server.py
Go ahead and execute it, and you will see that a server has started at http://localhost:8080.
localhost is your own machine and port 8080 is the corresponding port that the server listens to. If you neglect the port, as you normally do when requesting a website then the implied port is 80. In other words http://www.google.com is equivalent to http://www.google.com:80.
Go to your browser and try: http://localhost:8080/hello and you should see a hello message. Congrats you just made a GET request!
After executing server.py for the first time you will see a new file called phones.db that has been created. This is a small database, an sqlite database which is not covered in this course. If you are familiar with any kind of database then we are still going to use basic SQL here which is common among all database systems.
Why? Well because we want to write, read and change data and we do not want to do it in a file but rather use a database as you have in real-life systems.
So far we know that we want to deal with phones and our API in this course is how to retrieve multiple or one phone, manipulate the data of a phone, delete a phone or simply create a new phone.
To start designing our API we need to think what the routes will be. From http://localhost:8080/hello the route is the /hello part.
What if someone would tell you that he or she wants to retrieve all the phones. This sounds like a GET request or in other words the phrase can be summarized as "GET phones" which can be immediately translated to our RESTful API design as:
GET http://localhost:8080/phones
One would argue, why not design my api to be:
GET http://localhost:8080/allphones [NOT!]
or GET http://localhost:8080/phones_all [please NOT!] etc.
The best practice as always is to keep things simple so we are using a GET request with a /phones route.
Now that we have mastered what the verb GET for RESTful APIs is we should learn the basics about the rest of verbs, the most commonly used ones, that we are going to build in this lesson:
- POST: use it to create something, pass all the information that are necessary to create a new instance in your database.
- GET: Retrieving from the database. The GET should be safe. A safe GET request means that if you call multiple times and no other requests have been done in the system then nothing should have changed in the data. A safe GET request returns always the same results if this is the only request that is being called.
- PUT: Completely replace the contents of an entry. You use PUT to pass an object and replace the values of the old object. The only thing that does not change is the unique identification (id) of the object. You need to provide all the values.
- PATCH: Modify partially an instance in the database. In this case you simply provide one or a few values that you want to update. It is a more light-weight procedure than PUT. As you can imagine if you provide all the values then PATCH becomes equivalent to PUT.
- DELETE: Deletes an entry from the system using its id. Usually it returns a copy of this entry to the client in cases the client wants to do something with the recently deleted entry.
Note that we are referring to databases here but it can be anything behind the API. The API is the only thing that the client sees. The client does not and should not know what kind of storage system you have in your servers (MySQL, Sqlite, Hadoop, files, etc.). The client should not know not for security reasons but for not caring. The client should not care and should not adapt his or her code if you change something in your servers.
So far we have described how to GET all the phones but how are we going to GET only one phone using a RESTful API? If you check at the sqlite database the first column is called "id" and this column has a unique constraint, the number must be unique across all entries in the phones table. In other words we can use this id to fetch/get the phone that we want.
The API design for a GET request of a single phone is quite intuitive:
GET http://localhost:8080/phone/2
Note that now we are not using plurar but to make it more intuitive that the operation is on one phone we are using /phone, we are avoiding the /phones route.
Play with the quiz in this page if you are not 100% sure what the above request will do exactly.
Next we want to design our API to create a new phone. You currently only have two phones in the database and I guess if you own an online e-shop you would need to insert many more entries. In a RESTful way we use POST to create a new phone entry:
POST http://localhost:8080/phone
Note that you are not enforced to use POST for create, this is why you should know what the best practices are. Also note that to test POST requests later you can only do it via Postman Chrome App and we have not implemented any POST requests yet.
But you can also use Postman for GET requests and you can already test one by executing the GET http://localhost:8080/hello, as you did in the web browser.
For POST request of course we need to provide all the information that comes with a new phone. This means that the body of request will be JSON. (Try to find in Postman the request section and the body of the request)
We are not covering JSON in this course but get familiar with it as you will encounter it with any kind of data or software related career.
The Json for a new small iPhone could have been:
{
"brand": "Apple",
"model: "iPhone New",
"os": "iOS",
"image": "http://link.of.image",
"screensize": 4
}
Always include example when specifying your API, it will be much easier of whoever is going to consume your api rather than explaining with a long text.
The id is not included in the json above because it is automatically generated from the sqlite database. The id column has the auto-increment attribute which means that it assigns the next value to a new entry. In our case the latest entry has the value 2, therefore in the next insertion the new entry will be assigned with id number 3. In other words it does not make sense to include it with POST because it is something on the server side to keep track each phone by its unique identification.
This completes the first part of this course.
Enjoying it is not optional therefore you should play with the skills you acquired so far. For example you could use Postman to execute GET requests to your favorite websites to see what other information come along when a website arrives in your web browser apart from its content.
By continuing the course you are becoming a REST API master in less than 2 hours and you will leave with both knowledge and hands-on practical skills.
0 comments