Primeiramente, será apresentado como criar uma API Rest usando Rails 5.0 a partir da API de clima disponível no site https://openweathermap.org/api. Em seguida, será instalado o pacote RSpec de Rails para que seja possível executar os testes dessa API.
Pré-requisitos
- ruby version ≥ 2.3
- rails version ≥ 5
- API Key ao se cadastrar no site https://openweathermap.org/api
- Tutorial para Ruby on Rails: https://app.gitbook.com/@carolsprak/s/ruby-on-rails-para-iniciantes/
Criando uma API Rest com Ruby on Rails
Para criar uma API com Rails é necessário que seja feita a instalação completa do Rails 5.0 na sua máquina.
No terminal entrar na pasta do seu workspace e digitar o comando para criar um novo projeto de API em rails:
C:/workspace>rails new climateapi --api
Observe que esse projeto difere dos outros projetos por haver o termo ‘api’
Com a aplicação criada, entrar na pasta do projeto criado e digitar o comando para instalar todas as bibliotecas do projeto.
C:/workspace/climateapi>bundle install
Caso ocorra algum erro referente ao sqlite, basta alterar no arquivo /climateapi/Gemfile.
gem 'sqlite3', '< 1.4'
gem 'rack-cors'
Em seguida, executar novamente o comando ‘bundle install’.
Na pasta config adicionar ao arquivo application.rb a configuração do Cors, que autoriza essa API ser utilizada por outros sistemas.
#adicionar esse trecho do código
config.middleware.insert_before 0, "Rack::Cors" do .. end
require_relative 'boot' |
require "rails" |
# Pick the frameworks you want: |
require "active_model/railtie" |
require "active_job/railtie" |
require "active_record/railtie" |
require "action_controller/railtie" |
require "action_mailer/railtie" |
require "action_view/railtie" |
require "action_cable/engine" |
# require "sprockets/railtie" |
require "rails/test_unit/railtie" |
# Require the gems listed in Gemfile, including any gems |
# you've limited to :test, :development, or :production. |
Bundler.require(*Rails.groups) |
module Climatempoapi |
class Application < Rails::Application |
# Settings in config/environments/* take precedence over those specified here. |
# Application configuration should go into files in config/initializers |
# -- all .rb files in that directory are automatically loaded. |
# Only loads a smaller set of middleware suitable for API only apps. |
# Middleware like session, flash, cookies can be added back manually. |
# Skip views, helpers and assets when generating a new resource. |
config.api_only = true |
config.middleware.insert_before 0, "Rack::Cors" do |
allow do |
origins '*' |
resource( |
'*', |
headers: :any, |
methods: [:get, :patch, :put, :delete, :post, :options] |
) |
end |
end |
end |
end |
Na pasta controllers /climateapi/app/controllers/api/v1 criar o arquivo clima_controller.rb
module Api |
module V1 |
class ClimaController < ApplicationController |
def show |
@host = 'http://api.openweathermap.org/data/2.5/' |
@key = 'SUA_API_KEY' |
city = params[:city] |
@weather_city = api_request_city_weather(@host, city, @key) |
puts @weather_city |
render json: @weather_city |
end |
private |
# GET API city weather from Open weather map |
def api_request_city_weather(host, city, key) |
require 'net/http' |
require 'net/https' |
require 'open-uri' |
require 'json' |
url_weather = host + 'weather?q=' + city + '&appid=' + key |
uri = URI.parse(url_weather) |
http = Net::HTTP.new(uri.host, uri.port) |
request = Net::HTTP::Post.new(uri.request_uri) |
response = http.request(request) |
content = JSON.parse(response.body) |
return content |
end |
end |
end |
end |
Na pasta config /climateapi/config alterar o arquivo routes.rb
Rails.application.routes.draw do |
namespace 'api' do |
namespace 'v1' do |
resources :weather, param: :city |
end |
end |
end |
Executar o comando no terminal para criar as rotas
C:/workspace/climateapi>rails routes
Controller#Action api_v1_weather_index GET /api/v1/weather(.:format) api/v1/weather#index POST /api/v1/weather(.:format) api/v1/weather#create api_v1_weather GET /api/v1/weather/:city(.:format) api/v1/weather#show PATCH /api/v1/weather/:city(.:format) api/v1/weather#update PUT /api/v1/weather/:city(.:format) api/v1/weather#update DELETE /api/v1/weather/:city(.:format) api/v1/weather#destroy
Em seguida, rodar a API para verificar se os dados em formato JSON foram recuperados da API Rest original.
C:/workspace/climateapi>rails s -b 0.0.0.0 -p 3050
Acessar a URL local no navegador e ver se exibe o resultado: http://localhost:3050/api/v1/weather/Aracaju
{ | |
"coord": { | |
"lon": -37.07, | |
"lat": -10.91 | |
}, | |
"weather": [ | |
{ | |
"id": 802, | |
"main": "Clouds", | |
"description": "scattered clouds", | |
"icon": "03n" | |
} | |
], | |
"base": "stations", | |
"main": { | |
"temp": 298.15, | |
"feels_like": 299.58, | |
"temp_min": 298.15, | |
"temp_max": 298.15, | |
"pressure": 1012, | |
"humidity": 83 | |
}, | |
"visibility": 10000, | |
"wind": { | |
"speed": 4.6, | |
"deg": 100 | |
}, | |
"clouds": { | |
"all": 40 | |
}, | |
"dt": 1605072214, | |
"sys": { | |
"type": 1, | |
"id": 8322, | |
"country": "BR", | |
"sunrise": 1605081293, | |
"sunset": 1605126599 | |
}, | |
"timezone": -10800, | |
"id": 3471872, | |
"name": "Aracaju", | |
"cod": 200 | |
} |
Pronto! Sua API Rest em Ruby on Rails foi criada utilizando outro serviço de API disponível na internet.
Testando uma Rails API com Rspec
Agora que já temos uma Rails API criada, iremos instalar o rspec-rails e outras gems para que seja possível realizar os testes nessa API.
Abrir o arquivo Gemfile na raiz do mesmo projeto climateapi/Gemfile e incluir as seguintes gems na seção :test.
group :development, :test do | |
gem 'byebug', platform: :mri | |
gem 'rspec-rails', '~> 4.0.1' | |
gem 'factory_bot_rails' | |
end |
Entrar na pasta do projeto criado e digitar o comando para instalar as novas bibliotecas do projeto.
C:/workspace/climateapi>bundle install
Em seguida executar o comando para geração da pasta climateapi/spec.
C:/workspace/climateapi>rails generate rspec:install
Entrar nessa pasta e criar um novo arquivo climateapi/spec/clima_spec.rb
require 'rails_helper' | |
describe "get weather route to Aracaju", :type => :request do | |
before {get '/api/v1/weather/Aracaju'} | |
it 'returns weather' do | |
expect(JSON.parse(response.body)['name']).to eq('Aracaju') | |
end | |
it 'returns status code 200' do | |
expect(response).to have_http_status(:success) | |
end | |
end |
Em seguida, executar os testes utilizando o comando abaixo.
C:/workspace/climateapi>bundle exec rspec ./spec/weather_spec.rb
Observar que os testes passaram conforme o resultado esperado:
{"coord"=>{"lon"=>-37.07, "lat"=>-10.91}, "weather"=>[{"id"=>802, "main"=>"Clouds",
"description"=>"scattered clouds", "icon"=>"03n"}], "base"=>"stations",
"main"=>{"temp"=>298.15, "feels_like"=>299.58, "temp_min"=>298.15, "temp_max"=>298.15,
"pressure"=>1012, "humidity"=>83}, "visibility"=>10000, "wind"=>{"speed"=>4.6, "deg"=>100},
"clouds"=>{"all"=>40}, "dt"=>1605073980, "sys"=>{"type"=>1, "id"=>8322, "country"=>"BR",
"sunrise"=>1605081293, "sunset"=>1605126599}, "timezone"=>-10800, "id"=>3471872,
"name"=>"Aracaju", "cod"=>200}
Finished in 1.55 seconds (files took 5.51 seconds to load)
2 examples, 0 failures
Fiz este artigo originalmente no Medium do GTSW:
https://medium.com/gtsw/como-testar-uma-rails-api-com-rspec-596d4ce39988
Redes Sociais