Background
Have you encountered such troubles: taking over an API project only to find messy code structure, vulnerable security, and missing documentation? As a Python developer, I deeply relate to this. Through years of practice, I've gradually developed an effective methodology for API development. Today I'd like to share with you how to build a truly highly available interface service from dimensions like architectural design, security protection, and quality assurance.
Framework Selection
In Python web development, Flask and Django are the two most popular frameworks. So how should we choose between them for API development?
Flask is lightweight and flexible, making it very suitable for building microservices. See how concise this code is:
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/api/users', methods=['GET'])
def get_users():
users = [{'id': 1, 'name': 'Zhang San'}, {'id': 2, 'name': 'Li Si'}]
return jsonify(users)
While Django REST Framework provides a more complete toolkit:
from rest_framework import viewsets
from .models import User
from .serializers import UserSerializer
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
My suggestion is: Flask is more suitable for small projects or microservice architecture; if it's a large project needing complete ORM support, Django REST Framework would be more worry-free.
Version Management
API version management is an often overlooked but extremely important topic. In projects I've participated in, we frequently encounter situations where old and new versions coexist.
The simplest way is to reflect the version number in the URL:
@app.route('/api/v1/users')
def api_v1():
return "API v1"
@app.route('/api/v2/users')
def api_v2():
return "API v2"
However, I recommend using request headers to control versions, which keeps URLs cleaner. Just remember to clearly specify version compatibility in the documentation.
Authentication Mechanism
Security is always paramount in API development. JWT (JSON Web Token) is one of the most popular authentication solutions currently:
from jwt import encode, decode
def create_token(user_id):
payload = {
'user_id': user_id,
'exp': datetime.utcnow() + timedelta(days=1)
}
return encode(payload, 'secret_key', algorithm='HS256')
Pay special attention to token expiration settings here. In practice, I've found that setting a 1-day validity period is reasonable, ensuring security while not requiring users to log in frequently.
Access Control
An API without rate limiting is like a bridge without guardrails - looks smooth but is actually dangerous. Using Flask-Limiter makes it easy to implement rate limiting:
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"]
)
My experience is to set different rate limiting strategies based on the importance of interfaces. For example, login interfaces can be set more strictly, while query interfaces can be relatively lenient.
Data Validation
"Garbage in, garbage out" is particularly applicable in API development. Using marshmallow for data validation is a good choice:
from marshmallow import Schema, fields
class UserSchema(Schema):
name = fields.Str(required=True)
email = fields.Email(required=True)
age = fields.Int(required=True)
This ensures incoming data meets expected formats and prevents dirty data from contaminating the database.
Graceful Handling
Finally, let's talk about error handling. An excellent API should handle various exceptions gracefully:
from flask import jsonify
@app.errorhandler(404)
def not_found(error):
return jsonify({
'error': 'Not found',
'status_code': 404
}), 404
I suggest using a unified return format, which makes it more convenient for frontend handling:
def format_response(data, status=200, message="Success"):
return jsonify({
"status": status,
"message": message,
"data": data
})
What do you think about this API development approach? Is there anything that needs to be added? Welcome to discuss with me in the comments.