Cómo crear una API REST con Symfony 7 – Parte 1

Enlace al repositorio: https://github.com/polvilarrasa/tutoriales-web-basic-api-rest-example

Introducción

En este artículo, exploraremos cómo crear una API REST utilizando Symfony 7, un popular framework de desarrollo web en PHP. En la actualidad, las API REST se han convertido en una parte fundamental del desarrollo de aplicaciones web. Estas APIs permiten la comunicación entre diferentes sistemas de forma eficiente y segura.

¿Qué es una API REST?

Antes de sumergirnos en los detalles de cómo crear una API REST con Symfony 7, es importante entender qué es una API REST. Una API REST, o Interfaz de Programación de Aplicaciones Representacional por sus siglas en inglés, es un conjunto de reglas y convenciones que permiten la comunicación entre sistemas utilizando el protocolo HTTP. A través de una API REST, se pueden enviar solicitudes a un servidor y obtener respuestas en un formato estructurado, como JSON o XML.

Las APIs REST son ampliamente utilizadas en el desarrollo de aplicaciones web y móviles, ya que proporcionan una arquitectura flexible y escalable. Al diseñar una API REST, es fundamental considerar aspectos como la identificación de los recursos y endpoints, los métodos HTTP que se utilizarán y la autenticación y autorización de los usuarios.

Ventajas de utilizar Symfony para crear una API REST

Existen numerosos frameworks de desarrollo web disponibles que facilitan la creación de APIs REST. Sin embargo, Symfony se destaca por varias razones. En primer lugar, Symfony es un framework de código abierto respaldado por una gran comunidad de desarrolladores. Esto significa que hay una amplia cantidad de documentación, tutoriales y recursos disponibles para ayudar en el proceso de desarrollo.

Además, Symfony ofrece una gran cantidad de componentes y herramientas que facilitan la creación de APIs REST eficientes y seguras. Por ejemplo, Symfony proporciona un potente ORM llamado Doctrine, que simplifica la gestión de datos en la base de datos. Symfony también cuenta con un sistema de autenticación y autorización flexible y robusto, lo que permite proteger los recursos y acciones de la API.

Introducción a Symfony y su versión 7

Symfony es un framework de desarrollo web para PHP que se utiliza ampliamente en la industria. Symfony se caracteriza por seguir las mejores prácticas de desarrollo, como el uso de patrones de diseño y la modularidad. La versión 7 es la versión más nueva al momento de escribir este artículo.

Symfony 7 ofrece numerosas mejoras y características nuevas que hacen que el desarrollo de una API REST sea aún más eficiente y productivo. Al utilizar Symfony 7, se pueden aprovechar todas estas mejoras y mantenerse al día con las últimas tendencias en el desarrollo web.

Paso 1: Configuración de Symfony

Antes de comenzar a desarrollar una API REST con Symfony 7, es importante realizar la configuración inicial del proyecto. A continuación, se describen los requisitos previos para instalar Symfony 7 y cómo crear un nuevo proyecto Symfony.

Requisitos previos para instalar Symfony 7

Para instalar Symfony 7, es necesario tener instalado PHP en el sistema. Symfony 7 es compatible con PHP 8.2 o versiones superiores. Además, es necesario tener instalado el administrador de paquetes de Composer. En nuestro caso también vamos a instalar el binario de Symfony el cual nos va a ayudar mucho en el desarrollo local.

https://symfony.com/download
https://getcomposer.org/download/
https://www.php.net/downloads.php

Creación de un nuevo proyecto Symfony

Una vez cumplidos los requisitos previos, se puede proceder a crear un nuevo proyecto Symfony. Hay múltiples formas de crear un proyecto, ya sea a partir de composer o a partir del binario de Symfony.

symfony new basic-api-rest-example --version="7.0.*"
Bash
cd basic-api-rest-example
Bash
symfony server:start
Bash

Ahora hemos arrancado el servidor local que nos ofrece el binario de Symfony junto a nuestra instalación local de PHP. En la consola veremos el siguiente mensaje:

[OK] Web server listening http://127.0.0.1:8000 
api rest con symfony
Proyecto Symfony 7 en entorno local

Ya tenemos un proyecto Symfony creado y arrancado en nuestra máquina local.

Paso 2: Diseñando la arquitectura de la API

Una vez realizada la configuración inicial del proyecto, es hora de diseñar la arquitectura de la API REST. En esta sección, se explorarán los conceptos clave en el diseño de una API REST, como la identificación de recursos y endpoints, y la definición de los métodos HTTP y sus acciones correspondientes.

Conceptos clave en el diseño de una API REST

