Guías de Make it Real
  • Introduction
  • Preparación
    • Conceptos básicos
    • El editor de texto
    • La línea de comandos
    • Git y Github
  • Git
    • Instalación y configuración
    • Conceptos y comandos esenciales
    • Ignorando archivos y carpetas
    • Trabajando con ramas
    • Repositorios remotos
    • Etiquetas
    • Reescribiendo la historia
    • Stashing
    • Github
  • HTML y CSS
    • Introducción a HTML
    • Introducción a CSS
    • Más elementos de HTML
    • Tablas
    • Formularios
    • El modelo de caja en CSS
    • Fondos (backgrounds)
    • Posicionamiento
    • Selectores CSS
    • Bordes, sombras y gradientes
    • Media Queries
    • Unidades en CSS
    • Flexbox
  • Bootstrap 3
    • Primeros pasos
    • Elementos básicos de HTML
    • Componentes
    • La grilla
    • Personalizando Bootstrap
    • Utilizando plantillas
  • Bootstrap 4
    • Primeros pasos
    • Elementos básicos de HTML
    • Componentes
    • La grilla
    • Clases utilitarias
    • Personalizando Bootstrap
  • Ruby
    • Primeros pasos
    • Tipos y operadores
    • Variables y entrada de usuario
    • Condicionales
    • Ciclos
    • Arreglos
    • Más cadenas de texto
    • Hashes
    • Métodos
    • Manipulación de archivos
    • Gemas
  • Programación Orientada a Objetos en Ruby
    • Clases y objetos
    • Métodos y atributos de clase
    • Herencia
    • Módulos
    • Excepciones
  • JavaScript I
    • Primeros pasos
    • Tipos y operadores
    • Variables
    • Condicionales
    • Ciclos
    • Arreglos
    • Más cadenas de texto
    • Funciones
    • Objetos literales
    • Manipulación de archivos
  • JavaScript en el navegador
    • Primeros pasos
    • Manipulando HTML
    • Escuchando eventos
    • Local Storage
    • History API
    • Canvas
    • Notificaciones Web
    • Audio y Video
    • Arrastrar y soltar
    • JSON
    • Realizando peticiones HTTP
  • jQuery
    • Primeros pasos
    • Manipulando HTML
    • Escuchando eventos
    • Plugins
    • Realizando peticiones con AJAX
  • JavaScript II
    • Prototipos
    • Librerías (Node.js)
    • ES6
    • Uso de this (call, apply, bind)
    • Programación funcional
    • Scope, hoisting, closures
    • Programación asincrónica
    • Testing
  • HTTP y Sinatra
    • Primeros pasos con Sinatra
    • El protocolo HTTP
    • Rutas
    • Formularios
    • Cookies y sesión
  • Bases de datos
    • Bases de datos relacionales
    • SQL
    • DDL
    • MongoDB
  • Ruby on Rails I
    • Primeros pasos
    • Arquitectura
    • Rutas
    • Layouts y rendering
    • ActiveRecord - Modelos
    • ActiveRecord - Migraciones
    • ActiveRecord - Validaciones
    • ActiveRecord - Asociaciones
    • ActiveRecord - Scopes
    • ActiveRecord - Callbacks
    • Recursos REST
    • Formularios
    • Autenticación con Devise
    • Sass y Bootstrap
    • Envío de correos
    • Carga de imágenes
    • Seeds
    • Heroku
  • Ruby on Rails II
    • Usando JavaScript (y jQuery) en Rails
    • Testing en Ruby
    • Testing en Rails
    • Creando una Web API
    • Web Sockets
  • Express.js
    • Primeros Pasos
    • El protocolo HTTP
    • Rutas
    • Vistas
    • Middlewares y manejo de errores
    • Formularios
    • Cookies y sesión
  • Express.js II
    • Mongoose
    • Web Sockets
    • Autenticación
    • Envío de correos
    • Cargar imágenes
    • Deployment
    • Testing
    • Creando una Web API
  • React
    • Primeros pasos
    • JSX
    • Componentes
    • Más sobre estado
    • Formularios
    • Peticiones HTTP con Axios
    • React Hooks
    • React Context
    • React Bootstrap
    • React Router
    • Carga de Imágenes
    • Testing
    • Estructura de carpetas
    • Componentes de clase
  • Redux
    • Primeros pasos
    • Action creators
    • Usando la librería react-redux
    • Middlewares
    • Operaciones asincrónicas con redux-thunk
    • Combinando funciones reductoras
    • Testing
    • Redux Tool Kit
  • Algoritmos
    • Describiendo un algoritmo
    • Complejidad (Big-O)
    • Estructuras de datos
    • Recursión
    • Ordenamiento
    • Búsqueda
    • Programación dinámica
  • Python
    • Primeros Pasos
    • Tipos y Variables
    • Funciones
    • Control de Flujo
    • Listas
    • Ciclos
    • Diccionarios, Tuplas y Sets
  • NumPy
    • Primeros Pasos
    • Arreglos
    • Arreglos Multidimensionales
    • Estadística con NumPy
    • Distribución Estadística
  • Pandas
    • Primeros Pasos
    • Inspección y Selección de Datos
    • Modificando Dataframes
    • La Función Lambda
    • Aggregates en Pandas
    • Múltiples Tablas
