# Controllers
Controllers in the MMO framework are responsible for handling HTTP requests and returning responses. They are defined as classes that extend the `aController` class and use the `APIRoute` attribute to define routes.
## Defining a Controller
To define a controller, create a class that extends the `aController` class. Use the `APIRoute` attribute to define routes for the controller methods.
> **WARNING: the first controller that matches the route is the one executed.** There can be only one
> controller per request.
### Example
```php
use MMO\core\classes\aController;
use MMO\core\attributes\APIRoute;
use MMO\core\server\Route;
use MMO\core\interfaces\iResponse;
class MyController extends aController {
#[APIRoute('GET|data/{repository}/{collection}.{format}', 'Get data from the repository', mediaTypes: ['json', 'csv'])]
public function getData(Route $route): iResponse {
// Route handling logic
}
}
```
**An answer should follow the general json api format wherever that applies** —
[the specification](https://jsonapi.org/format/#query-parameters-families).
## Answer's format
```json
{
data: {
index: {..} //index is for the pagination
},
links: {
self: //current url for this request
first: // if pagination first page for this request
last: // if pagination last page for this request
prev: // if pagination previous page for this request
next: // if pagination next page for this request
},
logs: [..] //server logs
}
```
## Entity querying
## Pagination
the pagination is provided in the query with `page[offset]` and `page[limit]`
Example: `xxx?page[offset]=0&page[limit]=10`
## Sort request
the sorting parameter is provided in the query as a comma separated value, with - for descending sorting
Example: `xxx?sort=-created,title => sort by create(DESC) and title(ASC)`
## Add/show fields
Example `xxx?fields=articles.title,-articles.body,people.name => article.body is hidden`
## Limit listing to ids
Example `xxx?listOnly`
## Filter request
the filter is provided as a family under the format `filter[xxx]`
Example:
```text
xxx?filter[age][>]=20&filter[age][<]=50&filter[author.status]=active
=> (age > 20) && (age < 50) && (author.status = active)
```
# Route Annotation in MMO Framework - Overview
The MMO framework uses the `APIRoute` attribute to define routes for controllers. This attribute allows you to specify the HTTP method, URL path, query parameters, request body, headers, and cookies for a route. It also provides options for setting the order of routes and hiding routes from API documentation.
## Usage
### Defining a Route
To define a route, use the `APIRoute` attribute on a controller method. The attribute takes the following parameters:
- **url**: The URL path for the route. It can include placeholders for path parameters.
- **info**: An array or string providing additional information about the route.
- **body**: An array or string defining the expected request body.
- **mediaTypes**: An array of supported media types for the request and response.
- **order**: An integer specifying the order of the route.
- **hidden**: A boolean indicating whether the route should be hidden from API documentation.
### Example
```php
use MMO\core\attributes\APIRoute;
use MMO\core\server\Route;
use MMO\core\interfaces\iResponse;
class MyController {
#[APIRoute('GET|data/{repository}/{collection}.{format}', 'Get data from the repository', mediaTypes: ['json', 'csv'])]
public function getData(Route $route): iResponse {
// Route handling logic
}
}
```
In this example, the `getData` method is defined as a route that handles `GET` requests to the URL `data/{repository}/{collection}.{format}`. The route supports `json` and `csv` media types and includes additional information about the route.
## Path Placeholders
The URL path can include placeholders for path parameters. These placeholders are defined using curly braces `{}` and can specify a type and whether the parameter is required.
### Example
```php fragment
#[APIRoute('GET|data/{repository:string}/{collection:string}.{format:json}', 'Get data from the repository')]
public function getData(Route $route): iResponse {
// Route handling logic
}
```
In this example, the URL path includes placeholders for `repository`, `collection`, and `format`. The `repository` and `collection` parameters are required and must be strings, while the `format` parameter is optional and defaults to `json`.
## Query Parameters, Headers, and Cookies
Query parameters are part of the url itself, after a `?`, with the same placeholders (a `?` inside the braces
makes one optional). Headers and cookies have no attribute argument: set them on the route object with
`setHeader()` / `setCookie()` (a query-string or an array of `name => placeholder|schema`), e.g. when a route is
built with `new APIRoute(...)` instead of the attribute.
### Example
```php fragment
#[APIRoute('GET|data?page={?page:integer}&limit={?limit:integer}', 'Get one page of data')]
public function getData(Route $route): iResponse {
// Route handling logic
}
```
In this example, `page` and `limit` are optional query parameters, validated and coerced to integers.