6

Un abreboca a GraphQL en Laravel

TL;DR: Un abrebocas de como funciona GraphQL y una implementación muy sencilla en Laravel.

Motivado en la espera del Curso de GraphQL de Platzi, les presento un pequeño abrebocas de Laravel + GraphQL.

¿Que es GraphQL?

Tomando como base la sencilla explicación que nos da Platzi en la presentación de su curso, GraphQL es una herramienta con la cual podemos realizar consultas a nuestra API de una manera mas simple, organizada y óptima, es importante destacar que GraphQL es la solución que nos presenta Facebook para la comunicación entre el front-end y el back-end, debido a que el “patrón” mas popular usado actualmente (y ya anticuado) es REST, que es la forma como la hemos visto en Laravel mediante las rutas de recursos, así como otros frameworks como Ruby on Rails, Django, entre otros.

GraphQL es soportado en muchos lenguajes de programación por lo cual si Php no es tu lenguaje favorito (el mió tampoco) lo mas seguro es que GraphQL esté disponible mediante alguna librería en ese lenguaje que te apasiona, vamos a ver un ejemplo muy muy sencillo de como GraphQL mejora la comunicación entre el front-end y el back-end comparado con REST, esto no pretende ser un tutorial completo ya que GraphQL es un tema muy extenso para explicarlo en un solo tutorial, por ello el curso de Platzi será un punto de partida excelente para dominarlo.

Tomaremos como ejemplo una simple tabla con los datos de estudiantes, en donde tendremos los campos: usuario, nombre, apellido y país

<?php// create_estudiantes_table.php
Schema::create('estudiantes', function(Blueprint $table){
    $table->increments('id');
    $table->string('usuario');
    $table->string('nombre');
    $table->string('apellido');
    $table->string('pais');
    $table->timestamps();
});

Ahora supongamos que quiero llamar a la API y obtener todos los estudiantes, la ruta que usuarios seria /estudiantes y la respuesta seria

{
  "data": [
    {
      "id": 1,
      "usuario": "pedronalbert",
      "nombre": "alberto",
      "apellido": "pedron",
      "pais": "Venezuela"
    },
    {
      "id": 2,
      "usuario": "danimed",
      "nombre": "daniel",
      "apellido": "medina",
      "pais": "Colombia"
    },
  ]
}

Todo muy bien por ahora ya que si necesitamos obtener los datos del usuario con id: 1 usuarios nuestra ruta /estudiantes/1 para obtener la respuesta

{
  "data": {
    "id": 1,
    "usuario": "pedronalbert",
    "nombre": "alberto",
    "apellido": "pedron",
    "pais": "Venezuela"
  },
}

Pero que sucede si quiero filtrar los campos que se mostrarán en la respuesta, terminaría con una solución de mandar parámetros GET a nuestra ruta algo como /estudiantes/2?campos=nombre,apellido algo que no se ve para nada bien y si tenemos muchos campos terminaremos con rutas desastrosas.

{
  "data": {
    "nombre": "Alberto",
    "apellido": "Pedron",
  },
}

Pero aquí es donde viene GraphQL a cambiar las reglas.

GraphQL al rescate

Lo primero importante a resaltar en GraphQL es que solo utilizaremos una ruta que será /graphql y le enviaremos los datos port POST y te preguntarás como podemos lograr una API completa con tal solo una ruta, la respuesta es sencilla, y si le enviamos JSONs a la API con la información que queremos?.. pues esa es la solución que propone GraphQL, aunque cabe destacar que no son JSONs son muy muy similares y usaremos librerías como Relay para construirlos.

Implementando GraphQL en Laravel

El primer paso para implementar GraphQL es colocarlo en nuestras dependencias e instalarlo, la dependencia que usaremos sera la siguiente laravel-graphql, luego de haberlo instalado necesitamos crear nuestros tipos de datos que para que entiendas facilmente es el equivalente a un recurso en REST en nuestro ejemplo el unico recurso que usaremos será Estudiante.

Creando nuestro tipos de datos

En repositorio Git puedes encontrar explicaciones muy claras de como se crean los tipos de datos y las consultas que veremos mas adelante, pasemos a crear nuestros datos

<?php// App/GraphQL/Type/EstudianteType.phpnamespaceApp\GraphQL\Type;

useGraphQL\Type\Definition\Type;
useFolklore\GraphQL\Support\TypeasGraphQLType;

classEstudianteTypeextendsGraphQLType{

  // Le damos el nombre a nuestro recursoprotected $attributes = [
		'name' => 'Estudiante',
	];

  // Especificamos los campospublicfunctionfields(){
		return [
			'id' => [
				'type' => Type::nonNull(Type::string()),
		     ],
            'usuario' => [
      	      'type' => Type::string(),
            ],
            'nombre' => [
      	      'type' => Type::string(),
            ],
            'apellido' => [
      	      'type' => Type::string(),
            ],
            'pais' => [
      	      'type' => Type::string(),
            ],
	  	];
	}
}

