Advertisement
  1. Code
  2. PHP

Cómo construir una API REST simple en PHP

Scroll to top
Read Time: 11 min

Spanish (Español) translation by Xiomara Reynoso (you can also view the original English article)

En este tutorial, les enseñaré cómo construir una simple API REST con PHP y MySQL

REST se ha convertido en el estándar de facto cuando se trata de exponer datos a través de API y servicios web. De hecho, la mayoría de las aplicaciones web hoy en día acceden y exponen datos a través de API REST. Con la popularidad de los marcos frontales que pueden consumir la API REST sin esfuerzo, siempre será un más para ti si tu aplicación web expone las API REST.

En este artículo, vamos a construir una simple aplicación de demostración, que te permite obtener una lista de usuarios de la base de datos MySQL a través de un punto final REST.

Prepara el esqueleto

En esta sección, repasaremos brevemente la estructura del proyecto.

Veamos la estructura siguiente.

1
├── Controller
2
│   └── Api
3
│       ├── BaseController.php
4
│       └── UserController.php
5
├── inc
6
│   ├── bootstrap.php
7
│   └── config.php
8
├── index.php
9
└── Model
10
    ├── Database.php
11
    └── UserModel.php

Intentemos entender la estructura del proyecto.

  • index.php: el punto de entrada de nuestra solicitud. Actuará como controlador frontal de nuestra aplicación.
  • inc/configura.php: tiene la información de configuración de nuestra aplicación. Sobre todo, tendrás las credenciales de la base de datos.
  • inc/bootstrap.php: usado para atrapar boots en nuestra aplicación incluyendo los archivos necesarios.
  • Modelo/base de datos.php: la capa de acceso a la base de datos que se utilizará para interactuar con la base de datos subyacente MySQL.
  • Modelo/Modelo usuario.php: el archivo del modelo de usuario que implementa los métodos necesarios para interactuar con la tabla de usuarios de la base de datos MySQL.
  • Controlador/Api/Control de bases.php: un archivo de control de base que contiene métodos de utilidad comunes.
  • Controlador/Api/Controlador de Use.php: el archivo controlador del usuario que contiene el código de aplicación necesario para entretener las llamadas de la API REST.

Así que esa es la configuración básica que vamos a implementar en el resto del artículo.

Crea una base de datos y clases modelo

En esta sección, crearemos una base de datos y la tabla de usuarios. También crearemos clases de modelos necesarias que se usarán para traer a los usuarios de una base de datos.

Crea una base de datos y la tabla de usuarios

Crea la base de datos rest_api_demo ejecutando la siguiente orden en su terminal MySQL. (Accede a esto con la orden mysql de la línea de comando.)

1
$CREATE DATABASE rest_api_demo;

También podrías usar una herramienta como phpMyAdmin si prefieres trabajar con tus bases de datos de esa manera.

Una vez creada la base de datos rest_api_demo, ve y crea la tabla de usuarios ejecutando las siguientes instrucciones.

