GraphQL y Ruby on Rails

  • por Juan Ignacio Hayashi

Introducción

GraphQL es una herramienta que permite hacer consultas de datos. Al contrario del protocolo ReST, las consultas se realizan sobre un único endpoint a través de un método POST. La principal ventaja que ofrece GraphQL, es la de definir los recursos y atributos que uno desea consultar, evitando un exceso de la información recibida. Una consulta de ejemplo podemos encontrarla a continuación:

query {
  users {
    id
    first_name
    last_name
    email
    posts {
      title
    }
  }
}

Mientras, la respuesta que llega desde el servidor es similar a la siguiente:

{
  "data": {
    "users": [
      {
        "id": 18,
        "first_name": "Jorge",
        "last_name": "Meza",
        "email": "jorge@test.com",
        "posts": [
			{
			  "title": "Proyecto en Elixir con base de datos Postgres"
			}
		]
      },
      {
        "id": 15,
        "first_name": "Matías",
        "last_name": "Castillo",
        "email": "mcast@test.com",
        "posts": [
			{
			  "title": "Introducción a React Native"
			}
		]
      },
    ]
  }
}

 

Al explicitar los datos que queremos recibir, evitamos la sobrecarga de datos innecesarios, como pudo haber sido en este caso la última vez que inició sesión, la fecha de creación de su cuenta, o la fecha de creación de los posts.

 

Instalación en Rails

Para la utilización de GraphQL en Rails, utilizaremos la versión de Rails 5.1.4 con Ruby 2.4.1, y crearemos un nuevo proyecto:

$ rails new graphql_project --database=postgresql

Entramos a la carpeta del proyecto, y agregamos la gema al Gemfile:

gem 'graphql'

y ejecutamos bundle install para instalar la gema requerida. Una vez finalizado, procedemos a instalar GraphQL ejecutando el comando:

$ rails generate graphql:install

Esto creará una nueva carpeta dentro de 'app'  llamada 'graphql', en donde se encontrarán los archivos dedicados al manejo de las consultas. Agregará también una dependencia que deberemos instalar ejecutando bundle install nuevamente, y también agregará la ruta en el archivo routes.rb hacia donde se deben hacer las consultas.

En el siguiente repositorio se encuentra un proyecto base con modelos para User y Post, junto con un seed básico para realizar unas consultas pequeñas: https://bitbucket.org/juanhayashi/graphql_project

Para el funcionamiento de GraphQL, se deben definir los datos que se pueden consultar, junto a los atributos que pueden solicitarse y el tipo de dato que son. Para empezar, debemos definir la consulta para solicitar todos los usuarios y posts. Modificamos el archivo 'app/graphql/types/query_type.rb' quedando de la siguiente forma:

Types::QueryType = GraphQL::ObjectType.define do
  name "Query"

  field :users, !types[Types::UserType] do
    resolve -> (obj, args, ctx) {
      User.all
    }
  end

  field :posts, !types[Types::PostType] do
    resolve -> (obj, args, ctx) {
      Post.all
    }
  end
end

Con esto indicamos que, cuando una query solicite el campo users, este retornará todos los usuarios, y cuando solicite el campo posts, retornará todos los posts existentes. Una vez realizado esto, debemos definir los campos disponibles para ambos modelos, creando en la carpeta 'app/graphql/types' los archivos 'post_type.rb' y 'user_type.rb' con el siguiente contenido:

# app/graphql/types/user_type.rb

Types::UserType = GraphQL::ObjectType.define do
  name 'User'

  field :id, !types.ID
  field :first_name, !types.String
  field :last_name, !types.String
  field :email, !types.String
  field :age, types.Int
  field :location, types.String
  
  field :posts, !types[Types::PostType]
end
# app/graphql/types/post_type.rb

Types::PostType = GraphQL::ObjectType.define do
  name 'Post'

  field :id, !types.ID
  field :title, !types.String
  field :content, types.String

end

Al crear estos archivos, indicamos que User puede entregar su id, first_name, last_name, email y posts como valores no-nulos, y age y location como valores posiblemente nulos; mientras que Post puede entregar su id y title como valores no-nulos, y content como valor posiblemente nulo.

Una vez definido los campos, procedemos a probar el funcionamiento de GraphQL. Para realizar las consultas en modo de prueba, hay que correr el servidor:

$ rails s

Y accedemos a localhost:3000/graphiql en donde encontraremos una interfaz gráfica que en el lado izquierdo presenta la consulta a realizar, y en el lado derecho la respuesta.

Realizamos nuestra consulta, preguntando los datos del usuario, y los posts que tiene:

query {
  users {
    id
    first_name
    last_name
    email
  	posts{
      id
      title
    }
  }
}

Y el servidor nos retorna los datos solicitados:

Como podemos ver, nos retorna únicamente los datos solicitados, teniendo la posibilidad de solicitar otra información, como la edad, o el contenido del post.

Con esto, damos por terminado el tutorial básico de GraphQL, dejando en el tintero diferentes aspectos: solicitar datos con ciertas condiciones; GraphQL Mutations y Autenticación, entre otros.

 

Links de Interés:

https://dev.to/martijnwalraven/why-i-believe-graphql-will-come-to-replace-rest

http://graphql-ruby.org/

https://stackoverflow.com/questions/40689858/are-there-any-disadvantages-to-graphql