Flask REST API

6 Kernkonzepte
Die wichtigsten Konzepte für REST-APIs mit Flask: JSON-Antworten · HTTP-Methoden · Fehlerbehandlung · JWT-Authentifizierung · Blueprints · Rate Limiting Flask eignet sich hervorragend für die Entwicklung von REST-APIs. Diese Cheatsheet fasst die wichtigsten Techniken zusammen – von JSON-Antworten über Authentifizierung bis zu Rate Limiting.

JSON-Antworten – API mit jsonify

jsonify · make_response · to_dict
from flask import jsonify @app.route('/api/user') def get_user(): return jsonify({'id': 1, 'name': 'Anna'})

jsonify() ist die bevorzugte Methode, um JSON-Antworten in Flask zu senden. Es setzt automatisch den korrekten Content-Type und konvertiert Python-Objekte in JSON.

Beispiele
# Einfache JSON-Antwort
@app.route('/api/status')
def status():
return jsonify({'status': 'OK', 'version': '1.0'})
# JSON mit benutzerdefiniertem Statuscode
@app.route('/api/user/<int:user_id>')
def get_user(user_id):
user = User.query.get(user_id)
if user is None:
return jsonify({'error': 'User not found'}), 404
return jsonify(user.to_dict())
# make_response für mehr Kontrolle
from flask import make_response
@app.route('/api/custom')
def custom_response():
data = {'message': 'Erfolg'}
response = make_response(jsonify(data), 201)
response.headers['X-Custom-Header'] = 'CustomValue'
return response
# JSON mit Listendaten
@app.route('/api/users')
def get_users():
users = [user.to_dict() for user in User.query.all()]
return jsonify(users)
Tipp: Definieren Sie eine to_dict()-Methode in Ihren Modellen, um konsistente JSON-Repräsentationen zu erzeugen – das hält Ihre Codebasis sauber und wartbar.

HTTP-Methoden – GET, POST, PUT, DELETE

methods=['GET', 'POST'] · request.method
@app.route('/api/user', methods=['GET', 'POST']) def user(): if request.method == 'GET': return jsonify({'action': 'GET'}) elif request.method == 'POST': return jsonify({'action': 'POST'}), 201

HTTP-Methoden definieren die Aktion, die eine API ausführen soll. Typische Methoden sind GET (lesen), POST (erstellen), PUT (aktualisieren) und DELETE (löschen).

Beispiele
# REST-API für eine Ressource
@app.route('/api/posts', methods=['GET', 'POST'])
def posts():
if request.method == 'GET':
# Alle Posts abrufen
posts = Post.query.all()
return jsonify([p.to_dict() for p in posts])
elif request.method == 'POST':
data = request.get_json()
# Neuen Post erstellen
post = Post(title=data['title'], content=data['content'])
db.session.add(post)
db.session.commit()
return jsonify(post.to_dict()), 201
# Einzelne Ressource mit ID
@app.route('/api/posts/<int:id>', methods=['GET', 'PUT', 'DELETE'])
def post_detail(id):
post = Post.query.get_or_404(id)
if request.method == 'GET':
return jsonify(post.to_dict())
elif request.method == 'PUT':
data = request.get_json()
post.title = data.get('title', post.title)
post.content = data.get('content', post.content)
db.session.commit()
return jsonify(post.to_dict())
elif request.method == 'DELETE':
db.session.delete(post)
db.session.commit()
return jsonify({'message': 'Post gelöscht'}), 204
Tipp: Verwenden Sie get_or_404() für elegante Fehlerbehandlung – es wirft automatisch einen 404-Fehler, wenn die Ressource nicht existiert.

Fehlerbehandlung – HTTP-Exceptions & Error-Handler

abort · @app.errorhandler · custom errors
from flask import abort @app.route('/api/resource') def resource(): if not authorized: abort(401, 'Nicht autorisiert')

Fehlerbehandlung ist entscheidend für eine robuste API. Mit abort() können Sie HTTP-Fehler auslösen und mit @app.errorhandler benutzerdefinierte Fehlerantworten definieren.

Beispiele
# Benutzerdefinierte Fehlerklasse
class APIError(Exception):
def __init__(self, message, status_code=400):
self.message = message
self.status_code = status_code
# Error-Handler für 404
@app.errorhandler(404)
def not_found(error):
return jsonify({
'error': 'Nicht gefunden',
'message': 'Die angeforderte Ressource existiert nicht'
}), 404
# Error-Handler für 500
@app.errorhandler(500)
def internal_error(error):
db.session.rollback()
return jsonify({'error': 'Interner Serverfehler'}), 500
# Benutzerdefinierter Error-Handler für APIError
@app.errorhandler(APIError)
def handle_api_error(error):
return jsonify({
'error': error.message,
'status': error.status_code
}), error.status_code
# Verwendung in einer Route
@app.route('/api/validate')
def validate():
data = request.get_json()
if not data or 'name' not in data:
raise APIError('Feld "name" ist erforderlich', 400)
return jsonify({'valid': True})
Tipp: Erstellen Sie einen zentralen Error-Handler für Ihre API, um konsistente JSON-Fehlerantworten zu gewährleisten – das verbessert die Entwicklererfahrung erheblich.

JWT-Authentifizierung – Token-basierte Sicherheit

