DEV Community

Cover image for Mastering REST API Best Practices in Python 🐍
Biswajit Patra
Biswajit Patra

Posted on

Mastering REST API Best Practices in Python 🐍

APIs are like a good friend—helpful, responsive, and reliable. Let’s create a Python-based REST API following best practices using Flask. 😄


1. Foundational Design & Security 🛡️

Start with the basics: secure your API like it’s your grandma’s cookie recipe 🍪.

Authentication & Authorization 🔒

  • Authentication: Who are you? (Use tokens like JWTs)
  • Authorization: What are you allowed to do? (Role-based access control)

Example:

GET /api/orders
Authorization: Bearer <token>
Enter fullscreen mode Exit fullscreen mode

Example: Token Validation

from flask import Flask, request, jsonify
import jwt

app = Flask(__name__)
SECRET_KEY = "supersecretkey"

@app.route('/orders', methods=['GET'])
def protected():
    token = request.headers.get('Authorization')
    if not token:
        return jsonify({"error": "Token missing"}), 401
    try:
        jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
        return jsonify({"message": "Access granted"}), 200
    except jwt.ExpiredSignatureError:
        return jsonify({"error": "Token expired"}), 403
    except jwt.InvalidTokenError:
        return jsonify({"error": "Invalid token"}), 403
Enter fullscreen mode Exit fullscreen mode

Token validation like:

  • No token? 🚫 401 Unauthorized
  • Invalid token? 🚓 403 Forbidden

Rate Limiter 🚦

Limit user requests with Flask-Limiter.
Prevent abuse by limiting the number of requests per user.

Example:

  • First 100 requests: 🏎️ Smooth sailing.
  • After 101st request: 🐢 Slow down, buddy.
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address

limiter = Limiter(get_remote_address, app=app)

@app.route('/limited', methods=['GET'])
@limiter.limit("5 per minute")
def limited():
    return jsonify({"message": "You are within the limit!"})
Enter fullscreen mode Exit fullscreen mode

Versioning Strategy 📅

Make your APIs future-proof.

Example:

GET /api/v1/orders
Enter fullscreen mode Exit fullscreen mode

Plan ahead so that in 2025 you don’t regret skipping versioning like you regret your 2015 haircut. 😅


CORS Validation 🌐

Use Flask-CORS to restrict origins.

Example:

from flask_cors import CORS

app = Flask(__name__)
CORS(app, resources={r"/api/*": {"origins": "https://trusted-site.com"}})
Enter fullscreen mode Exit fullscreen mode

Trying from an untrusted site?

Response: "Sorry, not today! 🙅"


2. API Structure & Operations 🏗️

Let’s make your API user-friendly and idiot-proof! 😄

Clear CRUD Endpoints 🛠️

Keep it simple. No rocket science. Let’s manage a simple resource like users.

Example:

  • GET /users – Get all users 👥
  • POST /users – Create a new user ✍️
  • PUT /users/{id} – Update user 🛠️
  • DELETE /users/{id} – Delete user 🗑️

Confusing endpoints = confused developers = angry developers.

users = []

@app.route('/users', methods=['GET'])
def get_users():
    return jsonify(users)

@app.route('/users', methods=['POST'])
def create_user():
    user = request.json
    users.append(user)
    return jsonify(user), 201

@app.route('/users/<int:id>', methods=['PUT'])
def update_user(id):
    user = next((u for u in users if u['id'] == id), None)
    if user:
        user.update(request.json)
        return jsonify(user)
    return jsonify({"error": "User not found"}), 404

@app.route('/users/<int:id>', methods=['DELETE'])
def delete_user(id):
    global users
    users = [u for u in users if u['id'] != id]
    return '', 204
Enter fullscreen mode Exit fullscreen mode

Status-Based Responses 📜

Return clear HTTP status codes.

Example:

@app.route('/status', methods=['GET'])
def status_example():
    return jsonify({"message": "All good!"}), 200
Enter fullscreen mode Exit fullscreen mode

Always tell users what’s happening, politely.

Examples:

  • 200 OK – Yay, it worked! 🎉
  • 201 Created – Your shiny new resource is ready! 🚀
  • 400 Bad Request – Uh-oh, something’s wrong with your input. 🤷
  • 500 Internal Server Error – Oops, we broke something. 😓

API Documentation 📚

Use tools like Swagger or Postman.

Why?
Because an undocumented API is like IKEA furniture with no manual. 😭


Consistent Naming Conventions 📏

Stick to a pattern and never mix styles.

Example:

  • Good: /api/v1/products
  • Bad: /API/getProducts
  • Ugly: /api/v1/proDuctsGetNow

3. Performance & Scalability 🚀

Caching Strategy 🧊

Use Flask-Caching to store responses.

Example:

from flask_caching import Cache

cache = Cache(app, config={'CACHE_TYPE': 'simple'})

@app.route('/cached')
@cache.cached(timeout=60)
def cached_endpoint():
    return jsonify({"message": "This response is cached!"})
Enter fullscreen mode Exit fullscreen mode

Blue/Green Deployment 🌏💚

Deploy without breaking anything. Test on a “blue” version while users stay on “green.”

Steps:

  1. Deploy the “blue” environment.
  2. Test it.
  3. Gradually switch traffic to blue.
  4. Celebrate with cake 🎂.

Logging Mechanism 📝

Keep logs for debugging.

Pro Tip:
Logs should be helpful, not a novel. Nobody likes wading through War and Peace. 🫠

Log every request with Flask’s built-in logging.

Example:

import logging

logging.basicConfig(level=logging.INFO)

@app.before_request
def log_request_info():
    app.logger.info(f"Request: {request.method} {request.path}")
Enter fullscreen mode Exit fullscreen mode

4. Quality Assurance 🧪

Comprehensive Test Cases ✅

Test every scenario, even the absurd ones.

Example:

  • Does the API handle invalid inputs?
  • What happens if someone tries to upload a cat picture to /users? 🐱

Error Handling 🚨

Be friendly, even when rejecting users.

Example:

{
  "error": "Invalid email address. Did you mean: abc@gmail.com? 🤔"
}
Enter fullscreen mode Exit fullscreen mode

Input Validation 🛂

Validate everything. Trust no one.

Example:

  • User sends "age": "twenty".
  • Response: "Age must be a number."

Conclusion:

A great API isn’t just functional; it’s intuitive, secure, and scalable. Treat your API like your house: keep it clean, secure, and easy to navigate. 🏠✨

And remember: Developers using your API will silently thank you (and maybe buy you coffee ☕). Or, if you ignore best practices, you might just end up on their “wall of shame.” 🙃


What’s your favorite REST API best practice? Share below!👇 Let’s chat! 🎉

Top comments (0)