DEV Community

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

Posted on

2 1

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! 🎉

Sentry blog image

How to reduce TTFB

In the past few years in the web dev world, we’ve seen a significant push towards rendering our websites on the server. Doing so is better for SEO and performs better on low-powered devices, but one thing we had to sacrifice is TTFB.

In this article, we’ll see how we can identify what makes our TTFB high so we can fix it.

Read more

Top comments (0)

Cloudinary image

Optimize, customize, deliver, manage and analyze your images.

Remove background in all your web images at the same time, use outpainting to expand images with matching content, remove objects via open-set object detection and fill, recolor, crop, resize... Discover these and hundreds more ways to manage your web images and videos on a scale.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay