Skip to content

Create RESTful API Using Flask

Setup

We will start by installing Flask-Restful from Python Package Index (PyPI) using the terminal/command line.

pip install flask_restful
pip install flask_restful

Let’s create a database that will contain three fields: first_name, last_name and email.

python
class User(db.Model):  
    id = db.Column(db.Integer, primary_key=True)  
    first_name = db.Column(db.String())  
    last_name = db.Column(db.String())  
    email = db.Column(db.String())
class User(db.Model):  
    id = db.Column(db.Integer, primary_key=True)  
    first_name = db.Column(db.String())  
    last_name = db.Column(db.String())  
    email = db.Column(db.String())

POST Request

Post request allows a client to send data to the server, which will be processed by the server and saved to the database.

python
from flask_restful import Api, Resource

app = Flask(__name__)
api = Api(app)

class CreateUser(Resource):
    response = {"status": 400, "message": "User not created"}

    def post(self):
        user_data = request.get_json()
        first_name = user_data["first_name"]
        last_name = user_data["last_name"]
        email = user_data["email"]
        user = User(first_name=first_name, last_name=last_name, email=email)
        db.session.add(user)
        db.session.commit()

        self.response["status"] = 201
        self.response["message"] = "User created successfully"

        return self.response, 201

api.add_resource(CreateUser, "/api/create")
from flask_restful import Api, Resource

app = Flask(__name__)
api = Api(app)

class CreateUser(Resource):
    response = {"status": 400, "message": "User not created"}

    def post(self):
        user_data = request.get_json()
        first_name = user_data["first_name"]
        last_name = user_data["last_name"]
        email = user_data["email"]
        user = User(first_name=first_name, last_name=last_name, email=email)
        db.session.add(user)
        db.session.commit()

        self.response["status"] = 201
        self.response["message"] = "User created successfully"

        return self.response, 201

api.add_resource(CreateUser, "/api/create")

The user_data variable stores the request body, which can be accessed by other variables(first_name, last_name and email). The data was added to a Python object, added to a Flask-SQLAlchemy session and we committed the session. The default response was updated before returning it to the user with the 201 HTTP status code.

The request will be received by the URL http://127.0.0.1:5000/api/create we was created using flask restful Resource.

GET Request

GET requests, allows us to retrieve data from the data, the data can contain a single record or multiple records. We will use this method to retrieve the all the users that we have in out database.

python
class Users(Resource):
    response = {"status": 404, "message": "Users not available"}

    def get(self):
        users = User.query.all()
        if users:
            all_users = []
            for user in users:
                user_details = {
                    "id": user.id,
                    "first_name": user.first_name,
                    "last_name": user.last_name,
                    "email": user.email,
                }
                all_users.append(user_details)
            self.response["status"] = 200
            self.response["message"] = all_users
            return self.response, 200
        else:
            return self.response, 404

api.add_resource(Users, "/api/users")
class Users(Resource):
    response = {"status": 404, "message": "Users not available"}

    def get(self):
        users = User.query.all()
        if users:
            all_users = []
            for user in users:
                user_details = {
                    "id": user.id,
                    "first_name": user.first_name,
                    "last_name": user.last_name,
                    "email": user.email,
                }
                all_users.append(user_details)
            self.response["status"] = 200
            self.response["message"] = all_users
            return self.response, 200
        else:
            return self.response, 404

api.add_resource(Users, "/api/users")

The Users class contains a default response which will be returned when no users records are stored in the database and get method. The database was queried to retrieve all the users and stored in the users variable. We looped through both the users variable and each user record in the user_details variable. Each user_details is appended to the all_users variable which we returned to the user in the updated response message.

Let’s send a get request that will retrieve a single user using the user ID.

python
class GetUser(Resource):
    response = {"status": 404, "message": "Users not available"}

    def get(self, user_id):
        user = User.query.filter_by(id=user_id).first()
        if user:
            user_details = {
                "id": user.id,
                "first_name": user.first_name,
                "last_name": user.last_name,
                "email": user.email,
            }
            self.response["status"] = 200
            self.response["message"] = user_details

            return self.response, 200
        else:
            return self.response, 404

