DEV Community

Cover image for Adding JSON Request and Response Support in a Lightweight Python Web Framework
HexShift
HexShift

Posted on

Adding JSON Request and Response Support in a Lightweight Python Web Framework

Modern web applications often use JSON as the primary format for sending and receiving data. Whether you're building REST APIs or single-page apps, your lightweight Python framework should be able to parse JSON from requests and return JSON in responses.


Why JSON Matters

JSON is the de facto standard for client-server communication in modern web development. It's supported by all major front-end frameworks and API consumers.

Supporting JSON enables your framework to:

  • Accept structured input from clients
  • Return machine-readable responses
  • Handle API endpoints cleanly

Reading JSON from Requests

Most clients sending JSON set the Content-Type header to application/json. Your framework needs to:

  1. Check that header
  2. Decode the request body
  3. Parse the JSON into a Python dictionary

Here’s a basic example:

import json

def parse_json_body(request):
    content_type = request["headers"].get("Content-Type", "")
    if "application/json" in content_type:
        try:
            body = request.get("body", b"")
            return json.loads(body.decode("utf-8"))
        except (ValueError, UnicodeDecodeError):
            return None
    return None
Enter fullscreen mode Exit fullscreen mode

Writing JSON Responses

To return JSON, serialize your Python object and set the correct headers:

def json_response(data, status=200):
    return {
        "status": status,
        "headers": {
            "Content-Type": "application/json"
        },
        "body": json.dumps(data).encode("utf-8")
    }
Enter fullscreen mode Exit fullscreen mode

Example Endpoint

A simple handler that accepts and returns JSON:

def echo_handler(request):
    data = parse_json_body(request)
    if data is None:
        return json_response({"error": "Invalid JSON"}, status=400)
    return json_response({"you_sent": data})
Enter fullscreen mode Exit fullscreen mode

Common Pitfalls

  • Missing Content-Type: Some clients forget to set headers; decide if you want to accept raw bodies anyway
  • Non-UTF8 encoding: JSON is expected to be UTF-8; reject otherwise
  • Invalid syntax: Always catch exceptions from json.loads()
  • Large payloads: Consider adding a max size check

JSON Middleware (Optional)

You can wrap JSON parsing into a middleware that adds .json to the request object:

def json_parser_middleware(request, next_handler):
    request["json"] = parse_json_body(request)
    return next_handler(request)
Enter fullscreen mode Exit fullscreen mode

Then in your handlers, access request["json"] directly.


Returning Errors in JSON

For consistency, even error messages should be structured:

def not_found():
    return json_response({"error": "Not found"}, status=404)
Enter fullscreen mode Exit fullscreen mode

Testing JSON Endpoints

Use curl for quick local testing:

curl -X POST http://localhost:8000/api/echo \
     -H "Content-Type: application/json" \
     -d '{"name": "Alice"}'
Enter fullscreen mode Exit fullscreen mode

Or use browser tools like Postman or HTTPie.


Wrap-Up

Adding JSON support makes your lightweight Python framework more powerful and compatible with modern frontend and mobile apps. It’s easy to implement and opens the door to building full-featured APIs.

Want to dive deeper? Check out my 20-page PDF guide: Building a Lightweight Python Web Framework from Scratch

Gen AI apps are built with MongoDB Atlas

Gen AI apps are built with MongoDB Atlas

MongoDB Atlas is the developer-friendly database for building, scaling, and running gen AI & LLM apps—no separate vector DB needed. Enjoy native vector search, 115+ regions, and flexible document modeling. Build AI faster, all in one place.

Start Free

Top comments (0)

Gen AI apps are built with MongoDB Atlas

Gen AI apps are built with MongoDB Atlas

MongoDB Atlas is the developer-friendly database for building, scaling, and running gen AI & LLM apps—no separate vector DB needed. Enjoy native vector search, 115+ regions, and flexible document modeling. Build AI faster, all in one place.

Start Free

👋 Kindness is contagious

Take a moment to explore this thoughtful article, beloved by the supportive DEV Community. Coders of every background are invited to share and elevate our collective know-how.

A heartfelt "thank you" can brighten someone's day—leave your appreciation below!

On DEV, sharing knowledge smooths our journey and tightens our community bonds. Enjoyed this? A quick thank you to the author is hugely appreciated.

Okay