Más en rubyonrails.org: Más Ruby on Rails

NO LEA ESTE ARCHIVO EN GITHUB, LAS GUÍAS SE PUBLICAN EN https://railsguides.es/

Uso de Rails para Aplicaciones Solo API

En esta guía aprenderá:

1 What is an API Application?

Tradicionalmente, cuando las personas decían que usaban Rails como una "API", querían decir proporcionando una API accesible mediante programación junto con su aplicación web. Por ejemplo, GitHub proporciona una API que usted puede utilizar desde sus propios clientes personalizados.

Con la llegada de los frameworks del lado del cliente, más desarrolladores están usando Rails para crear un back-end que se comparta entre su aplicación web y otras aplicaciones nativas aplicaciones.

Por ejemplo, Twitter usa su API pública en su sitio web. aplicación, que se crea como un sitio estático que consume recursos JSON.

En lugar de usar Rails para generar HTML que se comunica con el servidor a través de formularios y enlaces, muchos desarrolladores tratan su aplicación web como solo un cliente API entregado como HTML con JavaScript que consume una API JSON.

Esta guía cubre la creación de una aplicación Rails que proporciona recursos JSON a un Cliente API, incluidos los marcos del lado del cliente.

2 Why Use Rails for JSON APIs?

La primera pregunta que mucha gente tiene al pensar en construir una API JSON usar Rails es: "¿no está usando Rails para escupir un exceso de JSON? ¿No debería usar algo como Sinatra? ".

Para API muy simples, esto puede ser cierto. Sin embargo, incluso en HTML muy pesado aplicaciones, la mayor parte de la lógica de una aplicación vive fuera de la vista capa.

La razón por la que la mayoría de la gente usa Rails es que proporciona un conjunto de valores predeterminados que permite a los desarrolladores ponerse en marcha rápidamente, sin tener que hacer muchas cosas triviales decisiones.

Echemos un vistazo a algunas de las cosas que proporciona Rails listas para usar que son sigue siendo aplicable a las aplicaciones API.

Manejado en la capa de middleware:

  • Recarga: las aplicaciones de rieles admiten la recarga transparente. Esto funciona incluso si su aplicación se vuelve grande y reiniciar el servidor para cada solicitud se convierte en inviable.
  • Modo de desarrollo: las aplicaciones de Rails vienen con valores predeterminados inteligentes para el desarrollo, haciendo que el desarrollo sea agradable sin comprometer el rendimiento durante el tiempo de producción.
  • Modo de prueba: modo de desarrollo Ditto.
  • Registro: las aplicaciones de Rails registran cada solicitud, con un nivel de verbosidad apropiado para el modo actual. Los registros de Rails en desarrollo incluyen información sobre el entorno de solicitud, las consultas de la base de datos y el rendimiento básico información.
  • Seguridad: Rails detecta y frustra IP spoofing attacks y maneja firmas criptográficas en un timing attack forma consciente. No se que ¿Es un ataque de suplantación de IP o un ataque de tiempo? Exactamente.
  • Análisis de parámetros: desea especificar sus parámetros como JSON en lugar de como un Cadena codificada en URL? No hay problema. Rails decodificará el JSON por ti y hará está disponible en "params". ¿Quiere utilizar parámetros codificados en URL anidados? Ese también funciona.
  • GET condicionales: Rails maneja GET condicional (ETag y Last-Modified) procesar los encabezados de las solicitudes y devolver los encabezados y el estado de respuesta correctos código. Todo lo que necesita hacer es usar el stale? registre su controlador, y Rails manejará todos los detalles HTTP por usted.
  • Solicitudes HEAD: Rails convertirá de forma transparente las solicitudes HEAD enGET, y devuelva solo los encabezados al salir. Esto hace que "HEAD" funcione de manera confiable en todas las API de Rails.

Si bien, obviamente, podría construirlos en términos de middleware Rack existente, esta lista demuestra que la pila de middleware de Rails predeterminada proporciona mucho de valor, incluso si "solo está generando JSON".

