Introduction
I always wondered how applications send resources or information from one application to another and how the request is processed and sent right back to me, have you?
Let me use a scenario suppose you are using a mobile app to book a flight ticket. The mobile app needs to communicate with the airline’s reservation system to check for available flights and book a ticket. The mobile app you are using would send a request to the airline’s reservation system through an API endpoint. The reservation system would process the request, perform the necessary operations, and send back the response to the mobile app. The mobile app would then display the relevant information to you. All this is performed using an API.
SO WHAT IS AN API?
I have been studying about APIs lately and I have learned something that I would like to teach you. Let’s jump right into it.
According to my understanding APIs (Application Program Interfaces) are powerful tools that allow different software applications to communicate with each other. In simple terms, an API acts as a messenger that takes requests from one application and delivers them to another application to execute the requested action. In simple terms, an API is like a link between the client(the website) you are on and resources to be located on that website or another website. Like when you go to a restaurant to get a good meal, you are the client, the waiter who serves you is the API, and the food or drink you order is the resource you would like to access.
How do APIs work?
APIs work by establishing a connection between two software applications and defining a set of rules that govern how they can communicate with each other. This connection can be established using various communication protocols.
Types of APIs
There are several types of APIs, each with its specific use cases. Such as;
REST APIs (Representational State Transfer) APIs are the most common type of API used today. They use the HTTP protocol to establish a connection between the client and the server and use standard HTTP methods such as GET, POST, PUT, and DELETE to perform operations.
SOAP APIs (Simple Object Access Protocol) APIs are a type of API that uses XML(extensible markup language) to communicate between the client and the server. These are more complex than REST APIs and require more bandwidth to transmit data.
GraphQL APIs. These types of APIs are a new type of API that is gaining popularity. They use a query language to retrieve data, making it more efficient than REST APIs. GraphQL APIs are flexible, provide fine-grained control over data retrieval, and can be used to build efficient and scalable systems.
My main focus will be on REST APIs
So How does REST API work?
REST APIs work by defining resources, which are objects or data that can be accessed and manipulated by the client. Each resource is identified by a unique URI (Uniform Resource Identifier). For example, a resource could be a user profile, and its URI could be https://example.com/api/user/123.
When you want to access a resource on a website, it sends an HTTP request to the server with the resource’s URI and the desired HTTP method. For example, a GET request to https://example.com/api/user/123 would retrieve the user profile with the ID of 123.
The server processes the request and returns a response with the requested resource in a standardized format, such as JSON(Javascript Object Notation) or XML. You can then use the returned data to display or manipulate the resource.
HTTP Methods
As I had mentioned earlier REST APIs use HTTP methods to manipulate resources. The most common HTTP methods used in RESTful APIs are:
GET: retrieves a resource
POST: creates a new resource
PUT: updates an existing resource
DELETE: deletes a resource
HTTP Response Codes
REST APIs use HTTP response codes to indicate the status of a request. The most common HTTP response codes used in RESTful APIs are:
200 OK: the request was successful
201 Created: the resource was created successfully
400 Bad Request: the request was malformed or invalid
401 Unauthorized: the client is not authorized to access the resource
404 Not Found: the requested resource could not be found
500 Internal Server Error: an error occurred on the server
So let’s see some of the advantages of REST APIs
Advantages of REST API
Lightweight. REST APIs use a standardized format such as JSON or XML, which is easy to understand and manipulate.
Scalable. REST APIs are designed to be scalable, meaning that they can handle a large number of requests without affecting performance.
Flexibility. REST APIs are flexible and can be used with a variety of programming languages and platforms.
Caching: REST APIs can be cached, which improves performance and reduces server load
I will go ahead and see the use of REST APIs in Python scripts to show you how to implement HTTP Methods, using the Flask web framework. If you have no idea about how the Flask framework works you can refer to my article here what-is-a-web-framework where I talk about it in order to get a better understanding of how it works.
I will continue using the example where I mentioned earlier where I am using a mobile app to book a flight ticket from Nairobi to Kampala.
GET requests can be implemented using the code below;
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/api/book-flight', methods=['GET'])
def book_flight():
# Get the query parameters from the request
origin = request.args.get('origin')
destination = request.args.get('destination')
departure_date = request.args.get('departure_date')
return_date = request.args.get('return_date')
passenger_count = request.args.get('passenger_count')
# Call a hypothetical function to book the flight ticket
ticket_id = book_flight_ticket(origin, destination, departure_date, return_date, passenger_count)
# Return a JSON response with the ID of the booked ticket
response = {
'status': 'success',
'message': 'Flight ticket booked successfully,
'ticket_id': ticket_id
}
return jsonify(response), 200
if __name__ == '__main__':
app.run(debug=True)
Let me explain how this code works we first define a route /api/book-flight
that handles GET requests. My mobile app sends a GET request to this route with the necessary query parameters, the book_flight
function is called. Inside the book_flight
function, we retrieve the query parameters from the request using request.args.get()
. The get
method returns the value of the specified query parameter from the URL.
We then call a hypothetical function book_flight_ticket
to book the flight ticket with the given details. The function returns the ID of the booked ticket, which we include in the response.Finally, we return a JSON response with a status message and the ID of the booked ticket using the jsonify
method. We also set the HTTP status code to 200 OK
using the second parameter of jsonify
.
To test this code, you can use a tool like Postman to send a GET request to http://localhost:5000/api/book-flight?origin=Nairobi&destination=Kampala&departure_date=2023-06-01&return_date=2023-06-08&passenger_count=2
with the necessary query parameters. The server should book the flight ticket with the given details and return a JSON response with the ID of the booked ticket. This is what you see on your screen.
POST requests can be implemented using the code below;
#!/usr/bin/python3
from flask import Flask, request, jsonify
app = Flask(__name__)
# Mock data for available flights in an array in JSON format
available_flights = [
{
'id': 1,
'flight_number': 'ABC123',
'origin': 'Nairobi',
'destination': 'Kampala',
'departure_time': '2023–06–01 08:00:00',
'arrival_time': '2023–06–01 10:00:00',
'price': 500.00
},
{
'id': 2,
'flight_number': 'XYZ456',
'origin': 'Los Angeles',
'destination': 'New York',
'departure_time': '2023–06–01 12:00:00',
'arrival_time': '2023–06–01 14:00:00',
'price': 450.00
}
]
@app.route('/api/book_flight', methods=['POST'])
def book_flight():
data = request.get_json() # Get the JSON data from the request
flight_id = data['flight_id'] # Get the ID of the selected flight
passenger_name = data['passenger_name'] # Get the name of the passenger
# Find the selected flight by ID
selected_flight = next((flight for flight in available_flights if flight['id'] == flight_id), None)
if selected_flight:
# Book the flight by adding the passenger's name to the flight data
selected_flight['passenger_name'] = passenger_name
# Return a response with the details of the booked flight
response = {
'status': 'success',
'message': 'Flight booked successfully',
'flight_details': selected_flight
}
return jsonify(response), 201
else:
# If the selected flight is not found, return an error response
response = {
'status': 'error',
'message': 'Selected flight not found'
}
return jsonify(response), 404
if __name__ == '__main__':
app.run(debug=True)
Let me explain what is happening here, first, we define a route /api/book_flight
that handles POST requests. When my app sends a POST request to this route, the book_flight
function is called.
Inside the book_flight
function, we first retrieve the JSON data from the request using request.get_json()
. The get_json
method returns a Python dictionary containing the data sent by the client, including the ID of the selected flight and the name of the passenger.
We then find the selected flight from the available_flights
list by its ID using a list comprehension. If the flight is found, we add the passenger's name to the flight data to book the flight.
Finally, we return a JSON response with the details of the booked flight using the jsonify
method. We also set the HTTP status code to 201 Created
using the second parameter of jsonify
. If the selected flight is not found, we return an error response with a 404 Not Found
status code.
NB. Note that this example uses mock data for available flights in an array. In a real-world scenario, you would need to retrieve the available flights from a database or an external API.
To test this code, you can use a tool like Postman to send a POST request to http://localhost:5000/api/book_flight
with a JSON payload containing the ID of the selected flight and the name of the passenger. The server should book the flight and return a JSON response with the details of the booked flight. If the selected flight is not found, the server should return an error response.
PUT requests can be implemented using the code below;
#!/usr/bin/python3
from flask import Flask, request, jsonify
app = Flask(__name__)
# A dictionary to store flight details in memory
flights = {}
@app.route('/api/bookings/<int:booking_id>', methods=['PUT'])
def book_flight(booking_id):
data = request.get_json() # Get the JSON data from the request
flight_id = data['flight_id']
seat_class = data['seat_class']
num_passengers = data['num_passengers']
if flight_id not in flights:
# If the flight is not found, return an error response
response = {
'status': 'error',
'message': 'Flight not found'
}
return jsonify(response), 404
# Check if there are enough seats in the requested class
available_seats = flights[flight_id][seat_class]
if available_seats < num_passengers:
# If there are not enough seats, return an error response
response = {
'status': 'error',
'message': 'Not enough seats'
}
return jsonify(response), 400
# Book the flight by reducing the number of available seats
flights[flight_id][seat_class] -= num_passengers
# Return a successful response with the booking details
response = {
'status': 'successful',
'message': 'Flight booked successfully',
'booking_id': booking_id,
'flight_id': flight_id,
'seat_class': seat_class,
'num_passengers': num_passengers
}
return jsonify(response), 200
if __name__ == '__main__':
# Initialize the flight's dictionary with sample data
flights = {
'AB123': {
'Economy': 100,
'Business': 20,
'First Class': 5
},
'CD456': {
'Economy': 50,
'Business': 10,
'First Class': 2
}
}
app.run(debug=True)
Let me explain what is happening above, we first define a route /api/bookings/<int:booking_id>
that handles PUT requests. The booking_id
parameter in the route is a variable that holds the ID of the booking.
When my app sends a PUT request to this route, the book_flight
function is called. Inside the book_flight
function, we first retrieve the JSON data from the request using request.get_json()
. The get_json
method returns a Python dictionary containing the data sent by the app, including the flight_id
, seat_class
, and num_passengers
details.
We then check if the requested flight exists in the flights
dictionary. If not, we return an error response with a 404 status code.
Next, we check if there are enough seats in the requested class for the given number of passengers. If not, we return an error response with a 400 status code.
If there are enough seats, we book the flight by reducing the number of available seats in the flights
dictionary.
Finally, we return a JSON response with a success message and the booking details, including the booking_id
, flight_id
, seat_class
, and num_passengers
.
To test this code, you can use a tool like Postman to send a PUT request to http://localhost:5000/api/bookings/123 (where 123 is the booking ID)
DELETE requests can be implemented using an API only to cancel flights booked earlier let's see how we can implement it using Python.
#!/usr/bin/python3
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/api/bookings/<int:booking_id>', methods=['DELETE'])
def cancel_booking(booking_id):
# Delete the booking from the database
delete_booking_from_database(booking_id)
# Return a response with a success message
response = {
'status': 'success',
'message': 'Booking cancelled successfully'
}
return jsonify(response), 200
if __name__ == '__main__':
app.run(debug=True)
Here we are defining a route /api/bookings/<int:booking_id>
that handles DELETE requests. The booking_id
parameter in the route is a variable that holds the ID of the booking to be cancelled.
When my app sends a DELETE request to this route, the cancel_booking
function is called.
Inside the cancel_booking
function, we delete the booking from the database using a hypothetical function delete_booking_from_database
.
Finally, we return a JSON response with a success message using the jsonify
method. We also set the HTTP status code to 200 OK
using the second parameter of jsonify
.
To test this code, you can use a tool like Postman to send a DELETE request to http://localhost:5000/api/bookings/123
(where 123
is the ID of the booking to be cancelled). The server should delete the booking from the database and return a JSON response with a success message. Have you noticed something? Python is easy to understand just like speaking English.
NB: Note that we are using the debug=True
parameter in the app.run
()
method. This enables debugging mode in Flask, which helps us to identify and fix errors quickly during development.
In conclusion
APIs are widely used to develop web applications, web services, and mobile applications. They are lightweight, scalable, and easy to understand, making them an ideal choice for developing modern web-based software systems, so the next time you choose an API to implement in your project use REST API. I will be giving references to resources that I found useful while reading and understanding REST APIs, hope they will help you too get a clear picture of what I am talking about. If you would like to connect with me you can do so on Twitter @myrajarenga and on LinkedIn at https://www.linkedin.com/in/myra-jarenga/. I will be happy to know if you enjoyed reading it as much as I enjoyed writing it. You can support me by following me on this blog. Thank you.
References
Designing a RESTful API with Python and Flask
*In recent years REST (REpresentational State Transfer) has emerged as the standard architectural design for web…*blog.miguelgrinberg.com
REST API Tutorial
*Building RESTful web services, like other programming skills is part art, part science. As the Internet industry…*restapitutorial.com