Flask RESTful: Implementing CRUD Methods

Flask RESTful: Implementing CRUD Methods


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.