jwt · @jwt_required · get_jwt_identity
# Installation: pip install flask-jwt-extended from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity @app.route('/api/protected') @jwt_required() def protected(): user_id = get_jwt_identity()

JWT (JSON Web Tokens) ermöglicht eine sichere, token-basierte Authentifizierung für APIs. Der Client sendet das Token im Authorization-Header.

Beispiele
# Konfiguration
from flask_jwt_extended import JWTManager
app.config['JWT_SECRET_KEY'] = 'super-secret-key'
jwt = JWTManager(app)
# Login-Endpoint (Token erstellen)
@app.route('/api/login', methods=['POST'])
def login():
data = request.get_json()
# Benutzer validieren (Dummy-Check)
if data.get('username') == 'admin' and data.get('password') == 'secret':
access_token = create_access_token('admin')
return jsonify({'access_token': access_token})
return jsonify({'error': 'Ungültige Anmeldedaten'}), 401
# Geschützter Endpoint
@app.route('/api/protected')
@jwt_required()
def protected():
current_user = get_jwt_identity()
return jsonify({'user': current_user})
# Token-Refresh
@app.route('/api/refresh')
@jwt_required(refresh=True)
def refresh():
user = get_jwt_identity()
new_token = create_access_token(user)
return jsonify({'access_token': new_token})
Tipp: Verwenden Sie flask-jwt-extended für eine robuste JWT-Implementierung. Es unterstützt Token-Refresh, benutzerdefinierte Claims und vieles mehr.

Blueprints – Modulare API-Struktur

Blueprint · url_prefix · register_blueprint
# api/v1/users.py from flask import Blueprint, jsonify bp = Blueprint('users', __name__, url_prefix='/users') @bp.route('/') def get_users(): return jsonify([])

Blueprints ermöglichen die modulare Organisation Ihrer API – ideal für Versionierung (v1, v2) oder das Aufteilen nach Ressourcen.

Beispiele
# api/v1/__init__.py
from flask import Blueprint
api_v1 = Blueprint('api_v1', __name__, url_prefix='/api/v1')
# Routes importieren und registrieren
from . import users, posts, auth
# api/v1/users.py
from flask import jsonify, request
from . import api_v1
@api_v1.route('/users')
def get_users():
# Benutzer aus DB abrufen
return jsonify([{'id': 1, 'name': 'Anna'}])
@api_v1.route('/users/<int:user_id>')
def get_user(user_id):
return jsonify({'id': user_id, 'name': 'Anna'})
# app.py – Blueprint registrieren
from api.v1 import api_v1
app.register_blueprint(api_v1)
# Versionierung: V2 Blueprint
# api/v2/__init__.py
api_v2 = Blueprint('api_v2', __name__, url_prefix='/api/v2')
# app.py
from api.v1 import api_v1
from api.v2 import api_v2
app.register_blueprint(api_v1)
app.register_blueprint(api_v2)
Tipp: Nutzen Sie Blueprints für API-Versionierung – so können Sie alte Versionen parallel betreiben, während Sie neue entwickeln.

Rate Limiting & Security – API vor Überlastung schützen

@limiter · flask-limiter · CORS
# Installation: pip install flask-limiter from flask_limiter import Limiter limiter = Limiter(app, key_func=lambda: request.remote_addr) @app.route('/api/limited') @limiter.limit('5 per minute') def limited(): return jsonify({'ok': True})

Rate Limiting schützt Ihre API vor Überlastung durch zu viele Anfragen. CORS ermöglicht sicheren Zugriff von anderen Domains.

Beispiele
# Rate Limiting Konfiguration
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
limiter = Limiter(
app,
key_func=get_remote_address,
default_limits=['200 per day', '50 per hour']
)
# Endpoint-spezifische Limits
@app.route('/api/sensitive')
@limiter.limit('10 per minute')
def sensitive():
return jsonify({'data': 'sensible Daten'})
# CORS-Konfiguration
# pip install flask-cors
from flask_cors import CORS
# Einfache CORS-Konfiguration
CORS(app)
# Erweiterte CORS-Konfiguration
CORS(app, resources={
r'/api/*': {
'origins': ['http://localhost:3000', 'https://example.com'],
'methods': ['GET', 'POST', 'PUT', 'DELETE'],
'allow_headers': ['Content-Type', 'Authorization']
}
})
# Security-Header
@app.after_request
def add_security_headers(response):
response.headers['X-Content-Type-Options'] = 'nosniff'
response.headers['X-Frame-Options'] = 'DENY'
response.headers['X-XSS-Protection'] = '1; mode=block'
return response
Tipp: Kombinieren Sie Rate Limiting mit CORS und Security-Headern für eine sichere und robuste API. Verwenden Sie default_limits für globale Limits und überschreiben Sie sie bei Bedarf pro Endpoint.

Flask REST API im Überblick

jsonify JSON-Antworten
Content-Type: application/json
methods HTTP-Methoden
GET, POST, PUT, DELETE
abort Fehler auslösen
HTTP-Exceptions
JWT Authentifizierung
Token-basiert
Blueprint Modulare Struktur
Versionierung, Ressourcen
limiter Rate Limiting
Anfragenbegrenzung

Quick Summary

jsonify
JSON-Antwort
methods
HTTP-Methoden
abort
Fehlerbehandlung
JWT
Authentifizierung
Blueprint
Module
limiter
Rate Limiting
jsonify(data) · @jwt_required() · @limiter.limit("10 per minute")