Powered by GitBook
On this page
  • Nuestro primer endpoint
  • Probando nuestro primer endpoint
  • Curl
  • Postman
  • HTTParty
  • Con el navegador
  • Completando el API
  • Autenticación
  • Integración con Devise
  1. Ruby on Rails II

Creando una Web API

PreviousTesting en RailsNextWeb Sockets

Last updated 2 years ago

A través de un Web API puedes permitir a otras aplicaciones interactuar con tu aplicación.

API, por las siglas en Inglés Application Programming Interface es, en general, una forma en que un software interactúa con otro software, no necesariamente a través de HTTP. Por ejemplo, a través del puedes realizar todo tipo de cosas interesantes en el navegador.

Un Web API es un tipo de API que utiliza el protocolo HTTP como forma de comunicación.

Todo lo que has visto hasta ahora te sirve para crear tus propias Web API's, la única diferencia es que en vez de recibir información de formularios y renderizar HTML, ahora nuestros controladores van a recibir y retornar JSON.

Nuestro primer endpoint

A las URL's que van exponer funcionalidad de nuestra aplicación se les llama endpoints.

Por ejemplo, el siguiente controlador permite listar los artículos:

class ArticlesController < ApplicationController
  def index
    articles = Articles.all
    render json: articles
  end
end

La línea más importante de este código es render json: articles que retorna los artículos en formato JSON en vez de renderizar una vista normal.

Nuestro archivo config/routes.rb tendría configurada la ruta de la siguiente forma:

Rails.application.routes.draw do
  resources :tasks, only: [:index]
end

Fíjate que esto es igual a lo que ya habías visto antes. La única diferencia es retornar JSON en vez de renderizar la vista.

Probando nuestro primer endpoint

Puedes probar este primer endpoint de varias formas:

  1. Utilizando curl, que es una aplicación de la línea de comandos para hacer peticiones HTTP.

  2. Cuando estás haciendo llamados GET puedes utilizar el navegador e ingresar la URL.

Veamos cada una de ellas.

Curl

Curl viene instalado en la mayoría de distribuciones de Linux y en Mac. Si estás en Windows deberás instalarlo o utilizar alguna de las otras alternativas que vamos a ver.

Para hacer una petición a nuestro endpoint deberás abrir otra ventana de la consola (recuerda que debes tener prendido el servidor) y ejecutar el siguiente comando:

$ curl http://localhost:3000/articles

El resultado puede variar dependiendo de los registros que tengas en tu aplicación, pero deberás ver una respuesta similar a la siguiente:

[{"id":1,"title":"Artículo 1","body":"Cuerpo del artículo","published":false,"created_at":"2017-07-09T19:54:42.257Z","updated_at":"2017-07-09T19:54:42.257Z"},{"id":2,"title":"Artículo 2","body":"Cuerpo del artículo","published":true,"created_at":"2017-07-09T19:54:56.582Z","updated_at":"2017-07-09T19:54:56.582Z"}]

Postman

Una vez que has descargado e instalado Postman puedes realizar una petición HTTP como se ven en la siguiente imagen:

HTTParty

Primero debes descargar la gema ejecutando:

$ gem install httparty

Después abre IRB y ejecuta lo siguiente:

$ irb
> require 'httparty'
 => true
> response = HTTParty.get("http://localhost:3000/articles")
  => ...
> response.parsed_response
 => [{"id"=>1, "title"=>"Artículo 1", "body"=>"Cuerpo del artículo", "published"=>false, "created_at"=>"2017-07-09T19:54:42.257Z", "updated_at"=>"2017-07-09T19:54:42.257Z"}, {"id"=>2, "title"=>"Artículo 2", "body"=>"Cuerpo del artículo", "published"=>true, "created_at"=>"2017-07-09T19:54:56.582Z", "updated_at"=>"2017-07-09T19:54:56.582Z"}]

Con el navegador

Como nuestro endpoint sólo retorna JSON puedes abrir en tu navegador la URL http://localhost:3000/articles y verás la respuesta en formato JSON.

Sin embargo, esto sólo es posible para llamados GET.

Completando el API

Veamos ahora los endpoints de crear, editar y eliminar artículos:

