• Nenhum resultado encontrado

A conexão do Rails com o Rack

No documento Livro Desconstruindo a Web (páginas 195-200)

versão 3, sendo que, desde essa versão, toda nova aplicação possui um arquivo config.ru . Por utilizar uma versão maior que a 3,

podemos ver o arquivo config.ru na raiz do projeto do desconstruindoaweb.com.br :

# This file is used by Rack-based servers to start the application.

require_relative 'config/environment'

run Rails.application

Como vimos enquanto estudávamos o Rack, esse é o arquivo que é carregado pelo Passenger para fazer a conexão com o framework e, consequentemente, com a aplicação.

Vamos inspecionar o conteúdo de Rails.application para

entender melhor:

$ rails runner "p Rails.application" 2>/dev/null

#<DesconstruindoAWeb::Application:0x0000000304deb0 @_all_autoload_ paths=...

Esse é o objeto da nossa aplicação, que é um

Rails::Application via herança:

# https://github.com/PotHix/desconstruindoaweb.com.br/blob/master/ config/application.rb#L18

module DesconstruindoAWeb

class Application < Rails::Application

# ...

end end

O Rails::Application , por sua vez, é uma Engine no Rails.

Por esse motivo, ele responde ao método call , se tornando uma

aplicação Rack. Podemos ver isso no código do Rails: # https://github.com/rails/rails/blob/v5.0.0/railties/lib/rails/en gine.rb#L520 # Define the Rack API for this engine. def call(env) req = build_request env app.call req.env 180 8.3 O RUBY ON RAILS

end

Além disso, o Rails também utiliza uma grande quantidade de middlewares do Rack para lidar com os vários passos da conexão.

Às vezes, a palavra middleware é traduzida como mediador. O que ele faz é ficar no meio do caminho entre duas camadas executando uma tarefa. No caso do Rack, os middlewares são plugáveis, possibilitando que eles sejam encadeados. Cada middleware faz uma parte do trabalho, podendo ou não alterar dados na conexão atual.

O Rails possui vários middlewares, que funcionam como microaplicações utilizando o conceito de encadeamento para atender uma requisição. Para ver como é a cadeia de middlewares do desconstruindoaweb.com.br , vamos usar o comando rails middleware : $ bin/rails middleware use Rack::Sendfile use ActionDispatch::Static use ActionDispatch::Executor use ActiveSupport::Cache::Strategy::LocalCache::Middleware use Rack::Runtime use Rack::MethodOverride use ActionDispatch::RequestId use Rails::Rack::Logger use ActionDispatch::ShowExceptions use WebConsole::Middleware use ActionDispatch::DebugExceptions use ActionDispatch::RemoteIp use ActionDispatch::Reloader use ActionDispatch::Callbacks use ActionDispatch::Cookies use ActionDispatch::Session::CookieStore use ActionDispatch::Flash use Rack::Head use Rack::ConditionalGet use Rack::ETag

Os middlewares

8.3 O RUBY ON RAILS 181

run DesconstruindoAWeb::Application.routes

MIDDLEWARE DE SSL

No capítulo 1, vimos o HSTS, e mencionamos que nossa aplicação não estava usando-o para que pudéssemos testar tanto HTTP como HTTPS. Para utilizar, precisamos ativar a opção force_ssl do Rails. Quando essa opção é ativada, um

novo middleware é adicionado à lista:

ActionDispatch::SSL .

Esse middleware lida com o redirecionamento da requisição atual para HTTPS e adiciona o cabeçalho do HSTS para que novas requisições usem o protocolo.

Como exemplo, podemos usar o

ActionDispatch::RequestId que faz parte do ActionDispatch

e tem como finalidade gerar um número aleatório para a requisição. Vamos estudá-lo mais de perto:

# https://github.com/rails/rails/blob/v5.0.0/actionpack/lib/action _dispatch/middleware/request_id.rb#L17

class RequestId

X_REQUEST_ID = "X-Request-Id".freeze # :nodoc:

def initialize(app) @app = app end

def call(env)

req = ActionDispatch::Request.new env

req.request_id = make_request_id(req.x_request_id)

@app.call(env).tap { |_status, headers, _body| headers[X_REQUE

ST_ID] = req.request_id }

end

# ...

end

Essa é a estrutura de um middleware do Rack. Ele recebe a aplicação quando é iniciado e responde pelo método call(env) .

O env é um hash com todas as informações sobre a conexão atual,

incluindo as que foram adicionadas por middlewares executados antes dele.

Nesse código, ele chama o método call para passar a

requisição para o próximo middleware e aguarda até a resposta. Quando a resposta é recebida, ele executa o método tap para ter

acesso ao conteúdo e utiliza apenas o Hash de cabeçalhos para

incluir uma nova chave. Essa chave se chama X-Request-Id e

possui o número aleatório referente a essa requisição.

Podemos ver esse cabeçalho na prática quando fazemos uma requisição para o desconstruindoaweb.com.br :

$ curl -v http://desconstruindoaweb.com.br |& grep Request < X-Request-Id: 1f844f1e-d176-4584-a629-75fa887b928a

CURIOSIDADE SOBRE O COMANDO CURL

Nesse comando, estamos utilizando o comando curl com o

argumento -v para mostrar, além do conteúdo da página,

todos os cabeçalhos enviados e recebidos. Como esse valor vai para a saída de erro padrão, também conhecida com STDERR ,

precisamos usar esse truque do |& para conseguir utilizar o

comando grep para filtrá-los.

Esse é apenas um dos middlewares, sendo provavelmente o mais simples deles. Por padrão, o Rails adiciona middlewares para executar diversos tipos de tarefas. Mas não é só um privilégio do Rails, pois o desenvolvedor também pode adicionar middlewares customizados, bastando adicioná-los ao processo na configuração 8.3 O RUBY ON RAILS 183

principal da aplicação.

O sistema de middlewares é uma forma poderosa e extensível que vem sendo utilizada em aplicações web há muitos anos.

Figura 8.6: O processo dos middlewares

O último dos middlewares da lista é o

DesconstruindoAWeb::Application.routes , responsável pelas

rotas da aplicação. Vamos inspecioná-lo para obter mais informações:

$ rails runner "p DesconstruindoAWeb::Application.routes"

#<ActionDispatch::Routing::RouteSet:0x0000000368e6a8>

Ele é um objeto do tipo

ActionDispatch::Routing::RouteSet , que também é um

middleware. Se olharmos no código do Rails, veremos que ele possui um método initialize e um método call . Para

entender o que ele faz, vamos olhar o método call :

# https://github.com/rails/rails/blob/v5.0.0/actionpack/lib/action

No documento Livro Desconstruindo a Web (páginas 195-200)

Documentos relacionados