fix api routing and config paths
This commit is contained in:
+5
-1
@@ -7,7 +7,7 @@ Queste regole definiscono il comportamento per tutti gli sviluppi futuri su ques
|
|||||||
Tutte le dipendenze devono essere iniettate tramite costruttore. Il container in `bootstrap.php` provvederà all'autowiring automatico.
|
Tutte le dipendenze devono essere iniettate tramite costruttore. Il container in `bootstrap.php` provvederà all'autowiring automatico.
|
||||||
|
|
||||||
2. **Namespace e Struttura dei Controller**
|
2. **Namespace e Struttura dei Controller**
|
||||||
Tutti i nuovi Controller devono essere posizionati all'interno della cartella relativa alla loro versione (es. `src/Controllers/V1/`) e devono avere il namespace corretto (es. `namespace Controllers\V1;`). Questo permette al `Router` di mapparli automaticamente partendo dalle route versionate (es. `/v1/risorsa`).
|
Tutti i nuovi Controller devono essere posizionati all'interno della cartella relativa alla loro versione (es. `src/Api/Controllers/V1/`) e devono avere il namespace corretto (es. `namespace Api\Controllers\V1;`). Questo permette al `Router` di mapparli automaticamente partendo dalle route versionate (es. `/v1/risorsa`).
|
||||||
|
|
||||||
3. **Risposte HTTP Standard**
|
3. **Risposte HTTP Standard**
|
||||||
Non utilizzare mai funzioni di output diretto (come `echo`, `print` o `header()`) all'interno dei Controller.
|
Non utilizzare mai funzioni di output diretto (come `echo`, `print` o `header()`) all'interno dei Controller.
|
||||||
@@ -19,3 +19,7 @@ Queste regole definiscono il comportamento per tutti gli sviluppi futuri su ques
|
|||||||
|
|
||||||
5. **Validazione dell'Input**
|
5. **Validazione dell'Input**
|
||||||
Assicurati sempre di validare l'input proveniente da `$req->body()` o dai parametri URL prima di processarlo con la business logic applicativa. (Consigliato l'uso di DTO).
|
Assicurati sempre di validare l'input proveniente da `$req->body()` o dai parametri URL prima di processarlo con la business logic applicativa. (Consigliato l'uso di DTO).
|
||||||
|
|
||||||
|
6. **Routing API e prefissi di versione**
|
||||||
|
Le route devono essere registrate senza il prefisso `/api` e senza il prefisso di versione (es. usare `/users` invece di `/api/users` o `/api/v1/users`). Il router deve normalizzare i percorsi in ingresso rimuovendo il prefisso `/api` prima di confrontarli con le route registrate, così richieste come `/api/users` e `/api/v1/users` continuano a funzionare.
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -44,9 +44,9 @@ if (strpos($request->path(), '/api/') === 0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// register routes (path without version prefix)
|
// register routes (path without version prefix)
|
||||||
$router->get('/users', 'UsersController@index');
|
$router->get('/users/index', 'UsersController@index');
|
||||||
$router->post('/users', 'UsersController@create');
|
$router->post('/users/create', 'UsersController@create');
|
||||||
$router->get('/example', 'ExampleController@test');
|
$router->get('/example/test', 'ExampleController@test');
|
||||||
|
|
||||||
// Rate limiting by IP address
|
// Rate limiting by IP address
|
||||||
$key = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
|
$key = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Api\Controllers\v1;
|
namespace Api\Controllers\V1;
|
||||||
|
|
||||||
use Api\Core\Request;
|
use Api\Core\Request;
|
||||||
use Api\Core\Response;
|
use Api\Core\Response;
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ class Config {
|
|||||||
|
|
||||||
private function loadConfig() {
|
private function loadConfig() {
|
||||||
if ($this->config === null) {
|
if ($this->config === null) {
|
||||||
$file = __DIR__ . '/../../config/config.php';
|
$file = __DIR__ . '/../../../config/config.php';
|
||||||
$this->config = file_exists($file) ? require $file : [];
|
$this->config = file_exists($file) ? require $file : [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function loadSecrets() {
|
private function loadSecrets() {
|
||||||
if ($this->secrets === null) {
|
if ($this->secrets === null) {
|
||||||
$file = __DIR__ . '/../../config/secrets.php';
|
$file = __DIR__ . '/../../../config/secrets.php';
|
||||||
$this->secrets = file_exists($file) ? require $file : [];
|
$this->secrets = file_exists($file) ? require $file : [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-4
@@ -16,9 +16,17 @@ class Router {
|
|||||||
public function get($path, $handler) { $this->register('GET', $path, $handler); }
|
public function get($path, $handler) { $this->register('GET', $path, $handler); }
|
||||||
public function post($path, $handler) { $this->register('POST', $path, $handler); }
|
public function post($path, $handler) { $this->register('POST', $path, $handler); }
|
||||||
|
|
||||||
|
private function normalizePath(string $path): string {
|
||||||
|
$path = '/' . trim($path, '/');
|
||||||
|
$path = preg_replace('#^/api(?=/|$)#i', '', $path);
|
||||||
|
$path = '/' . trim($path, '/');
|
||||||
|
|
||||||
|
return $path === '' ? '/' : $path;
|
||||||
|
}
|
||||||
|
|
||||||
public function dispatch(Request $req, Response $res) {
|
public function dispatch(Request $req, Response $res) {
|
||||||
$method = $req->method();
|
$method = $req->method();
|
||||||
$path = $req->path();
|
$path = $this->normalizePath($req->path());
|
||||||
|
|
||||||
// extract version prefix /v1/...
|
// extract version prefix /v1/...
|
||||||
if (preg_match('#^/v([0-9]+)(/.*)?$#', $path, $m)) {
|
if (preg_match('#^/v([0-9]+)(/.*)?$#', $path, $m)) {
|
||||||
@@ -39,9 +47,9 @@ class Router {
|
|||||||
// handler can be 'UsersController@index' or 'Controllers\\UsersController@index'
|
// handler can be 'UsersController@index' or 'Controllers\\UsersController@index'
|
||||||
if (strpos($handler, '@') !== false) {
|
if (strpos($handler, '@') !== false) {
|
||||||
list($class, $function) = explode('@', $handler);
|
list($class, $function) = explode('@', $handler);
|
||||||
// if class not namespaced, prefix with Controllers\V{n}\
|
// if class not namespaced, prefix with Api\\Controllers\\V{n}\\
|
||||||
if (strpos($class, '\\') === false) {
|
if (strpos($class, '\\') === false) {
|
||||||
$class = "Controllers\\V{$version}\\" . $class;
|
$class = "Api\\Controllers\\V{$version}\\" . $class;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return $res->json(['error' => 'Invalid handler'], 500);
|
return $res->json(['error' => 'Invalid handler'], 500);
|
||||||
@@ -51,7 +59,6 @@ class Router {
|
|||||||
return $res->json(['error' => 'Controller not found'], 500);
|
return $res->json(['error' => 'Controller not found'], 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
// snippet inside Router::dispatch
|
|
||||||
$controller = $this->container->make($class);
|
$controller = $this->container->make($class);
|
||||||
return $controller->$function($req, $res);
|
return $controller->$function($req, $res);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user