Manejado en la capa Action Pack:

  • Enrutamiento ingenioso: si está creando una API JSON RESTful, desea ser utilizando el enrutador Rails. Mapeo limpio y convencional de HTTP a controladores significa no tener que perder tiempo pensando en cómo modelar su API en términos de HTTP.
  • Generación de URL: la otra cara del enrutamiento es la generación de URL. Una buena API basada en HTTP incluye URL (consulte the GitHub Gist API para un ejemplo).
  • Respuestas de encabezado y redirección: head: no_content y redirect_to user_url (current_user) es útil. Claro, podrías manualmente agregue los encabezados de respuesta, pero ¿por qué?
  • Almacenamiento en caché: Rails proporciona almacenamiento en caché de páginas, acciones y fragmentos. Almacenamiento en caché de fragmentos es especialmente útil cuando se crea un objeto JSON anidado.
  • Autenticación básica, implícita y de token: Rails viene con soporte listo para usar para tres tipos de autenticación HTTP.
  • Instrumentación: Rails tiene una API de instrumentación que dispara registrados controladores para una variedad de eventos, como el procesamiento de acciones, el envío de un archivo o consultas de datos, redirección y bases de datos. La carga útil de cada evento viene con información relevante (para el evento de procesamiento de acciones, la carga útil incluye el controlador, la acción, los parámetros, el formato de solicitud, el método de solicitud y el ruta completa de la solicitud).
  • Generadores: a menudo es útil generar un recurso y obtener su modelo, controlador, stubs de prueba y rutas creadas para usted en un solo comando para más ajustes. Lo mismo para migraciones y otros.
  • Complementos: muchas bibliotecas de terceros vienen con soporte para Rails que reducen o eliminar el costo de configurar y pegar la biblioteca y el marco web. Esto incluye cosas como anular los generadores predeterminados, agregar Rake tareas y respetando las opciones de Rails (como el registrador y el back-end de caché).

Por supuesto, el proceso de arranque de Rails también pega todos los componentes registrados. Por ejemplo, el proceso de arranque de Rails es lo que usa su archivo config/database.yml al configurar Active Record.

La versión corta es: es posible que no hayas pensado en qué partes de Rails siguen siendo aplicables incluso si elimina la capa de vista, pero la respuesta resulta para ser la mayor parte.

3 The Basic Configuration

Si está creando una aplicación Rails, primero será un servidor API y sobre todo, puede comenzar con un subconjunto más limitado de rieles y agregar características según sea necesario.

3.1 Creating a new application

Puede generar una nueva aplicación api Rails:

$ rails new my_api --api

Esto hará tres cosas principales por ti:

  • Configure su aplicación para comenzar con un conjunto más limitado de middleware de lo normal. Específicamente, no incluirá ningún middleware principalmente útil. para aplicaciones de navegador (como soporte de cookies) de forma predeterminada.
  • Hacer que ApplicationController herede de ActionController::API en lugar de ActionController::Base. Al igual que con el middleware, esto omitirá cualquier acción. Módulos de controlador que proporcionan funcionalidades utilizadas principalmente por el navegador aplicaciones.
  • Configure los generadores para omitir la generación de vistas, ayudantes y activos cuando genera un nuevo recurso.

3.2 Changing an existing application

If you want to take an existing application and make it an API one, read the following steps.

In config/application.rb add the following line at the top of the Application class definition:

config.api_only = true

En config/environment/development.rb, establezca config.debug_exception_response_format para configurar el formato utilizado en las respuestas cuando se producen errores en el modo de desarrollo.

Para representar una página HTML con información de depuración, use el valor :predeterminado.

config.debug_exception_response_format = :default

Para renderizar la información de depuración conservando el formato de respuesta, use el valor :api.

config.debug_exception_response_format = :api

De forma predeterminada, config.debug_exception_response_format se establece en :api, cuando config.api_only se establece en verdadero.

Finalmente, dentro de app/controllers/application_controller.rb, en lugar de:

class ApplicationController < ActionController::Base
end

hacer:

class ApplicationController < ActionController::API
end

4 Choosing Middleware

Una aplicación API viene con el siguiente middleware de forma predeterminada:

  • ActionDispatch::HostAuthorization
  • Rack::Sendfile
  • ActionDispatch::Static
  • ActionDispatch::Executor
  • ActiveSupport::Cache::Strategy::LocalCache::Middleware
  • Rack::Runtime
  • ActionDispatch::RequestId
  • ActionDispatch::RemoteIp
  • Rails::Rack::Logger
  • ActionDispatch::ShowExceptions
  • ActionDispatch::DebugExceptions
  • ActionDispatch::ActionableExceptions
  • ActionDispatch::Reloader
  • ActionDispatch::Callbacks
  • ActiveRecord::Migration::CheckPending
  • Rack::Head
  • Rack::ConditionalGet
  • Rack::ETag

Consulte el internal middleware sección de la Guía del bastidor para obtener más información sobre ellos.

