Hi Readers
In this blog, we'll examine how to use CRUD methods with a Restful API.
What is a Rest?
Rest is an architectural design pattern/style used for composing a web framework. By using the principles of Rest, we can build clean and readable code for naming routes and methods.
Key Details
from flask import Flask
from flask_restful import Api, Resource
app = Flask(__name__)
api = Api(app)
class Cars(Resource):
def get(self):
return {"car": "VROOM VROOM!"}
api.add_resource(Cars, '/cars')
if __name__ == '__main__':
app.run(port=5555)
Before covering the syntax of the Car class, get function, and '/cars' route, we must first understand what is happening above it. We are importing two classes (Api, Resource) from flask_restful to "calibrate" our restful style of code. The Api class is the "handler" for the whole Restful API.
app = Flask(__name__)
api = Api(app)
Our Car class is defined and takes in Resource as a parameter which is added to the API with add_resource(). Using the parameters (Cars, '/cars'), it's then able to distinguish which method to use and at what destination.
api.add_resource(Car, '/cars')
Example Model:
#models.py
class Car(db.Model, SerializerMixin):
__tablename__ = 'cars'
id = db.Column(db.Integer, primary_key=True)
make = db.Column(db.String)
model = db.Column(db.String)
year = db.Column(db.Integer)
color = db.Column(db.String)
Above is the example table for a list of cars and their data.
Below, I will demonstrate the syntax to apply CRUD methods to this data using Flask RESTful.
Get,Post '/cars':
#app.py
from flask import Flask, request
from flask_restful import Api, Resource
from models import Car
app = Flask(__name__)
api = Api(app)
class Cars(Resource):
def get(self):
cars = [car.to_dict() for car in Car.query.all()]
return cars, 200
def post(self):
data = request.get_json()
new_car = Car(
make = data.get('make'),
model = data.get('model'),
year = data.get('year'),
color = data.get('color')
)
db.session.add(new_car)
db.session.commit()
return new_car.to_dict(), 201
api.add_resource(Cars, '/cars')
if __name__ == '__main__':
app.run(port=5555)
As you can see, my '/cars' route which will interact with the entire table of cars only uses the get and post methods. In this case, I am "getting" the entire database of cars or I am "posting" a new car to my database. The crud methods I use in this class will be "linked" to the destination '/cars'. This is because I am passing in the "Cars" class as the first parameter in add_resource.
Get, Patch, Delete '/cars/<int:id>':
from flask_restful import Api, Resource
from models import Car
app = Flask(__name__)
api = Api(app)
# code for Cars here
class CarsById(Resource):
def get(self, id):
car = Car.query.filter(Car.id == id).first()
return car, 200
def patch(self, id):
data = request.get_json()
car = Car.query.filter(Car.id == id).first()
for attr in data:
setattr(car, attr, data.get(attr))
db.session.add(car)
db.session.commit()
return car.to_dict(), 202
def delete(self, id):
car = Car.query.filter(Car.id == id).first()
db.session.delete(car)
db.session.commit()
return {}. 204
api.add_resource(CarsById, '/cars/<int:id>')
if __name__ == '__main__':
app.run(port=5555)
Above, CarsById uses the route '/cars/<int:id>' to interact with an individual car from the database specified by an id passed in as an argument. The "get" will retrieve an individual car from the database and its information. The "patch" will retrieve an individual car and its information, then apply the changes brought in by requesting the json from where the "user" submitted the information. The "delete" will retrieve an individual car and delete it from the database. The get, patch, and delete in this class will be "linked" to the destination '/cars/<int:id>'
. This is because I am passing in the "CarsById" class as the first parameter in add_resource.
Wrapping up
As you can see, the "meat" of the CRUD is the same regardless of the style we use to organize our routes. Flask RESTful is simply a very efficient and clean readable way to structure our CRUD methods.