Difficulty: Advanced
Flask-RESTful is an extension that adds support for building REST APIs with class-based resources. While you can build APIs with plain Flask routes, Flask-RESTful provides a structured approach with automatic request parsing, response marshalling, and error handling.
The core concept in Flask-RESTful is the Resource class. Each Resource represents a REST endpoint and defines methods for HTTP verbs: get(), post(), put(), patch(), and delete(). The Api object registers Resources with URL rules, similar to how Flask registers view functions.
Request parsing with reqparse replaces manual request.get_json() and validation. You define a RequestParser with expected arguments, their types, locations (json, args, form, headers), and whether they are required. The parser validates the request and returns parsed arguments as a namespace object.
Response marshalling with marshal_with defines the output format. You create a dictionary of field definitions that maps model attributes to JSON fields. marshal_with acts as a decorator that filters and formats the response, ensuring only specified fields are included and types are correct.
Flask-RESTful provides automatic error handling. If a request fails parsing, it returns a 400 error with details about which field failed and why. You can customize error messages and add custom error handlers.
The Api object manages resources and handles content negotiation, error formatting, and URL routing. You can prefix all resources with a URL prefix, and resources can have multiple URL rules.
Note: Flask-RESTful is in maintenance mode. For new projects, consider Flask-RESTX (actively maintained fork with Swagger documentation), Flask-Smorest (built on marshmallow with OpenAPI support), or just plain Flask with marshmallow for serialization.
from flask import Flask
from flask_restful import Api, Resource, reqparse
app = Flask(__name__)
api = Api(app)
tasks = [
{'id': 1, 'title': 'Buy groceries', 'done': False},
{'id': 2, 'title': 'Read a book', 'done': True},
]
class TaskList(Resource):
def get(self):
return tasks
def post(self):
parser = reqparse.RequestParser()
parser.add_argument('title', type=str, required=True, help='Title is required')
args = parser.parse_args()
task = {'id': len(tasks) + 1, 'title': args['title'], 'done': False}
tasks.append(task)
return task, 201
class Task(Resource):
def get(self, task_id):
task = next((t for t in tasks if t['id'] == task_id), None)
if not task:
return {'error': 'Not found'}, 404
return task
def delete(self, task_id):
global tasks
tasks = [t for t in tasks if t['id'] != task_id]
return '', 204
api.add_resource(TaskList, '/api/tasks')
api.add_resource(Task, '/api/tasks/<int:task_id>')
Resource classes define HTTP methods. TaskList handles the collection (GET all, POST new). Task handles individual items (GET one, DELETE). api.add_resource binds URLs to resources.
from flask_restful import reqparse
# Define reusable parser
user_parser = reqparse.RequestParser()
user_parser.add_argument('name', type=str, required=True,
help='Name is required', location='json')
user_parser.add_argument('email', type=str, required=True,
help='Valid email required', location='json')
user_parser.add_argument('age', type=int, required=False,
default=0, location='json')
user_parser.add_argument('role', type=str, choices=('admin', 'user'),
default='user', location='json')
class UserList(Resource):
def post(self):
args = user_parser.parse_args(strict=True) # Reject unknown fields
user = {
'name': args['name'],
'email': args['email'],
'age': args['age'],
'role': args['role']
}
return user, 201
# If validation fails, auto returns:
# {"message": {"name": "Name is required"}} with 400 status
reqparse validates and parses request data. Each argument has a type, required flag, default, and allowed choices. strict=True rejects unexpected fields. Validation errors return 400 automatically.
from flask_restful import Resource, fields, marshal_with, marshal
# Define output format
user_fields = {
'id': fields.Integer,
'name': fields.String,
'email': fields.String,
'created_at': fields.DateTime(dt_format='iso8601'),
'profile_url': fields.Url('user_detail', absolute=True),
}
class UserList(Resource):
@marshal_with(user_fields)
def get(self):
users = User.query.all()
return users # Automatically marshalled
class UserDetail(Resource):
@marshal_with(user_fields)
def get(self, user_id):
user = User.query.get_or_404(user_id)
return user
# Or marshal manually:
def get_users():
users = User.query.all()
return marshal(users, user_fields)
marshal_with controls exactly which fields appear in the response and how they are formatted. It filters out unlisted fields (like password_hash) and formats types like DateTime. fields.Url generates URLs automatically.
from flask import Flask
from flask_restful import Api, Resource, reqparse, marshal_with, fields, abort
app = Flask(__name__)
api = Api(app)
book_fields = {
'id': fields.Integer,
'title': fields.String,
'author': fields.String,
'year': fields.Integer,
}
book_parser = reqparse.RequestParser()
book_parser.add_argument('title', type=str, required=True)
book_parser.add_argument('author', type=str, required=True)
book_parser.add_argument('year', type=int)
books = {}
next_id = 1
class BookList(Resource):
@marshal_with(book_fields)
def get(self):
return list(books.values())
@marshal_with(book_fields)
def post(self):
global next_id
args = book_parser.parse_args()
book = {'id': next_id, args}
books[next_id] = book
next_id += 1
return book, 201
class BookDetail(Resource):
@marshal_with(book_fields)
def get(self, book_id):
if book_id not in books:
abort(404, message=f'Book {book_id} not found')
return books[book_id]
@marshal_with(book_fields)
def put(self, book_id):
args = book_parser.parse_args()
books[book_id] = {'id': book_id, args}
return books[book_id]
def delete(self, book_id):
if book_id in books:
del books[book_id]
return '', 204
api.add_resource(BookList, '/api/books')
api.add_resource(BookDetail, '/api/books/<int:book_id>')
A complete CRUD resource with parsing and marshalling. BookList handles collection operations, BookDetail handles individual resources. marshal_with ensures consistent output. abort returns errors with messages.
Flask-RESTful, Resource, reqparse, marshal_with, Api, Class-Based API