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

Top comments (0)