Skip to content

Commit c44de17

Browse files
feat(docs): Introduce decorator-based route mapping for REST controllers
- Added support for a declarative approach to route definition using decorators like `@GetMapping` and `@PostMapping`, enhancing code organization and type safety. - Updated documentation to reflect changes in the `RestController` class, including examples and key benefits of the new routing method.
1 parent 5cffa93 commit c44de17

File tree

2 files changed

+66
-67
lines changed

2 files changed

+66
-67
lines changed

docs/guide/entities-in-framework/rest-controller.md

Lines changed: 64 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ The `RestController` class in PySpring serves as a base class for building RESTf
1919

2020
### Create a Controller Class
2121

22-
Extend the `RestController` class and override the `register_routes()` method to define routes. Optionally, override `register_middlewares()` to add middleware.
22+
Extend the `RestController` class and use the route mapping decorators to define your API endpoints. Optionally, override `register_middlewares()` to add middleware.
2323

2424
### Example:
2525

2626
```py
2727
from py_spring_core import RestController
28+
from py_spring_core import GetMapping, PostMapping
2829
from fastapi import HTTPException
2930
from pydantic import BaseModel
3031

@@ -36,24 +37,23 @@ class MyController(RestController):
3637
class Config:
3738
prefix = "/api/items" # Base URL prefix for this controller
3839

39-
def register_routes(self):
40-
@self.router.get("/")
41-
def read_items():
42-
return {"message": "List of items"}
40+
@GetMapping("/")
41+
def read_items(self):
42+
return {"message": "List of items"}
4343

44-
@self.router.get("/{item_id}")
45-
def read_item(item_id: int):
46-
return {"message": f"Details for item {item_id}"}
44+
@GetMapping("/{item_id}")
45+
def read_item(self, item_id: int):
46+
return {"message": f"Details for item {item_id}"}
4747

48-
@self.router.post("/", status_code=201)
49-
def create_item(item: Item):
50-
return item
48+
@PostMapping("/", status_code=201)
49+
def create_item(self, item: Item):
50+
return item
5151
```
5252

5353
### Key Points:
5454

5555
- Use the `Config` inner class to set the route prefix.
56-
- Define routes using the `@self.router` decorator.
56+
- Define routes using the route mapping decorators (`@GetMapping`, `@PostMapping`, etc.).
5757

5858
* * * * *
5959

@@ -62,72 +62,69 @@ class MyController(RestController):
6262
2. The `_handle_register_rest_controller()` method:
6363
- Registers the controller with the application context.
6464
- Initializes an `APIRouter` instance.
65-
- Calls `register_routes()` to add routes.
65+
- Automatically registers routes defined with decorators.
6666
- Includes the controller's router in the main FastAPI application.
6767
- Calls `register_middlewares()` for middleware registration.
6868

6969
* * * * *
7070

7171
### Defining Routes
72-
Use `@self.router` decorators to define API endpoints inside `register_routes()`:
72+
PySpring provides a declarative approach to route definition using decorators, similar to Spring's annotation-based routing. This provides a cleaner and more type-safe way to define API endpoints.
7373

74-
```py
75-
@self.router.get("/")
76-
def read_items():
77-
return {"message": "List of items"}
78-
79-
@self.router.post("/", status_code=201)
80-
def create_item(item: Item):
81-
return item
82-
```
83-
### Example:
84-
85-
- `GET /` maps to the `read_items` method.
86-
- `POST /` maps to the `create_item` method.
74+
#### Available Decorators:
75+
- `@GetMapping`: For HTTP GET requests
76+
- `@PostMapping`: For HTTP POST requests
77+
- `@PutMapping`: For HTTP PUT requests
78+
- `@DeleteMapping`: For HTTP DELETE requests
79+
- `@PatchMapping`: For HTTP PATCH requests
8780