Ok ya tenemos nuestro tipo de dato, que podemos ver como las “clases” que usara GraphQL para manejar las consultas, ahora pasemos a crear nuestras consultas

Creando la consulta

Debido a que solo tenemos un recurso solo necesitaremos una consulta ya en nuestras APIs con relaciones y mas complejidad necesitaremos mas consultas, las “consultas” son toda la logica necesaria que usará nuestro backend para adaptarse a las peticiones que hagan y como responderá a cada una de ellas.

<?phpnamespaceApp\GraphQL\Query;

useGraphQL;
useGraphQL\Type\Definition\Type;
useFolklore\GraphQL\Support\Query;
useApp\Estudiante;

classEstudiantesextendsQuery{

  // Le damos un nombre a la listaprotected $attributes = [
		'name' => 'estudiantes'
	];

   /* 
    * Especificamos que las consultas a este recurso devolveran un array con listOf
    * ademá diciendole que sera nuestro tipo de dato Estudiante
    */publicfunctiontype(){
		return Type::listOf(GraphQL::type('Estudiante'));
	}

   // Espeficiamos los campos y su tipopublicfunctionargs(){
		return [
			'id' => ['name' => 'id', 'type' => Type::string()],
            'usuario' => ['name' => 'usuario', 'type' => Type::string()],
			'nombre' => ['name' => 'nombre', 'type' => Type::string()],
			'apellido' => ['name' => 'apellido', 'type' => Type::string()],
			'pais' => ['name' => 'pais', 'type' => Type::string()],,
		];
	}

    // Especificamos la logica necesaria para obtener los datos del modelopublicfunctionresolve($root, $args){
    // Si recibimos el parametro "id" buscaremos en base a ese idif(isset($args['id']))
		{
			return Estudiante::where('id' , $args['id'])->get();
		}
		else// De lo contrario devolveremos la lista completa
		{
			return Estudiante::all();
		}
	}

}

Interactuando con nuestro Grap

Ahora que ya tenemos montado nuestro Graph es hora de hacer peticiones, en nuestro front-end usaremos librerías como Rilay, pero para nuestras pruebas podemos usar un IDE llamado Graphi en el cual podemos interactuar de forma sencilla con nuestro Graph mediante un editor en el navegador, la primera consulta que haremos será de todos los estudiantes esto lo logramos con la siguiente estructura.

{
  estudiantes {
    id
    usuario
    nombre
    apellido
    pais
  }
}

El resultado a nuestra consulta será

{
  "data": [
    {
      "id": "1",
      "usuario": "pedronalbert",
      "nombre": "alberto",
      "apellido": "pedron",
      "pais": "Venezuela"
    },
    {
      "id": "2",
      "usuario": "danimed",
      "nombre": "daniel",
      "apellido": "medina",
      "pais": "Colombia"
    },
  ]
}

En donde estamos enviando algo muy similar a un JSONs el cual mediante nuestra consulta hemos realizado un Estudiante::all(), debido a que no hemos enviado ningun argumento a la consulta, te invito a revisar nuevamente el codigo de nuestra consulta.

Filtrando resultados y campos

Pasemos a filtrar resultados, esto lo lograremos cambiando la estructura del “JSON” que estamos enviando a nuestro API, cabe recalcar que dicho “JSON” se envia a nuestra única ruta /graphql esta vez enviaremos solo dos campos que son nombre y apellido

{
  estudiantes(id: "2") {
    nombre
    apellido
  }
}

El resultado a nuestra consulta será

{
  "data": [
    {
      "id": 2,
      "nombre": "daniel",
      "apellido": "medina",
    },
  ]
}

Ya hemos filtrado los resultados!, ya que enviando (id: “2”) llegará a nuestra consulta como $args[“id”] y hemos hecho un Estudiante::where(‘id’ , $args[‘id’])->get() con lo cual solo nos devolvió el estudiante con dicho id, pero esto no termina aquí, GraphQL puede manejar relaciones y muchas cosas mas las cuales te invito a que las indagues en su página oficial de Graphql y quedando a la espera del curso de GraphQL de Platzi en donde se tocarán cada una de las funcionalidades que tiene GraphQL, como curiosidad te dejo como luciría una consulta con relaciones.

{
  estudiantes(id: "2") {
    nombre
    apellido
    certificados {
      titulo
      lenguaje
    }
  }
}

El resultado a nuestra consulta será

{
  "data": [
    {
      "id": 2,
      "nombre": "daniel",
      "apellido": "medina",
      "certificados": [
        {
          "titulo": "Curso definitivo de Javascript",
          "lenguaje": "js",
        },
        {
          "titulo": "Curso de Vue.js",
          "lenguaje": "js",
        },
      ]
    },
  ]
}
Escribe tu comentario
+ 2
1
7Puntos

El paquete de GraphQL referido ya no encuentra vigente, deberían actualizar el tutorial