Inicio / Ruby / Ruby: Lenguaje Elegante y Expresivo / HTTP, APIs y Networking

HTTP, APIs y Networking

Net::HTTP, HTTParty, Faraday, WEBrick, Sinatra, WebSockets y Sockets TCP.

Avanzado
🔒 Solo lectura
📖

Estás en modo lectura

Puedes leer toda la lección, pero para marcar progreso, hacer ejercicios y ganar XP necesitas una cuenta Pro.

Desbloquear por $9/mes

HTTP, APIs y Networking en Ruby

Ruby tiene herramientas potentes para trabajar con HTTP y construir/consumir APIs.


Net::HTTP (stdlib)

require 'net/http'
require 'json'
require 'uri'

# GET simple
uri = URI('https://jsonplaceholder.typicode.com/posts/1')
response = Net::HTTP.get_response(uri)
puts response.code          # "200"
puts response.content_type  # "application/json"

data = JSON.parse(response.body)
puts data['title']

# GET con parámetros
uri = URI('https://api.example.com/search')
uri.query = URI.encode_www_form(q: 'ruby', page: 1)
response = Net::HTTP.get_response(uri)

# POST con JSON
uri = URI('https://jsonplaceholder.typicode.com/posts')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Post.new(uri.path)
request['Content-Type'] = 'application/json'
request['Authorization'] = 'Bearer token123'
request.body = { title: 'Hola', body: 'Contenido', userId: 1 }.to_json

response = http.request(request)
puts JSON.parse(response.body)

# PUT
request = Net::HTTP::Put.new(uri.path + '/1')
request['Content-Type'] = 'application/json'
request.body = { title: 'Actualizado' }.to_json

# DELETE
request = Net::HTTP::Delete.new(uri.path + '/1')

HTTParty (gema popular)

gem install httparty
require 'httparty'

# GET
response = HTTParty.get('https://api.github.com/users/octocat',
  headers: { 'User-Agent' => 'Ruby App' }
)
puts response['name']
puts response.code
puts response.headers['content-type']

# POST
response = HTTParty.post('https://jsonplaceholder.typicode.com/posts',
  body: { title: 'Hola', body: 'Contenido' }.to_json,
  headers: { 'Content-Type' => 'application/json' }
)

# Clase wrapper
class GitHubAPI
  include HTTParty
  base_uri 'https://api.github.com'
  headers 'User-Agent' => 'Ruby App'

  def user(username)
    self.class.get("/users/#{username}")
  end

  def repos(username)
    self.class.get("/users/#{username}/repos",
      query: { sort: 'updated', per_page: 5 }
    )
  end
end

api = GitHubAPI.new
user = api.user('octocat')
puts "#{user['name']} - #{user['public_repos']} repos"

Faraday (gema flexible)

require 'faraday'
require 'faraday/net_http'

# Cliente configurado
conn = Faraday.new(url: 'https://api.example.com') do |f|
  f.request :json                    # encode body como JSON
  f.response :json                   # parse response como JSON
  f.response :raise_error            # lanza en 4xx/5xx
  f.adapter Faraday.default_adapter
  f.headers['Authorization'] = 'Bearer token123'
end

# GET
response = conn.get('/users', page: 1, per_page: 10)
puts response.body   # ya parseado como Hash

# POST
response = conn.post('/users') do |req|
  req.body = { name: 'Ana', email: 'ana@test.com' }
end

# Middleware custom
class LoggingMiddleware < Faraday::Middleware
  def call(env)
    puts ">> #{env.method.upcase} #{env.url}"
    response = @app.call(env)
    puts "<< #{response.status}"
    response
  end
end

Servidor HTTP con WEBrick

require 'webrick'
require 'json'

server = WEBrick::HTTPServer.new(Port: 8080)

server.mount_proc '/' do |req, res|
  res.content_type = 'application/json'
  res.body = { message: 'Hola Mundo', time: Time.now }.to_json
end

server.mount_proc '/users' do |req, res|
  case req.request_method
  when 'GET'
    res.content_type = 'application/json'
    res.body = [{ id: 1, name: 'Ana' }].to_json
  when 'POST'
    body = JSON.parse(req.body)
    res.status = 201
    res.body = body.merge('id' => 2).to_json
  end
end

trap('INT') { server.shutdown }
server.start

Sinatra (micro-framework)

gem install sinatra sinatra-contrib
require 'sinatra'
require 'sinatra/json'

# Rutas
get '/' do
  json message: 'Hola Mundo'
end

get '/users/:id' do
  id = params[:id]
  json id: id, name: "User #{id}"
end

post '/users' do
  body = JSON.parse(request.body.read)
  status 201
  json body.merge('id' => rand(1000))
end

put '/users/:id' do
  body = JSON.parse(request.body.read)
  json body.merge('id' => params[:id])
end

delete '/users/:id' do
  status 204
end

# Middleware
before do
  content_type :json
  # Autenticación
  unless request.path == '/'
    token = request.env['HTTP_AUTHORIZATION']
    halt 401, json(error: 'No autorizado') unless token
  end
end

# Error handling
error 404 do
  json error: 'No encontrado'
end

not_found do
  json error: 'Ruta no encontrada'
end

WebSockets

require 'faye-websocket'
require 'eventmachine'

# Cliente WebSocket
EM.run do
  ws = Faye::WebSocket::Client.new('wss://echo.websocket.org')

  ws.on :open do
    puts 'Conectado'
    ws.send('Hola WebSocket!')
  end

  ws.on :message do |event|
    puts "Recibido: #{event.data}"
    ws.close
  end

  ws.on :close do
    puts 'Desconectado'
    EM.stop
  end
end

TCP/UDP con Sockets

require 'socket'

# Servidor TCP
server = TCPServer.new('localhost', 3000)
puts "Servidor escuchando en puerto 3000..."

loop do
  client = server.accept
  request = client.gets
  puts "Recibido: #{request}"

  client.puts "HTTP/1.1 200 OK\r\n"
  client.puts "Content-Type: text/plain\r\n"
  client.puts "\r\n"
  client.puts "Hola desde Ruby!"
  client.close
end

# Cliente TCP
require 'socket'
socket = TCPSocket.new('localhost', 3000)
socket.puts "GET / HTTP/1.1\r\n\r\n"
response = socket.read
puts response
socket.close

Resumen

Herramienta Tipo Uso
Net::HTTP stdlib HTTP básico
HTTParty gema HTTP simple y elegante
Faraday gema HTTP flexible con middleware
WEBrick stdlib Servidor HTTP básico
Sinatra gema Micro-framework web
Socket stdlib TCP/UDP raw
Faye gema WebSockets
🔒

Ejercicio práctico disponible

Router HTTP y middleware

Desbloquear ejercicios
// Router HTTP y middleware
// Desbloquea Pro para acceder a este ejercicio
// y ganar +50 XP al completarlo

function ejemplo() {
    // Tu código aquí...
}

¿Te gustó esta lección?

Con Pro puedes marcar progreso, hacer ejercicios, tomar quizzes, ganar XP y obtener tu constancia.

Ver planes desde $9/mes