> ## Documentation Index
> Fetch the complete documentation index at: https://docs-fw.madbuilder.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# 2. Obtendo Parâmetros da URL

> Este guia mostra como capturar e trabalhar com parâmetros enviados pela URL em seus controllers (ou services), seja através de parâmetros na rota ou através do objeto Request.
Quando criamos rotas personalizadas (como vimos no capítulo anterior), frequentemente precisamos obter dados enviados pelo cliente. Esses dados podem vir de diferentes formas: parâmetros na URL, query strings, headers HTTP, corpo da requisição, cookies e até mesmo tokens de autenticação. 

## Passo 1: Parâmetros de Rota Diretamente no Método

A forma mais simples de capturar parâmetros da URL é defini-los diretamente como argumentos do seu método no controller.

Primeiro, vamos criar uma rota que aceita parâmetros. No arquivo `app/routes/api.php`:

```php theme={null}
// Em: app/routes/api.php

Router::group([
    'prefix' => '/api'
], function () {
    Router::get('/cidade/{id}/{unidade_id}', 'ApiExemploService::getCidade');
});
```

Neste exemplo, vamos utilizar uma service para capturar os parâmetros da URL:

```php theme={null}
// Em: app/service/ApiExemploService.php

<?php
use Mad\Rest\Response;

class ApiExemploService
{
    public static function getCidade($id, $unidade_id)
    {
        // Retorna uma resposta JSON para mostrar os parâmetros capturados
        return (new Response())->json([
            'cidade_id' => $id,
            'unidade_id' => $unidade_id,
            'message' => 'Parâmetros capturados com sucesso!'
        ]);
    }
}
```

Após enviar uma requisição GET `{{base_url}}/api/exemplo/15/3` via *Postman API*, o resultado será:

![Capturando parâmetros da URL](https://monosnap.ai/image/hJUzIqjT1jMTQ6pTy39CfiB1cFnK3c)

***

## Passo 2: Usando o Objeto `Request` para Maior Flexibilidade

Para ter mais controle e acesso a informações adicionais da requisição, você pode usar a classe `Request`. Esta classe oferece vários métodos úteis para capturar diferentes tipos de dados.

```php theme={null}
// Em: app/service/ApiExemploService.php

<?php
use Mad\Rest\Request;

class ApiExemploService 
{
    public static function getCidade($id, $unidade_id, Request $request)
    {
        // Agora você tem acesso tanto aos parâmetros da rota
        // quanto ao objeto Request para informações adicionais
        
        // Sua lógica aqui...
    }
}
```

### Métodos Disponíveis no Request

Dentro os métodos que a classe `Request` oferece, estes são os que nos permitem capturar dados via API:

#### 1. `get($chave)` - Parâmetros Individuais

Captura um parâmetro específico enviado na requisição (GET, POST, etc.).

```php theme={null}
use Mad\Rest\Request;
use Mad\Rest\Response;

class ApiExemploService
{
    public static function getCidade($id, $unidade_id, Request $request)
    {
        // Captura parâmetros específicos da requisição
        $filtro = $request->get('filtro');
        $limite = $request->get('limite');
        
        ...

        // Retorna uma resposta JSON para mostrar os parâmetros capturados
        return (new Response())->json([
            'id_rota' => $id,
            'unidade_rota' => $unidade_id,
            'filtro_enviado' => $filtro,
            'limite_enviado' => $limite
        ]);
    }
}
```

Exemplo de requisição GET: `{{base_url}}/api/exemplo/15/3?filtro=ativo&limite=10`

![Capturando parâmetros da URL 2](https://monosnap.ai/image/YPsTW4xcGbN3AMCc0f3dZZqCm5xTMp)

#### 2. `getParams()` - Todos os Parâmetros

Retorna um array com todos os parâmetros enviados na requisição.

```php theme={null}
use Mad\Rest\Request;

class ApiExemploService
{
    public static function getCidade($id, $unidade_id, Request $request)
    {
        // Captura todos os parâmetros de uma vez
        $todosParametros = $request->getParams();

        ...

        // Executando função `print_r()` em modo de `return = true` para exibir os parâmetros
        return '<pre>' . print_r($todosParametros, true) . '</pre>';
    }
}
```

Exemplo de requisição GET:

![Requisição GET getParams](https://monosnap.ai/image/cejw8Yv6GjsHe8hU0PT4HxPhFXekXN)

As tags `<pre>` são usada para "embelezar" a visualização do array. Veja abaixo o resultado no modo de "Preview" do *Postman API*:

![Resposta GET getParams](https://monosnap.ai/image/b1LJvr8cqwzJDK3OWKco6dVak69Wjy)

> **Observação:** perceba que, além dos parâmetros enviados via "body", constam também os que foram inseridos na URL.

#### 3. `getHeaders()` - Headers HTTP

Captura todos os headers HTTP enviados pelo cliente.

```php theme={null}
use Mad\Rest\Request;
use Mad\Rest\Response;

public static function getCidade($id, $unidade_id, Request $request)
{
    // Captura todos os headers HTTP enviados pelo cliente
    $headers = $request->getHeaders();
    
    return (new Response())->json([
        'content_type' => $headers['Content-Type'] ?? 'não informado',
        'user_agent' => $headers['User-Agent'] ?? 'não informado',
        'host' => $headers['Host'] ?? 'não informado'
    ]);
}
```

Exemplo de seleção de headers na requisição (no mesmo endpoint que os exemplos anteriores):

![Requisição GET getHeaders](https://monosnap.ai/image/P5cyV0XM4o5hMfVzQmZi2oJdgp3GuB)

E o resultado:

![Resposta GET getHeaders](https://monosnap.ai/image/QSDFtX5tBF3Ko0OsEsX8TeMOjEvBVF)

> **Observação:** Perceba que, além dos headers enviados manualmente, constam também headers gerados automaticamente, como `User-Agent` e `Host`.

#### 4. `getAuthToken()` - Token de Autenticação

Caso tenha sido enviado, captura o token de autenticação. O padrão mais comum é enviá-lo no header `Authorization` com o prefixo `Bearer`, `Basic`, etc.

```php theme={null}
use Mad\Rest\Request;
use Mad\Rest\Response;

class ApiExemploService
{
    public static function getCidade($id, $unidade_id, Request $request)
    {
        try {
            // Captura o token de autenticação
            $token = $request->getAuthToken();
        
            // Valida o token e obtém os dados do usuário
            $usuario = self::autenticarUsuarioPeloToken($token);
        
            // Se chegou aqui, o usuário está autenticado
            return (new Response())->json([
                'status' => 'sucesso',
                'mensagem' => "Bem-vindo, {$usuario['nome']}!",
                'token' => $token
            ]);

        } catch (Exception $e) {
            // Se a autenticação falhar, retorna um erro 401 (Não Autorizado)
            return (new Response())->json([
                'status' => 'erro',
                'mensagem' => $e->getMessage(),
                'token' => $token
            ], 401);
        }
    }

    /**
     * Valida um token (método fictício).
     * @throws Exception Se o token for nulo ou inválido.
     */
    private static function autenticarUsuarioPeloToken(?string $token): array
    {
        if (empty($token)) {
            throw new Exception('Token de autenticação não fornecido.');
        }

        // Em um caso real, você consultaria o banco de dados ou decodificaria um JWT.
        if ($token !== 'meu-token-secreto-123') {
            throw new Exception('Token inválido ou expirado.');
        }

        // Retorna dados do usuário fictício
        return ['id' => 1, 'nome' => 'Usuário Teste'];
    }
}
```

Ao enviar uma requisição GET sem token de autenticação (no mesmo endpoint que os exemplos anteriores):

![Resposta GET getAuthToken não fornecido](https://monosnap.ai/image/lkYauiqg48bogr7pAwvQztNxhZFP5F)

Da mesma forma, enviar um token inválido também causa um *Erro 401*:

![Requisição GET getAuthToken inválido](https://monosnap.ai/image/JA87OuqcG0la2d1scmVXSDO9ZOKT9i)

Veja o resultado:

![Resposta GET getAuthToken inválido](https://monosnap.ai/image/Pxj3808XWRfC7zOuJ1jqmApNemOM3S)

Finalmente, ao enviar um token válido, recebemos um código **200 OK**:

![Requisição GET getAuthToken válido](https://monosnap.ai/image/sNuZwDwjh3BfGyAob20hexWq8zrdZM)

Resposta:

![Resposta GET getAuthToken válido](https://monosnap.ai/image/SnWgTef1VVepDZblw7Tu3AN7Q7eh75)

> **Observação:** autenticação e middlewares serão abordados em maior detalhe em capítulos posteriores.

Assim, capturamos os parâmetros da requisição e personalizamos a resposta.