Al diseñar una API REST, es fundamental identificar los recursos que se estarán exponiendo a través de la API. Los recursos representan los objetos o entidades que se manipularán a través de las solicitudes HTTP. Por ejemplo, si estamos creando una API para una tienda en línea, algunos de los recursos podrían ser productos, clientes y pedidos.

Además de identificar los recursos, es importante definir los endpoints de la API. Un endpoint es una URL específica a través de la cual se puede acceder a un recurso. Por ejemplo, si queremos obtener información sobre un producto en particular, podríamos utilizar el siguiente endpoint: /api/productos/{id}.

Identificación de recursos y endpoints

Para identificar los recursos y endpoints de la API, es útil realizar un análisis exhaustivo de los requisitos del proyecto. Identifique los objetos y entidades clave que se manipularán a través de la API y defina las URL que se utilizarán para acceder a cada recurso.

Definición de los métodos HTTP y sus acciones correspondientes

Una parte fundamental del diseño de una API REST es definir los métodos HTTP que se utilizarán y sus acciones correspondientes. Algunos de los métodos HTTP más comunes son GET, POST, PUT y DELETE.

  • El método GET se utiliza para obtener información de un recurso.
  • El método POST se utiliza para crear un nuevo recurso.
  • El método PUT se utiliza para actualizar un recurso existente.
  • El método DELETE se utiliza para eliminar un recurso.

Es importante definir claramente las acciones correspondientes a cada método HTTP y cómo deberían interactuar con los recursos de la API. Para trabajar nuestra api vamos a implementar las siguientes operaciones:

Paso 3: Implementando los controladores y rutas

Una vez diseñada la arquitectura de la API, es hora de implementar los controladores y las rutas en Symfony. Los controladores son responsables de procesar las solicitudes HTTP y devolver las respuestas adecuadas, mientras que las rutas enlazan las URL a los controladores correspondientes.

Creación de controladores para los recursos de la API

En Symfony, los controladores se crean como clases PHP. Cada método dentro del controlador representa una acción específica que se puede realizar en un recurso. Por ejemplo, un controlador para el recurso «products» podría tener métodos como getProduct, createProduct, updateProduct y deleteProduct.

Configuración de las rutas en Symfony

Hay muchas formas para configurar las rutas en Symfony. A partir de ficheros .yaml, ficheros .xml o el formato que vamos a utilizar que van a ser los atributos de PHP que aparecieron en la versión 8 de PHP.

Para facilitar el desarrollo vamos a instalar un paquete de Symfony que sólo se utiliza en tiempo de desarrollo llamado MakerBundle el cúal está desarrollado por Symfony.

composer require --dev symfony/maker-bundle
Bash

No vamos a entrar en profundidad cómo utilizar el paquete, pero si utilizamos el comando list make podemos ver todo lo que nos permite o ayuda a crear este paquete.

php bin/console list make
Bash
Resultado de ejecutar el comando list make

En nuestro caso vamos a empezar creando un controlador con el make:controller y cómo parámetro al comando le vamos a indicar el nombre del controlador ProductsController.

php bin/console make:controller ProductsController
Bash
Imagen del controlador ProductsController creado con el comando make:controller

Para configurar la ruta, utilizamos el atributo Route dónde el primer parámetro es la ruta a la que debemos navegar para que este controlador reciba la petición y el segundo parámetro es cómo se llama esta ruta para que podamos identificarla en otras partes del código. Este segundo parámetro es muy útil cuando estamos realizando aplicaciones full-stack con Symfony.

Para ver rápidamente cómo funciona, abrimos nuestro navegador y nos dirigimos a http://127.0.0.1:8000/products

Url 127.0.0.1:8000/products

Paso 4: Creando los endpoints de la API REST con Symfony

Ahora vamos a expandir el controlador para crear las 5 rutas que definimos en el paso 2. Cómo de momento nuestra aplicación no tiene base de datos vamos a trabajar con datos ficticios creados en memoria en nuestros controladores. Más adelante veremos cómo añadir una base de datos y hacer las consultas necesarias.

Primero de todo vamos a añadir el atributo Route encima de nuestra classe ProductsController

Prefijo /api para todas las rutas del controlador

Definiendo este atributo vamos a forzar a que todas las rutas que definamos en nuestras funciones del controlador lleven el prefijo /api delante.

Obtener todos los productos

PHP
    #[Route('/products', name: 'app_get_products', methods: ['GET'])]
    public function getProducts(): JsonResponse
    {
        // get the products from the database
        $products = [
            ['id' => 1, 'name' => 'Product 1'],
            ['id' => 2, 'name' => 'Product 2'],
            ['id' => 3, 'name' => 'Product 3'],
        ];
        // return a 200 response
        return $this->json(['products' => $products], Response::HTTP_OK);
    }

Nuestra ruta /api/products va a devolver una respuesta con el status 200 indicando que tódo ha ido bién y va a devolver un array de productos en formato JSON. Indicamos que sólo aceptamos peticiones 'GET'.

