Flask-RESTful
Flask-RESTful is an extension that structures REST APIs around resource classes instead of individual route functions. Each resource class handles all HTTP methods for one endpoint, keeping related code grouped together and reducing boilerplate.
Installing Flask-RESTful
pip install flask-restfulSetting Up Flask-RESTful
from flask import Flask
from flask_restful import Api, Resource
app = Flask(__name__)
api = Api(app)Creating a Resource
Each resource is a class that inherits from Resource. Define methods named get, post, put, patch, and delete — Flask-RESTful routes HTTP methods to the matching class method automatically.
books = [
{'id': 1, 'title': 'Flask Web Development'},
{'id': 2, 'title': 'Python Crash Course'},
]
class BookList(Resource):
def get(self):
return books, 200
def post(self):
from flask import request
data = request.get_json()
new_book = {'id': len(books) + 1, 'title': data['title']}
books.append(new_book)
return new_book, 201
class Book(Resource):
def get(self, book_id):
book = next((b for b in books if b['id'] == book_id), None)
if not book:
return {'error': 'Not found'}, 404
return book, 200
def delete(self, book_id):
global books
books = [b for b in books if b['id'] != book_id]
return {'message': 'Deleted'}, 200
api.add_resource(BookList, '/api/books')
api.add_resource(Book, '/api/books/<int:book_id>')How Flask-RESTful Routes Requests
GET /api/books → BookList.get() POST /api/books → BookList.post() GET /api/books/5 → Book.get(book_id=5) DELETE /api/books/5 → Book.delete(book_id=5)
Request Parsing with reqparse
Flask-RESTful provides its own argument parser called reqparse. It validates incoming request data and returns errors automatically in JSON format:
from flask_restful import reqparse
parser = reqparse.RequestParser()
parser.add_argument('title', type=str, required=True, help='Title is required')
parser.add_argument('author', type=str, required=False, default='Unknown')
parser.add_argument('year', type=int, required=False)
class BookList(Resource):
def post(self):
args = parser.parse_args()
new_book = {
'id': len(books) + 1,
'title': args['title'],
'author': args['author'],
'year': args['year']
}
books.append(new_book)
return new_book, 201If title is missing, Flask-RESTful automatically returns:
{"message": {"title": "Title is required"}} with status 400Output Fields with marshal_with
Flask-RESTful's marshal_with decorator controls which fields appear in the response and their types. It acts as an output filter:
from flask_restful import fields, marshal_with
book_fields = {
'id': fields.Integer,
'title': fields.String,
'author': fields.String,
}
class Book(Resource):
@marshal_with(book_fields)
def get(self, book_id):
book = next((b for b in books if b['id'] == book_id), None)
if not book:
return {'error': 'Not found'}, 404
return bookEven if your data has extra fields (like internal IDs or passwords), only the fields declared in book_fields appear in the JSON response.
Returning Error Responses
from flask_restful import abort
class Book(Resource):
def get(self, book_id):
book = next((b for b in books if b['id'] == book_id), None)
if not book:
abort(404, message=f'Book {book_id} does not exist.')
return bookFlask-RESTful's abort() returns a JSON error response instead of an HTML error page:
{"message": "Book 99 does not exist."} with status 404Flask-RESTful vs Plain Flask Routes
| Feature | Plain Flask | Flask-RESTful |
|---|---|---|
| Method separation | if/elif in one function | Separate methods in one class |
| Input validation | Manual | reqparse |
| Output shaping | Manual to_dict() | marshal_with decorator |
| JSON error format | Custom | Consistent JSON by default |
Summary
Flask-RESTful organizes REST API code into resource classes where each HTTP method becomes a class method. Add resources to the API with api.add_resource(). Use reqparse to validate incoming arguments with automatic JSON error responses. Use marshal_with to define exactly which fields appear in responses. Flask-RESTful reduces boilerplate and enforces consistent API structure as your project grows.