1
$use rest_api_demo;
2
$CREATE TABLE `users` (
3
  `user_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
4
  `username` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
5
  `user_email` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
6
  `user_status` int(11) NOT NULL DEFAULT '0',
7
  PRIMARY KEY (`user_id`)
8
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Eso debería crear la tabla de usuarios en la base de datos rest_api_demo. También querrás poblar esta tabla con unos pocos registros falsos para fines de prueba. ¡Incluye algunos discos y ya estás listo!

Crea clases de modelo

En esta sección, crearemos las clases de modelo necesarias.

Crea la base de datos del Modelo.el archivo de php con el siguiente contenido.

1
<?php
2
class Database
3
{
4
    protected $connection = null;
5
6
    public function __construct()
7
    {
8
        try {
9
            $this->connection = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_DATABASE_NAME);
10
    	
11
            if ( mysqli_connect_errno()) {
12
                throw new Exception("Could not connect to database.");   
13
            }
14
        } catch (Exception $e) {
15
            throw new Exception($e->getMessage());   
16
        }			
17
    }
18
19
    public function select($query = "" , $params = [])
20
    {
21
        try {
22
            $stmt = $this->executeStatement( $query , $params );
23
            $result = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);				
24
            $stmt->close();
25
26
            return $result;
27
        } catch(Exception $e) {
28
            throw New Exception( $e->getMessage() );
29
        }
30
        return false;
31
    }
32
33
    private function executeStatement($query = "" , $params = [])
34
    {
35
        try {
36
            $stmt = $this->connection->prepare( $query );
37
38
            if($stmt === false) {
39
                throw New Exception("Unable to do prepared statement: " . $query);
40
            }
41
42
            if( $params ) {
43
                $stmt->bind_param($params[0], $params[1]);
44
            }
45
46
            $stmt->execute();
47
48
            return $stmt;
49
        } catch(Exception $e) {
50
            throw New Exception( $e->getMessage() );
51
        }	
52
    }
53
}

Esta es una clase de capa de acceso a la base de datos, que nos permite establecer una conexión a la base de datos MySQL. Además de la conexión establecida, contiene métodos genéricos como seleccionar y ejecutarDeclaración que nos permite seleccionar registros de una base de datos. No usaremos la clase de base de datos directamente, crearemos clases de modelos correspondientes que amplíen la clase de base de datos para acceder a la base de datos MySQL subyacente.

Después, vamos a crear el Modelo Model/UserModel.php con el siguiente contenido.

1
<?php
2
require_once PROJECT_ROOT_PATH . "/Model/Database.php";
3
4
class UserModel extends Database
5
{
6
    public function getUsers($limit)
7
    {
8
        return $this->select("SELECT * FROM users ORDER BY user_id ASC LIMIT ?", ["i", $limit]);
9
    }
10
}

Es importante notar que la clase UsuarioModelo amplía la clase de base de datos.

Además, contiene el método ObtenUsuarios, que nos permite seleccionar a los usuarios de la base de datos MySQL. Es obligatorio pasar el parámetro $límite, lo que se asegura de que no seleccionará todos los registros a la vez.

Por supuesto, podría definir más métodos en la clase UsuarioModelo según tus necesidades. Mantendremos las cosas simples en el contexto de este tutorial.

Así que ahora tenemos nuestras clases de base de datos y modelos establecidas. En la siguiente sección veremos cómo crear controles y los archivos que se emiten en nuestra aplicación demo.

Crea componentes de la capa de la aplicación

En esta sección, crearemos los archivos que quedan necesarios para que nuestra aplicación de demo funcione.

El directorio inc

Para empezar, crearemos los archivos de configuración necesarios.

Crea el archivo inc/config.php con el siguiente contenido.

1
<?php
2
define("DB_HOST", "localhost");
3
define("DB_USERNAME", "demo");
4
define("DB_PASSWORD", "demo");
5
define("DB_DATABASE_NAME", "rest_api_demo");

Asegúrate de actualizar todos los valores que estés usando en tu instalación.

Después, ve y crea el archivo inc/bootstrap.php con el siguiente contenido.

1
<?php
2
define("PROJECT_ROOT_PATH", __DIR__ . "/../");
3
4
// include main configuration file

5
require_once PROJECT_ROOT_PATH . "/inc/config.php";
6
7
// include the base controller file

8
require_once PROJECT_ROOT_PATH . "/Controller/Api/BaseController.php";
9
10
// include the use model file

11
require_once PROJECT_ROOT_PATH . "/Model/UserModel.php";
12
?>

Primero, hemos iniciado la constante PROJECT_ROOT_PATH con la raíz del directorio de nuestra aplicación. De esta manera, podríamos usar la constante PROJECT_ROOT_PATH para preparar caminos absolutos en nuestra aplicación. Después, incluimos el archivo config.php, que contiene la información de conexión de la base de datos. Finalmente, hemos incluido archivos de control y modelos.

Eso es para establecer los archivos comunes en nuestra aplicación.

El controlador del directorio

En esta sección, implantaremos controles que contengan la mayoría de nuestra lógica de la aplicación.

El archivo BaseController.php

Crea el archivo Controller/Api/BaseController.php con el siguiente contenido. La clase Base de control contiene los métodos de utilidad que son utilizados por otros controladores.

1
<?php
2
class BaseController
3
{
4
    /**

5
     * __call magic method.

6
     */
7
    public function __call($name, $arguments)
8
    {
9
        $this->sendOutput('', array('HTTP/1.1 404 Not Found'));
10
    }
11
12
    /**

13
     * Get URI elements.

14
     * 

15
     * @return array

16
     */
17
    protected function getUriSegments()
18
    {
19
        $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
20
        $uri = explode( '/', $uri );
21
22
        return $uri;
23
    }
24
25
    /**

26
     * Get querystring params.

27
     * 

28
     * @return array

29
     */
30
    protected function getQueryStringParams()
31
    {
32
        return parse_str($_SERVER['QUERY_STRING'], $query);
33
    }
34
35
    /**

36
     * Send API output.

37
     *

38
     * @param mixed  $data

39
     * @param string $httpHeader

40
     */
41
    protected function sendOutput($data, $httpHeaders=array())
42
    {
43
        header_remove('Set-Cookie');
44
45
        if (is_array($httpHeaders) && count($httpHeaders)) {
46
            foreach ($httpHeaders as $httpHeader) {
47
                header($httpHeader);
48
            }
49
        }
50
51
        echo $data;
52
        exit;
53
    }
54
}

Repasemos rápidamente todos los métodos de clase Base de Control.

El método __call es un método mágico, y así se llama cuando intentas llamar un método que no existe. Estamos aprovechando esta oportunidad para lanzar el error no encontrado de HTTP/1.1 404 cuando alguien intenta llamar un método que no hemos implementado. Si esto te suena confuso, no te preocupes, tendrá más sentido cuando probemos nuestra aplicación en la siguiente sección.

Luego está el método getUriSegments, que devuelve un conjunto de segmentos de URI. Es útil cuando intentamos validar el final REST llamado por el usuario. Después de eso, está el método getQueryStringParams, que devuelve un conjunto de variables de la línea de requeté que se pasan junto con la petición entrante.

Finalmente, está el método sendOutput, que se usa para enviar la respuesta API. Usaremos este método cuando queramos enviar la respuesta API al usuario.

El archivo UserController.php

Después, crea el archivo Controller/Api/UserController.php con el siguiente contenido.

1
<?php
2
class UserController extends BaseController
3
{
4
    /**

5
     * "/user/list" Endpoint - Get list of users

6
     */
7
    public function listAction()
8
    {
9
        $strErrorDesc = '';
10
        $requestMethod = $_SERVER["REQUEST_METHOD"];
11
        $arrQueryStringParams = $this->getQueryStringParams();
12
13
        if (strtoupper($requestMethod) == 'GET') {
14
            try {
15
                $userModel = new UserModel();
16
17
                $intLimit = 10;
18
                if (isset($arrQueryStringParams['limit']) && $arrQueryStringParams['limit']) {
19
                    $intLimit = $arrQueryStringParams['limit'];
20
                }
21
22
                $arrUsers = $userModel->getUsers($intLimit);
23
                $responseData = json_encode($arrUsers);
24
            } catch (Error $e) {
25
                $strErrorDesc = $e->getMessage().'Something went wrong! Please contact support.';
26
                $strErrorHeader = 'HTTP/1.1 500 Internal Server Error';
27
            }
28
        } else {
29
            $strErrorDesc = 'Method not supported';
30
            $strErrorHeader = 'HTTP/1.1 422 Unprocessable Entity';
31
        }
32
33
        // send output

34
        if (!$strErrorDesc) {
35
            $this->sendOutput(
36
                $responseData,
37
                array('Content-Type: application/json', 'HTTP/1.1 200 OK')
38
            );
39
        } else {
40
            $this->sendOutput(json_encode(array('error' => $strErrorDesc)), 
41
                array('Content-Type: application/json', $strErrorHeader)
42
            );
43
        }
44
    }
45
}

Es importante notar que la clase UserController amplía la clase BaseController. Idealmente, esta clase contendría los métodos de acción que están asociados con los puntos finales de REST que están definidos para la entidad usuaria. En nuestro caso, por ejemplo, el punto final /user/list REST corresponde al método listAction. De esta manera, también se pueden definir otros métodos para otros puntos finales de REST.

El método listAction se utiliza para obtener una lista de usuarios de la base de datos MySQL. Contiene toda la lógica del final de /user/list REST.

En el método listAction, hemos iniciado un par de variables como $requestMethod y $arrQueryStringParams en primer lugar. Después, comprobamos que si el usuario ha llamado al punto usuario/lista con el método OBTÉN, de lo contrario no procesaremos más. Finalmente, creamos el objeto UserModel y llamamos al método getUsers para obtener una lista de usuarios de una base de datos. También hemos usado la función json_encode para convertir un orden en un objeto JSON antes de que lo envíen al usuario.

Por último, hemos usado el método sendOutput para enviar la respuesta JSON al usuario. Es importante notar que el valor del entero del tipo de contenido de respuesta está fijado en application/json, ya que estamos enviando la respuesta JSON.

De manera similar, se podrían definir otros métodos también para otros puntos finales.

El archivo index.php

El archivo index.php es el punto de entrada de nuestra aplicación. Veamos cómo se ve.

1
<?php
2
require __DIR__ . "/inc/bootstrap.php";
3
4
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
5
$uri = explode( '/', $uri );
6
7
if ((isset($uri[2]) && $uri[2] != 'user') || !isset($uri[3])) {
8
    header("HTTP/1.1 404 Not Found");
9
    exit();
10
}
11
12
require PROJECT_ROOT_PATH . "/Controller/Api/UserController.php";
13
14
$objFeedController = new UserController();
15
$strMethodName = $uri[3] . 'Action';
16
$objFeedController->{$strMethodName}();
17
?>

Primero, hemos usado funciones parse_url y explotar para iniciar segmentos de URI en la variable de orden $uri. Después, validamos los segmentos de URI. Finalmente, hemos iniciado el controlador de usuario y llamado al método de acción correspondiente.

Con eso hemos creado todos los archivos necesarios en nuestra aplicación demo REST. En la siguiente sección veremos cómo llamarlo desde la perspectiva del usuario final.

Cómo llamar a nuestra API REST

En esta sección veremos cómo llamar a nuestra aplicación de demostración. En nuestra aplicación, hemos construido un punto final REST para obtener una lista de usuarios.

Veamos cómo se ve el URL de nuestro punto final:

1
// https://localhost/index.php/{MODULE_NAME}/{METHOD_NAME}?limit={LIMIT_VALUE}

2
https://localhost/index.php/user/list?limit=20

Si pudieran recordar el archivo index.php, comprobamos que si la variable $uri[2] está fijada en usuario. Además, el valor de la variable $uri[3] funcionaría como nombre del método. En el caso anterior, la variable $uri[3] está fijada en lista. Así, terminaría llamando el método listAction de la clase UserController.

La salida debería verse así:

1
[
2
   {
3
      "user_id":1,
4
      "username":"Bob",
5
      "user_email":"bob@gmail.com",
6
      "user_status":0
7
   },
8
   {
9
      "user_id":2,
10
      "username":"John",
11
      "user_email":"john@gmail.com",
12
      "user_status":1
13
   },
14
   {
15
      "user_id":3,
16
      "username":"Mark",
17
      "user_email":"mark@gmail.com",
18
      "user_status":1
19
   },
20
   {
21
      "user_id":4,
22
      "username":"Ville",
23
      "user_email":"ville@gmail.com",
24
      "user_status":0
25
   }
26
]

Como pueden ver, regresa una lista de usuarios como un objeto de JSON. Además, si hay algún error de aplicación, sería devuelto como un objeto de JSON también para fines de devanamiento.

Conclusión

Hoy discutimos cómo construir una aplicación de REST con PHP y MySQL. Para fines de demostración, creamos una aplicación de demostración que permite obtener una lista de usuarios de la base de datos MySQL a través de la API REST.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.