class ArticlesController < ApplicationController
  protect_from_forgery with: :null_session

  def index
    articles = Article.all
    render json: articles
  end

  def create
    article = Article.new(article_params)
    if article.save
      render json: article
    else
      render json: { errors: article.errors }, status: 422
    end
  end

  def update
    article = Article.find(params[:id])
    if article.update(article_params)
      render json: article
    else
      render json: { errors: article.errors }, status: 422
    end
  end

  def destroy
    article = Article.find(params[:id])
    article.destroy

    head :no_content
  end

  private
    def article_params
      params.require(:article).permit(:title, :body, :published)
    end
end

Fíjate la línea protect_from_forgery with: :null_session al principio de la clase. Esto es importante para que Rails no haga la verificación normal sobre los formularios y nos permita crear y editar artículos.

En config/routes.rb configuraríamos nuestras rutas así:

Rails.application.routes.draw do
  resources :articles, only: [:index, :create, :update, :destroy]
end

Eso va a crear los siguientes endpoints:

GET /articles
POST /articles
PATCH /articles/:id
DELETE /articles/:id

Para crear un nuevo artículo podemos hacer la siguiente petición:

HTTParty.post("http://localhost:3000/articles",
    body: { title: "Otro artículo", body: "El cuerpo", published: true }.to_json,
    headers: { "Content-Type" => "application/json" })

Para editar un artículo podemos hacer la siguiente petición asumiendo que existe el artículo con id 1:

HTTParty.patch("http://localhost:3000/articles/1",
    body: { title: "Cambia", body: "Cambia el cuerpo", published: true }.to_json,
    headers: { "Content-Type" => "application/json" })

Para eliminar un artículo podemos hacer la siguiente petición asumiendo que existe el artículo con id 1:

HTTParty.delete("http://localhost:3000/articles/1")

Autenticación

Existen varias formas de asegurar un API pero una de las más comunes y fáciles de implementar es HTTP Basic, que fue una de las primeras formas de autenticación en la Web.

Ruby on Rails incluye un método llamado authenticate_or_request_with_http_basic para implementar HTTP Basic. Por ejemplo, podemos asegurar un controlador de la siguiente forma:

class ProductsController < ApplicationController
  before_action :basic_auth

  # acá van todas las acciones

  private
    def basic_auth
      authenticate_or_request_with_http_basic do |user, password|
        # Verificar user y password. Por ejemplo (aunque no lo recomendamos):
        user == "german" && password == "test1234"
      end
    end
end

En la línea 2 agregamos un before_action que va a ejecutar el método basic_auth antes de cada acción.

En la línea 7 estamos definiendo el método que hace uso de authenticate_or_request_with_http_basic para verificar el usuario y la contraseña.

La línea 9 es la que hace la validación. Sin embargo, en este ejemplo tenemos quemados los valores del usuario y la contraseña, más adelante vamos a ver cómo integrar Devise.

Si la autenticación falla se va a retornar un código 401 Unauthorized.

Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l

Aunque es posible generar este encabezado manualmente, la mayoría de herramientas y librerías HTTP ofrecen algún mecanismo para incluir las credenciales y generar el encabezado. Por ejemplo, en curl se utiliza la opción --user o -u:

$ curl --user german:test1234 http://localhost:3000/products

Integración con Devise

  1. Debemos agregar un campo auth_token al modelo de Devise. Por ejemplo:

     $ rails g migration add_auth_token_to_users auth_token
  2. En el modelo User debemos generar el token cuando se crea el usuario utilizando un método que incluye Rails llamado has_secure_token:

     class User < ApplicationRecord
       has_secure_token :auth_token
    
       ...
     end
  3. Implementar el método que hace la verificación en ApplicationController (de esa forma lo podemos utilizar desde varios controladores)

     def basic_auth
       authenticate_or_request_with_http_basic do |username, token|
         user = User.find_by_email(username)
         if user.auth_token == token
           sign_in user
         end
       end
     end

Descargando , que es una aplicación gráfica para hacer peticiones HTTP.

Haciendo la petición HTTP desde cualquier lenguaje de programación. En Ruby puedes utilizar una gema llamada .

Postman
Browser

El primer endpoint lo probamos anteriormente de varias formas, veamos cómo podemos ahora probar los demás desde .

HTTP Basic utiliza un encabezado llamado Authorization que incluye el nombre de usuario y el password en . Por ejemplo:

Puedes autenticar a los usuarios de Devise por HTTP Basic como lo explican en .

Sin embargo, como decíamos anteriormente, no es buena idea utilizar la misma contraseña Web para el API. Una opción es utilizar una gema como o puedes implementarlo tu mismo(a) siguiendo estos pasos:

API de jQuery
Postman
HTTParty
HTTParty
Base64
este artículo
devise_token_auth