Otros complementos, incluido Active Record, pueden agregar middleware adicional. En En general, estos middleware son independientes del tipo de aplicación que está construir y tener sentido en una aplicación Rails solo para API.

Puede obtener una lista de todo el middleware en su aplicación a través de:

$ bin/rails middleware

4.1 Using the Cache Middleware

De forma predeterminada, Rails agregará un middleware que proporciona un almacén de caché basado en la configuración de su aplicación (memcache por defecto). Esto significa que la caché HTTP incorporada se basará en él.

Por ejemplo, usando el método stale?:

def show
  @post = Post.find(params[:id])

  if stale?(last_modified: @post.updated_at)
    render json: @post
  end
end

La llamada a stale? Comparará el encabezado If-Modified-Since en la solicitud con @post.updated_at. Si el encabezado es más nuevo que el último modificado, este La acción devolverá una respuesta "304 No modificado". De lo contrario, hará que el respuesta e incluir un encabezado "Última modificación" en él.

Normalmente, este mecanismo se utiliza por cliente. El middleware de caché nos permite compartir este mecanismo de almacenamiento en caché entre clientes. Podemos habilitar almacenamiento en caché entre clientes en la llamada a stale?:

def show
  @post = Post.find(params[:id])

  if stale?(last_modified: @post.updated_at, public: true)
    render json: @post
  end
end

Esto significa que el middleware de caché almacenará el valor de "Última modificación" para una URL en la caché de Rails, y agregue un encabezado If-Modified-Since a cualquier solicitudes entrantes posteriores para la misma URL.

Piense en ello como un almacenamiento en caché de páginas utilizando semántica HTTP.

4.2 Using Rack::Sendfile

Cuando usa el método send_file dentro de un controlador Rails, establece el Encabezado X-Sendfile. Rack :: Sendfile es responsable de enviar el expediente.

Si su servidor front-end admite el envío acelerado de archivos, Rack :: Sendfile descargará el trabajo de envío de archivos real al servidor de aplicaciones para el usuario.

Puede configurar el nombre del encabezado que utiliza su servidor de aplicaciones para este propósito usando config.action_dispatch.x_sendfile_header en el archivo de configuración del entorno.

Puede aprender más sobre cómo usar Rack :: Sendfile con popular frontales en the Rack::Sendfile documentation.

A continuación se muestran algunos valores de este encabezado para algunos servidores populares, una vez que estos servidores estén configurados para admitir envío de archivos acelerado:

# Apache and lighttpd
config.action_dispatch.x_sendfile_header = "X-Sendfile"

# Nginx
config.action_dispatch.x_sendfile_header = "X-Accel-Redirect"

Asegúrese de configurar su servidor para que admita estas opciones siguiendo las instrucciones en la documentación de Rack::Sendfile.

4.3 Using ActionDispatch::Request

ActionDispatch::Request#params tomará parámetros del cliente en el JSON formato y hacerlos disponibles en su controlador dentro de params.

Para usar esto, su cliente deberá realizar una solicitud con parámetros codificados en JSON y especifique el Content-Type como application/json.

Aquí hay un ejemplo en jQuery:

jQuery.ajax({
  type: 'POST',
  url: '/people',
  dataType: 'json',
  contentType: 'application/json',
  data: JSON.stringify({ person: { firstName: "Yehuda", lastName: "Katz" } }),
  success: function(json) { }
});

ActionDispatch::Request will see the Content-Type and your parameters will be:

{ :person => { :firstName => "Yehuda", :lastName => "Katz" } }

4.4 Using Session Middlewares

Los siguientes middlewares, que se utilizan para la gestión de sesiones, están excluidos de las aplicaciones API, ya que normalmente no necesitan sesiones. Si uno de sus clientes de API es un navegador, es posible que desee agregar uno de estos nuevamente en:

  • ActionDispatch::Session::CacheStore
  • ActionDispatch::Session::CookieStore
  • ActionDispatch::Session::MemCacheStore

El truco para volver a agregarlos es que, de forma predeterminada, se pasan session_options cuando se agrega (incluida la clave de sesión), por lo que no puede simplemente agregar un inicializador session_store.rb, agregue use ActionDispatch::Session::CookieStore y haga que las sesiones funcionen como de costumbre. (Para ser claros: sesiones puede funcionar, pero las opciones de sesión se ignorarán, es decir, la clave de sesión será por defecto _session_id)

En lugar del inicializador, tendrá que configurar las opciones relevantes en algún lugar antes de que su middleware sea built (como config/application.rb) y páselos a su middleware preferido, así:

config.session_store :cookie_store, key: '_interslice_session' # <-- this also configures session_options for use below
config.middleware.use ActionDispatch::Cookies # Required for all session management (regardless of session_store)
config.middleware.use config.session_store, config.session_options

4.5 Other Middleware

Rails se envía con una serie de middleware que quizás desee utilizar en un Aplicación API, especialmente si uno de sus clientes API es el navegador:

  • Rack::MethodOverride
  • ActionDispatch::Cookies
  • ActionDispatch::Flash

Cualquiera de estos middleware se puede agregar a través de:

config.middleware.use Rack::MethodOverride

4.6 Removing Middleware

Si no desea utilizar un middleware que se incluye de forma predeterminada en la API solo conjunto de middleware, puede eliminarlo con:

config.middleware.delete ::Rack::Sendfile

Tenga en cuenta que la eliminación de estos middlewares eliminará el soporte para ciertos características en Action Controller.

5 Choosing Controller Modules

Una aplicación API (usando ActionController::API) viene con lo siguiente módulos de controlador por defecto:

  • ActionController::UrlFor: Hace que url_for y ayudantes similares estén disponibles.
  • ActionController::Redirecting: Soporte para redirect_to.
  • AbstractController::Rendering y ActionController::ApiRendering: Soporte básico para renderizado.
  • ActionController::Renderers :: All: Soporte para render :json y amigos.
  • ActionController::ConditionalGet: Soporte para stale?.
  • ActionController::BasicImplicitRender: Se asegura de devolver una respuesta vacía, si no hay una explícita.
  • ActionController::StrongParameters: Soporte para filtrado de parámetros en combinación con asignación masiva de Active Model.
  • ActionController::DataStreaming: Soporte para send_file y send_data.
  • AbstractController::Callbacks: Soporte para before_action y ayudantes similares.
  • ActionController::Rescue: Soporte para rescue_from.
  • ActionController::Instrumentation: Soporte para la instrumentación ganchos definidos por Action Controller (consulte la instrumentación guía para más información al respecto).
  • ActionController::ParamsWrapper: Envuelve el hash de los parámetros en un hash anidado, para que no tenga que especificar elementos raíz que envíen solicitudes POST, por ejemplo.
  • ActionController::Head: Soporte para devolver una respuesta sin contenido, solo encabezados

Otros complementos pueden agregar módulos adicionales. Puede obtener una lista de todos los módulos incluido en ActionController::API en la consola de rails:

$ bin/rails c
>> ActionController::API.ancestors - ActionController::Metal.ancestors
=> [ActionController::API,
    ActiveRecord::Railties::ControllerRuntime,
    ActionDispatch::Routing::RouteSet::MountedHelpers,
    ActionController::ParamsWrapper,
    ... ,
    AbstractController::Rendering,
    ActionView::ViewPaths]

5.1 Adding Other Modules

Todos los módulos de Action Controller conocen sus módulos dependientes, por lo que puede sentir libre de incluir cualquier módulo en sus controladores, y todas las dependencias serán incluido y configurado también.

Algunos módulos comunes que quizás desee agregar:

  • AbstractController::Translation: Soporte para la localización l y t y métodos de traducción.
  • Soporte para autenticación HTTP básica, digest o token:
    • ActionController::HttpAuthentication::Basic::ControllerMethods,
    • ActionController::HttpAuthentication::Digest::ControllerMethods,
    • ActionController::HttpAuthentication::Token::ControllerMethods
  • ActionView::Layouts: Soporte para diseños al renderizar.
  • ActionController::MimeResponds: Soporte para respond_to.
  • ActionController::Cookies: Soporte para cookies, que incluye soporte para cookies firmadas y encriptadas. Esto requiere el middleware de cookies.
  • ActionController::Caching: Admite el almacenamiento en caché de vistas para el controlador API. Por favor informa eso deberá especificar manualmente el almacén de caché dentro del controlador como: ```ruby class ApplicationController < ActionController::API include ::ActionController::Caching self.cache_store = :mem_cache_store end

Rails no pasa esta configuración automáticamente.

El mejor lugar para agregar un módulo es en su ApplicationController, pero puede también agregue módulos a controladores individuales.

Comentarios Sobre el Contenido

Las guías de rieles se administran y publican en latinadeveloper/railsguides.es en GitHub.

Si lee esta guía y encuentra algún texto o código incorrecto que le interese, no dude en enviar una solicitud de extracción en el repositorio anterior. Consulte el archivo README en GitHub para saber cómo enviar una solicitud de extracción. Please contribute if you see any typos or factual errors.