API

Crear API REST en tu Módulo Perfex

J. Negro 8 Dic 2025 20 min lectura
Volver al Blog

Introducción a las APIs en Perfex

Perfex CRM incluye soporte nativo para APIs REST que permite exponer los datos de tu módulo a aplicaciones externas: apps móviles, integraciones con otros sistemas o automatizaciones.

💡 ¿Por qué crear una API?

  • Integrar con aplicaciones móviles
  • Conectar con sistemas externos (ERP, CRM)
  • Automatizar procesos con Zapier/n8n
  • Crear dashboards externos

Estructura de Endpoints

Define tus endpoints siguiendo el estándar REST:

GET /api/mi_modulo/productos

Lista todos los productos

GET /api/mi_modulo/productos/{id}

Obtiene un producto específico

POST /api/mi_modulo/productos

Crea un nuevo producto

PUT /api/mi_modulo/productos/{id}

Actualiza un producto existente

DELETE /api/mi_modulo/productos/{id}

Elimina un producto

Crear el Controlador API

Crea un controlador específico para la API que maneje las peticiones REST:

<?php
defined('BASEPATH') or exit('No direct script access allowed');

class Mi_modulo_api extends AdminController
{
    private $api_key;

    public function __construct()
    {
        parent::__construct();
        $this->load->model('productos_model');

        // Validar autenticación API
        $this->validar_api_key();
    }

    /**
     * Validar API Key en headers
     */
    private function validar_api_key()
    {
        $api_key = $this->input->get_request_header('X-API-KEY', TRUE);

        if (!$api_key) {
            $this->responder_error('API Key requerida', 401);
        }

        // Verificar key en base de datos
        $valida = $this->db
            ->where('api_key', $api_key)
            ->where('activo', 1)
            ->get(db_prefix() . 'mi_modulo_api_keys')
            ->row();

        if (!$valida) {
            $this->responder_error('API Key inválida', 403);
        }

        $this->api_key = $valida;
    }

    /**
     * GET /api/mi_modulo/productos
     */
    public function productos()
    {
        $method = $this->input->method();

        switch ($method) {
            case 'get':
                $this->listar_productos();
                break;
            case 'post':
                $this->crear_producto();
                break;
            default:
                $this->responder_error('Método no permitido', 405);
        }
    }

    /**
     * GET /api/mi_modulo/productos/{id}
     */
    public function producto($id = null)
    {
        $method = $this->input->method();

        if (!$id) {
            $this->responder_error('ID requerido', 400);
        }

        switch ($method) {
            case 'get':
                $this->obtener_producto($id);
                break;
            case 'put':
                $this->actualizar_producto($id);
                break;
            case 'delete':
                $this->eliminar_producto($id);
                break;
            default:
                $this->responder_error('Método no permitido', 405);
        }
    }
}

Métodos CRUD

Implementa los métodos que manejan cada operación:

/**
 * Listar todos los productos
 */
private function listar_productos()
{
    // Parámetros de paginación
    $page  = (int) $this->input->get('page') ?: 1;
    $limit = (int) $this->input->get('limit') ?: 20;
    $offset = ($page - 1) * $limit;

    // Filtros opcionales
    $categoria = $this->input->get('categoria');
    $busqueda  = $this->input->get('q');

    $this->db->select('*');
    $this->db->from(db_prefix() . 'mi_modulo_productos');
    $this->db->where('activo', 1);

    if ($categoria) {
        $this->db->where('categoria_id', $categoria);
    }

    if ($busqueda) {
        $this->db->like('nombre', $busqueda);
    }

    // Total para paginación
    $total = $this->db->count_all_results('', false);

    // Obtener resultados paginados
    $productos = $this->db
        ->limit($limit, $offset)
        ->get()
        ->result_array();

    $this->responder([
        'data'       => $productos,
        'pagination' => [
            'page'       => $page,
            'limit'      => $limit,
            'total'      => $total,
            'total_pages' => ceil($total / $limit)
        ]
    ]);
}

/**
 * Crear nuevo producto
 */
private function crear_producto()
{
    // Obtener JSON del body
    $json = file_get_contents('php://input');
    $data = json_decode($json, true);

    // Validar campos requeridos
    $requeridos = ['nombre', 'precio'];
    foreach ($requeridos as $campo) {
        if (empty($data[$campo])) {
            $this->responder_error("Campo {$campo} es requerido", 422);
        }
    }

    // Sanitizar datos
    $producto = [
        'nombre'      => strip_tags($data['nombre']),
        'descripcion' => strip_tags($data['descripcion'] ?? ''),
        'precio'      => (float) $data['precio'],
        'stock'       => (int) ($data['stock'] ?? 0),
        'datecreated' => date('Y-m-d H:i:s')
    ];

    $this->db->insert(db_prefix() . 'mi_modulo_productos', $producto);
    $id = $this->db->insert_id();

    $this->responder([
        'message' => 'Producto creado exitosamente',
        'id'      => $id
    ], 201);
}

Helpers de Respuesta

Crea métodos helper para formatear las respuestas JSON:

/**
 * Responder con JSON exitoso
 */
private function responder($data, $status = 200)
{
    $this->output
        ->set_status_header($status)
        ->set_content_type('application/json')
        ->set_output(json_encode([
            'success' => true,
            ...$data
        ]));
    exit;
}

/**
 * Responder con error
 */
private function responder_error($mensaje, $status = 400)
{
    $this->output
        ->set_status_header($status)
        ->set_content_type('application/json')
        ->set_output(json_encode([
            'success' => false,
            'error'   => [
                'code'    => $status,
                'message' => $mensaje
            ]
        ]));
    exit;
}

🔒 Seguridad Importante

Nunca expongas datos sensibles en tu API. Valida siempre los permisos del usuario asociado a la API key y limita los campos que se devuelven.

Registrar Rutas

Añade las rutas de tu API en el archivo de rutas del módulo:

// config/routes.php del módulo

// Rutas API
$route['api/mi_modulo/productos'] = 'mi_modulo/mi_modulo_api/productos';
$route['api/mi_modulo/productos/(:num)'] = 'mi_modulo/mi_modulo_api/producto/$1';

Ejemplo de Uso

# Listar productos
curl -X GET "https://tucrm.com/api/mi_modulo/productos?page=1&limit=10" \
  -H "X-API-KEY: tu_api_key_aqui"

# Crear producto
curl -X POST "https://tucrm.com/api/mi_modulo/productos" \
  -H "X-API-KEY: tu_api_key_aqui" \
  -H "Content-Type: application/json" \
  -d '{"nombre": "Producto Nuevo", "precio": 99.99}'

# Respuesta exitosa
{
  "success": true,
  "message": "Producto creado exitosamente",
  "id": 123
}

✅ API Lista

Ya tienes una API REST funcional con autenticación, validación y respuestas estructuradas. Puedes extenderla con más endpoints según las necesidades de tu módulo.

JN

J. Negro

Desarrollador especializado en Perfex CRM con más de 5 años de experiencia creando módulos empresariales. Fundador de SalesCloud.