Crear un producto

PHP
    #[Route('/products', name: 'app_create_product', methods: ['POST'])]
    public function createProduct(Request $request): JsonResponse
    {
        $data = json_decode($request->getContent(), true);

        // save data to the database

        // return a 201 response
        return $this->json(['product' => $data], Response::HTTP_CREATED);
    }

En nuestra función para crear productos, le indicamos que sólo vamos a aceptar peticiones de tipo 'POST'. Podemos ver cómo obtener datos que recibimos des del cuerpo de la petición. Los guardamos y después devolvemos una respuesta status 201 indicando que se ha creado el recurso.

Obtener un producto por ID

PHP
    #[Route('/products/{id}', name: 'app_get_product_by_id', methods: ['GET'])]
    public function getProductById(int $id): JsonResponse
    {
        // get the product from the database
        $product = ['id' => $id, 'name' => 'Product 1'];
        // return a 200 response
        return $this->json(['product' => $product], Response::HTTP_OK);
    }

En el caso de obtener un producto por ID, podemos ver cómo hemos añadido un parámetro variable en nuestra url {id}. Este parámetro le indica a Symfony que vamos a recibir una variable a la que llamamos $id y que la vamos a utilizar para obtener el producto de la base de datos y devolverlo con un status 200.

Actualizar un producto por ID

PHP
    #[Route('/products/{id}', name: 'app_update_product_by_id', methods: ['PUT'])]
    public function updateProduct(int $id, Request $request): JsonResponse
    {
        $data = json_decode($request->getContent(), true);

        // update data in the database

        // return a 200 response
        return $this->json(['product' => $data], Response::HTTP_OK);
    }

En el caso de actualizar un producto, sólo vamos a recibir peticiones 'PUT' también recibimos el parámetro $id a partir de la ruta y también podemos volver a ver cómo obtener los datos que nos llegan en el cuerpo de la petición.

Eliminar un producto por ID

PHP
    #[Route('/products/{id}', name: 'app_delete_product_by_id', methods: ['DELETE'])]
    public function deleteProduct(int $id): JsonResponse
    {
        // delete data from the database

        // return a 204 response
        return $this->json([], Response::HTTP_NO_CONTENT);
    }

En el caso de eliminar un producto por ID, indicamos que el tipo de petición va a ser 'DELETE' y vamos a devolver un array vacío y una respuesta de status 204 indicando que todo ha ido bién y que no hay contenido para devolver.

Paso 5: Testeando la API

Para testear la api existen múltiples herramientas. En nuestro caso vamos a utilizar Postman. Postman es una plataforma que nos permite construir y utilizar APIs, tiene tanto una versión web cómo una versión instalable. En nuestro caso lo vamos a instalar ya que queremos probar una API que tenemos en local.

https://www.postman.com/downloads

Para hacer pruebas de nuestra API, vamos a crear una colección nueva de Postman. Si sólo estás siguiendo este tutorial, te proporciono mi colección para que puedas seguir las pruebas.

https://documenter.getpostman.com/view/35023744/2sA3JT4K9b

Colección Postman

En esta colección puedes encontrar todas las llamadas a los endpoints que hemos definido en nuestro proyecto y se pueden ir ejecutando.

Peticiones GET en Postman

Llamada GET a http://127.0.0.1:8000/api/products des de Postman

Aqui podemos ver el resultado de la llamada a obtener todos los productos. Vemos que la respuesta es un JSON de productos y que el status es un 200 tal y cómo hemos definido en nuestro controlador.

Peticiones POST en Postman

Llamada POST a http://127.0.0.1:8000/api/products des de Postman

En el caso de una petición POST, le tenemos que indicar que queremos mandar un cuerpo con la petición y el cuerpo va a ser en formato JSON. En este ejemplo sólo le pasamos un id y un name. Podemos ver también la respuesta con un status 201 y devolvemos los mismos datos que hemos recibido.

Peticiones PUT en Postman

Llamada PUT a http://127.0.0.1:8000/api/products/5 des de Postman

En este ejemplo podemos ver 2 temas, primero de todo cómo le pasamos un cuerpo en formato JSON a la petición, y en segundo cómo le pasamos parámetros a la URL.

Peticiones DELETE en Postman

Llamada DELETE a http://127.0.0.1:8000/api/products/5 des de Postman

Podemos ver que en la petición eliminar productos, no recibimos ningún tipo de respuesta y un status 204.

Resumen

En este artículo, hemos explorado paso a paso cómo crear una API REST utilizando Symfony 7. Desde la configuración inicial del proyecto, la implementación de controladores y rutas hasta el testing con una herramienta cómo Postman.

Scroll al inicio