api.add_resource(GetUser, "/api/user/<int:user_id>/")
class GetUser(Resource):
    response = {"status": 404, "message": "Users not available"}

    def get(self, user_id):
        user = User.query.filter_by(id=user_id).first()
        if user:
            user_details = {
                "id": user.id,
                "first_name": user.first_name,
                "last_name": user.last_name,
                "email": user.email,
            }
            self.response["status"] = 200
            self.response["message"] = user_details

            return self.response, 200
        else:
            return self.response, 404

api.add_resource(GetUser, "/api/user/<int:user_id>/")

The user_id was passed into the get method, which was used to query the database. If a user with the ID exists, the user details are added to the response and returned but if not the default response is returned.

PUT Request

The PUT request allows us to update or create a record in the database. We will need to retrieve the record from the database before we can update it.

python
class UpdateUser(Resource):
    response = {"status": 404, "message": "Users not available"}

    def put(self, user_id):
        user = User.query.filter_by(id=user_id).first()
        if user:
            user_data = request.get_json()
            first_name = user_data["first_name"]
            last_name = user_data["last_name"]
            email = user_data["email"]
            user.first_name = first_name
            user.last_name = last_name
            user.email = email

            db.session.commit()
            self.response["status"] = 200
            self.response["message"] = "User updated successfully"
            return self.response, 200
        else:
            return self.response, 404

api.add_resource(UpdateUser, "/api/update/<int:user_id>")
class UpdateUser(Resource):
    response = {"status": 404, "message": "Users not available"}

    def put(self, user_id):
        user = User.query.filter_by(id=user_id).first()
        if user:
            user_data = request.get_json()
            first_name = user_data["first_name"]
            last_name = user_data["last_name"]
            email = user_data["email"]
            user.first_name = first_name
            user.last_name = last_name
            user.email = email

            db.session.commit()
            self.response["status"] = 200
            self.response["message"] = "User updated successfully"
            return self.response, 200
        else:
            return self.response, 404

api.add_resource(UpdateUser, "/api/update/<int:user_id>")

The put method accepts the user_id which was used to retrieve the user record. If the user record exists in the database, the new data that was sent by the client will replace the existing record.

DELETE Request

The delete method is used to delete a single or multiple records from the database. It will also delete the changes that were made to the database will be saved. The delete method will send a request to the server so that the record attached to the endpoint will be deleted from the database.

python
class DeleteUser(Resource):
    response = {"status": 404, "message": "User not available"}

    def delete(self, user_id):
        user = User.query.filter_by(id=user_id).first()
        if user:
            db.session.delete(user)
            db.session.commit()
            self.response["status"] = 200
            self.response["message"] = "User deleted successfully"
            return self.response, 200
        else:
            return self.response, 404

api.add_resource(DeleteUser, "/api/delete/<int:user_id>")
class DeleteUser(Resource):
    response = {"status": 404, "message": "User not available"}

    def delete(self, user_id):
        user = User.query.filter_by(id=user_id).first()
        if user:
            db.session.delete(user)
            db.session.commit()
            self.response["status"] = 200
            self.response["message"] = "User deleted successfully"
            return self.response, 200
        else:
            return self.response, 404

api.add_resource(DeleteUser, "/api/delete/<int:user_id>")

Just like the PUT and GET methods, this method also makes use of the user_id to retrieve a user from the database, if the record exists the user will be deleted and the changes will be saved to the database. But if the user does not exit the default response message will be returned to the user and no record will be deleted.

Conclusion

Now you know how to create a RESTful API using Flask. Some of the reasons why REST API is very popular are because it’s lightweight, independent, scalable and flexible. Unlike other APIS such as XML-RPC, JSON-RPC and SOAP impose a strict framework. REST API supports different types of data formats and can be easily developed with almost all programming languages.

Released under the MIT License.