88-
### FastAPI Features:
89-
90-
- Dependency Injection
91-
- Request body handling
92-
- Path parameter parsing
93-
94-
* * * * *
95-
96-
### Defining Middlewares
97-
Override `register_middlewares()` to add middleware. Use `app.middleware()` to define custom middleware functions.
81+
#### Example Usage:
82+
```python
83+
from py_spring_core import RestController
84+
from py_spring_core import GetMapping, PostMapping, PutMapping, DeleteMapping
85+
from pydantic import BaseModel
9886

99-
### Example:
87+
class User(BaseModel):
88+
name: str
89+
email: str
10090

101-
```py
102-
def register_middlewares(self):
103-
@self.app.middleware("http")
104-
async def add_process_time_header(request, call_next):
105-
start_time = time.time()
106-
response = await call_next(request)
107-
process_time = time.time() - start_time
108-
response.headers["X-Process-Time"] = str(process_time)
109-
return response
91+
class UserController(RestController):
92+
class Config:
93+
prefix = "/api/users"
94+
95+
@GetMapping("/")
96+
def get_users(self):
97+
return {"users": []}
98+
99+
@GetMapping("/{user_id}")
100+
def get_user(self, user_id: int):
101+
return {"user_id": user_id}
102+
103+
@PostMapping("/")
104+
def create_user(self, user: User):
105+
return {"message": "User created", "user": user}
106+
107+
@PutMapping("/{user_id}")
108+
def update_user(self, user_id: int, user: User):
109+
return {"message": f"User {user_id} updated", "user": user}
110+
111+
@DeleteMapping("/{user_id}")
112+
def delete_user(self, user_id: int):
113+
return {"message": f"User {user_id} deleted"}
110114
```
111-
### Common Middleware Use Cases:
112-
- Authentication
113-
- Authorization
114-
- Logging
115-
- Performance metrics
116-
117-
### Accessing FastAPI Components
118-
- **`self.app`**: The main FastAPI application instance.
119-
- **`self.router`**: The APIRouter instance for the controller.
120115

116+
#### Key Benefits:
117+
1. **Type Safety**: Decorators provide better type checking and IDE support
118+
2. **Cleaner Code**: Route definitions are more concise and readable
119+
3. **Automatic Registration**: Routes are automatically registered during application initialization
120+
4. **Class-Level Prefixing**: Still supports the `Config.prefix` for base URL prefixing
121+
5. **Preserved Metadata**: Function metadata is preserved using `functools.wraps`
121122

122-
### Important Considerations
123-
1. **Class Configuration**: Use the `Config` class to define the URL prefix.
124-
2. **Route Registration**: Ensure all routes are defined in `register_routes()` using `@self.router`.
125-
3. **Middleware Registration**: Add middleware in `register_middlewares()` using `app.middleware()`.
126-
4. **Dependency Injection**: In this class, you can leverage both PySpring's and FastAPI's dependency injection systems to manage dependencies efficiently.
127-
5. **Error Handling**: Use `HTTPException` for proper error responses and integrate with PySpring's error handling mechanisms.
128-
6. **Code Organization**: Keep controllers focused on request handling and delegate business logic to services or components.
123+
#### Technical Details:
124+
- Routes are stored in a static `RouteMapping.routes` dictionary
125+
- Each route is registered with its HTTP method, path, and handler function
126+
- Route registration happens during application initialization
127+
- Decorators preserve function metadata for better introspection
129128

130-
* * * * *
131-
132-
### Summary
133-
The `RestController` class helps build well-structured, maintainable, and scalable RESTful APIs in PySpring. By utilizing its features like routing, middleware support, and integration with FastAPI, developers can focus on creating efficient APIs while maintaining code clarity and modularity.
129+
### Defining Middlewares
130+
Override `register_middlewares()`

docs/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939

4040
- **Component Registration Validation**: The framework includes robust validation to prevent duplicate component registration and provides clear error messages for developers. This ensures that your application maintains a clean and consistent component structure.
4141

42+
- **Decorator-Based Route Mapping**: PySpring now supports a more declarative approach to route definition using decorators, similar to Spring's annotation-based routing. This provides a cleaner and more type-safe way to define API endpoints with better IDE support and code organization.
43+
4244
### Getting Started
4345
To get started with **PySpring**, follow these steps:
4446

0 commit comments

Comments
 (0)