The create:controller command generates a new controller file with your choice of API or templated responses.
Usage
framefox create:controller [name]
Arguments
The name of the controller in snake_case. If not provided, you’ll be prompted to enter it.
Controller Types
You’ll be prompted to choose between two controller types:
1. API Controller
Creates a controller that returns JSON responses, ideal for REST APIs.
Features:
JSON response format
RESTful endpoints
No template rendering
Perfect for SPAs and mobile apps
2. Templated Controller
Creates a controller that renders HTML templates.
Features:
Renders Jinja2 templates
Automatic view directory creation
Base template file included
Server-side rendering
Examples
Interactive Mode
$ framefox create:controller
What is the name of the controller ? ( snake_case )
Controller name: user
What type of controller do you want to create?
1. API controller (JSON responses )
2. Templated controller (HTML responses with views )
Controller type: 1
API Controller created successfully: src/controller/user_controller.py
With Name Argument
framefox create:controller product
API Controller Example
Creates src/controller/user_controller.py:
from framefox.core.http.response import Response
from framefox.core.routing.decorator.route import route
"""
Controller: UserController
Generated: 2024-01-15T10:30:00
"""
class UserController :
@route ( "/user" , methods = [ "GET" ])
def index ( self ) -> Response:
"""List all users"""
return Response.json({
"users" : [],
"message" : "User list"
})
@route ( "/user/<int:id>" , methods = [ "GET" ])
def show ( self , id : int ) -> Response:
"""Show a specific user"""
return Response.json({
"id" : id ,
"message" : "User details"
})
@route ( "/user" , methods = [ "POST" ])
def create ( self ) -> Response:
"""Create a new user"""
return Response.json({
"message" : "User created"
}, status = 201 )
@route ( "/user/<int:id>" , methods = [ "PUT" ])
def update ( self , id : int ) -> Response:
"""Update a user"""
return Response.json({
"id" : id ,
"message" : "User updated"
})
@route ( "/user/<int:id>" , methods = [ "DELETE" ])
def delete ( self , id : int ) -> Response:
"""Delete a user"""
return Response.json({
"id" : id ,
"message" : "User deleted"
})
Templated Controller Example
Creates src/controller/user_controller.py:
from framefox.core.http.response import Response
from framefox.core.routing.decorator.route import route
class UserController :
@route ( "/user" , methods = [ "GET" ])
def index ( self ) -> Response:
"""Display the user list page"""
return Response.render( "user/index.html" , {
"title" : "Users" ,
"users" : []
})
And creates templates/user/index.html:
{% extends "base.html" %}
{% block title %}User{% endblock %}
{% block content %}
< div class = "container" >
< h1 > User Page </ h1 >
< p > Welcome to the User controller </ p >
</ div >
{% endblock %}
File Locations
Controller File
src/controller/{name}_controller.py
Template Directory (Templated Only)
templates/{name}/
└── index.html
Naming Conventions
Controller names must be in snake_case . The command automatically converts them to PascalCase for class names.
Examples:
Input (snake_case) Class Name (PascalCase) File Name user UserController user_controller.py user_profile UserProfileController user_profile_controller.py api_webhook ApiWebhookController api_webhook_controller.py
Validation
The command performs several checks:
Name Format - Must be snake_case
Controller Exists - Prevents overwriting existing controllers
Template Exists - Checks for existing template directories
Error Examples
# Invalid name format
$ framefox create:controller UserController
Invalid name. Must be in snake_case.
# Controller already exists
$ framefox create:controller user
Controller user already exists!
Working with Controllers
Verify Routes
After creating a controller, verify it’s registered:
Test the Endpoint
API Controller:
curl http://localhost:8000/user
Templated Controller:
curl http://localhost:8000/user
# or open in browser
Customizing Controllers
After generation, you can:
Add Dependencies - Inject services via constructor
Add Middleware - Apply authentication, validation, etc.
Add More Routes - Use the @route decorator
Customize Response - Modify status codes, headers, etc.
Example with Dependency Injection
from framefox.core.di.decorator.service import service
from src.repository.user_repository import UserRepository
@service
class UserController :
def __init__ ( self , user_repository : UserRepository):
self .user_repository = user_repository
@route ( "/user" , methods = [ "GET" ])
def index ( self ) -> Response:
users = self .user_repository.find_all()
return Response.json([user.to_dict() for user in users])
Best Practices
Use API controllers for frontends (React, Vue, Angular)
Use templated controllers for server-side rendered pages
Keep controllers thin - move business logic to services
Use one controller per resource (users, products, orders, etc.)
Follow RESTful conventions for endpoint naming
Next Steps
Create Entity Generate entities for database models
Create CRUD Generate complete CRUD operations
Debug Routes View all registered routes