Design Philosophy¶
This page outlines the core design principles that guided the development of Plinx. Understanding these principles provides insight into why certain design choices were made.
Core Principles¶
1. Simplicity Over Complexity¶
Plinx prioritizes simplicity in its API and implementation. We believe that a framework should be easy to understand, both for users and for developers who want to learn from the code. This means:
- Favoring explicit code over "magic" behaviors
- Keeping the API surface area small and focused
- Minimizing indirection and abstraction layers
- Making the common case easy and the complex case possible
Simplicity doesn't mean lack of power—it means thoughtfully designing interfaces that expose the right level of abstraction for the task at hand.
2. Educational Value¶
Plinx was designed partly as an educational tool. The codebase should be readable and approachable enough that someone can learn web framework design by studying it. This influenced decisions like:
- Clear, well-documented code with minimal "cleverness"
- Straightforward implementations that prioritize readability
- Thorough docstrings explaining not just what code does, but why
- A codebase small enough to be understood as a whole
We want Plinx to be a framework that helps developers understand how web frameworks and ORMs work under the hood.
3. Minimal Dependencies¶
Plinx aims to have as few external dependencies as possible. This makes the framework:
- Easier to install and deploy
- More stable across environments
- Less susceptible to security issues in dependencies
- More maintainable over time
The core dependencies (WebOb, parse) were chosen carefully for their stability, simplicity, and focused purpose.
4. Pythonic Design¶
The framework embraces Python's strengths and conventions:
- Using decorators for route registration (
@app.route("/path")) - Providing a clean, object-oriented interface
- Following PEP 8 style conventions
- Leveraging Python's dynamic nature where appropriate
- Using type hints to improve developer experience
5. Extensibility¶
While keeping the core simple, Plinx is designed to be extended and customized:
- The middleware system allows for flexible request/response processing
- Class-based views support inheritance and composition
- The ORM can be extended with custom methods and properties
- Core components are designed to be subclassed when needed
Design Decisions¶
WSGI Foundation¶
Plinx is built on the WSGI standard rather than newer async frameworks (like ASGI) for several reasons:
- WSGI is simpler and more straightforward to understand
- It has wider support across servers and platforms
- It's sufficient for many web applications
- It provides a solid foundation for learning web framework concepts
Explicit Request and Response Objects¶
Unlike some frameworks that use global request objects or return values as responses, Plinx explicitly passes request and response objects to handlers:
@app.route("/")
def home(request, response):
response.text = "Hello, World!"
This design:
- Makes the flow of data more obvious
- Avoids hidden state and global variables
- Makes testing easier
- Simplifies understanding how requests and responses work
Lightweight ORM¶
The ORM in Plinx is intentionally lightweight:
- It focuses on the core CRUD operations
- It uses Python classes to define tables
- It provides a natural way to work with relationships
- It avoids complex query building or lazy loading
This approach makes the ORM easy to learn and use, while still being useful for many applications.
Middleware Pattern¶
The middleware system follows a nested pattern instead of a linear chain. This design:
- Makes the request/response flow easy to understand
- Allows middleware to completely short-circuit the request if needed
- Provides symmetrical processing of requests and responses
- Follows established patterns in the Python web ecosystem
Tradeoffs¶
Every design involves tradeoffs. Some conscious tradeoffs in Plinx include:
Performance vs. Clarity¶
In some cases, we've chosen more readable code over maximum performance optimizations. For example:
- The ORM prioritizes a clean API over raw SQL performance
- The routing system uses pattern matching for flexibility rather than fastest possible lookups
- The middleware chain is simple rather than highly optimized
Features vs. Focus¶
We've deliberately left out many features that larger frameworks provide:
- No built-in template rendering
- No form processing helpers
- No authentication/authorization system
- No admin interface
- Limited ORM query capabilities
These omissions keep the framework focused and learnable, while allowing users to integrate third-party libraries when needed.
Flexibility vs. Convention¶
Plinx provides less "convention over configuration" than some frameworks:
- No enforced project structure
- Minimal automatic configuration
- Few built-in defaults
This gives users more freedom but requires more explicit choices.
Future Direction¶
While maintaining the core principles, future versions of Plinx may explore:
- Optional ASGI support
- More sophisticated routing
- Enhanced ORM capabilities
- Minimal template integration
- Additional helper utilities
However, any additions will be measured against the core principles to ensure Plinx remains true to its design philosophy.