Utilizar este Framework es tan fácil como invocarlo y comenzar a desarrollar nuestras funciones, para tenerlo en nuestro entorno seguimos las instrucciones via "gem" que están en el site, para comenzar podemos hacer algo como esto:
require 'sinatra' get '/' do "Esta es la raíz!" endPero esto no es lo que buscamos, lo que queremos es conectarnos a nuestra BD para procesar datos, para simplificarnos las cosas y que nuestro archivo quede mas "legible" (por decirlo así) vamos a crear una clase donde estarán los métodos a utilizar dentro del API, al mismo tiempo que definiremos un ActiveRecord para nuestras consultas SQL, de modo que nuestro archivo vendría quedando algo así:
require 'mysql2' require 'sinatra' require 'sinatra/respond_to' require 'active_record' require 'json' Sinatra::Application.register Sinatra::RespondTo get '/:id' do |id| format_response MyAPI.getUser(id) end class MyAPI < ActiveRecord::Base class << self ActiveRecord::Base.establish_connection( :adapter => "mysql2", :host => "servidor", :port => "3306", :pool => 16, :username => "usuario", :password => "123456", :database => "mibd" ) def getUser(UserId) query = "SELECT nombre FROM usuarios WHERE id = #{UserId}" data = self.connection.select_all(query) data[0]["nombre"] end end end
Una vez definido todo comenzamos a crear nuestras consultas, para nuestra tarea el API de Sinatra nos facilita las cosas ya que cada ruta es un método HTTP asociado a nuestra URL (mas info en w3.org), vamos por ejemplo a definir 4 métodos simples donde creamos, editamos, modificamos y eliminamos un usuario en específico:
require 'mysql2' require 'sinatra' require 'sinatra/respond_to' require 'active_record' require 'json' Sinatra::Application.register Sinatra::RespondTo # Retorna el nombre de usuario, http://127.0.0.1/user/24 get '/user/:id' do |id| format_response MyAPI.getUser(id) end # Agrega un nuevo usuario, http://127.0.0.1/user/carlos post '/user/:name' do |name| format_response MyAPI.createUser(name) end # Modifica el nombre de usuario, http://127.0.0.1/user/id=24&name=carlitox put '/user' do format_response MyAPI.updateUser(params[:id], params[:name]) end # Elimina el usuario, http://127.0.0.1/user/24 delete '/user/:id' do |id| format_response MyAPI.deleteUser(id) end class MyAPI < ActiveRecord::Base class << self ActiveRecord::Base.establish_connection( :adapter => "mysql2", :host => "servidor", :port => "3306", :pool => 16, :username => "usuario", :password => "123456", :database => "mibd" ) # GET def getUser(UserId) query = "SELECT nombre FROM usuarios WHERE id = #{UserId}" data = self.connection.select_all(query) data[0]["nombre"] end # POST def createUser(UserName) query = "INSERT INTO usuarios(nombre) VALUES ('#{UserName}')" self.connection.execute(query) "done" end # PUT def updateUser(UserId, UserName) query = "UPDATE usuarios SET nombre = '#{userName}' WHERE id = #{UserId}" self.connection.execute(query) "done" end # DELETE def deleteUser(UserId) query = "DELETE FROM usuarios WHERE id = #{UserId}" self.connection.execute(query) "done" end end end
La razón de que utilicemos la librería JSON es para que cuando hagamos nuestra llamada solicitemos el archivo en este formato (format_response), de esta forma es más fácil leer la data devuelta. No olvidemos definir dicha función:
def format_response (package) respond_to do |request| request.json { package.to_json } end end
Todo bien, pero ¿que tal si vamos a enviar mas de 1 parámetro a la vez?, como vimos en el ejemplo anterior para el método PUT, pero podemos extendernos un poco más y trabajarlos dentro de la misma clase:
require 'mysql2' require 'sinatra' require 'sinatra/respond_to' require 'active_record' require 'json' Sinatra::Application.register Sinatra::RespondTo # http://127.0.0.1/user/name=carlos&nick=carlitoxenlaweb post '/user' do format_response MyAPI.createUser(params) end class MyAPI < ActiveRecord::Base class << self ActiveRecord::Base.establish_connection( :adapter => "mysql2", :host => "servidor", :port => "3306", :pool => 16, :username => "usuario", :password => "123456", :database => "mibd" ) def createUser(params) query = "INSERT INTO usuarios(name, nick) VALUES ('#{params[:name]}', '#{params[:nick]}')" self.connection.execute(query) "done" end end end
Esto es lo básico, esta entrada puede hacerse tan extensa como repetir la documentación (que bastante hay sobre el tema), visita la página para ver todas las posibilidades: Sinatra Intro!
Por último algunos tips útiles (todo esto fuera de la clase que definimos):
No olvidemos cerrar siempre nuestra conexión con el servidor de base de datos:
after do ActiveRecord::Base.connection.close end
Podemos definir mas formatos de salida como xml, csv o html plano (format_response), así como los métodos que utilizara el servidor y el origen de acceso:
def format_response (package) response.headers['Access-Control-Allow-Origin'] = "http://carlitoxenlaweb.blogspot.com/" response.headers['Access-Control-Allow-Methods'] = "POST, GET, PUT, DELETE" respond_to do |request| request.txt { package.to_s } request.csv { package.to_csv } request.xml { package.to_xml } request.json { package.to_json } request.html { package.to_json } end end
Definamos siempre la IP (interfaz) y puerto que escuchará nuestro servidor
#require..... set :bind => '192.168.1.100', :port => '6543'
Recibe notificaciones por correo
2 Comentarios
Escribir ComentarioLas consultas pueden sufrir ataques de sql injection, no?
ResponderSi, de esta forma pueden sufrir esos fallos de seguridad, para evitarlo se puede crear una función que formatee estos valores y construya el SQL...
ResponderLamentablemente hay muchos usuarios en la red que han llegado al blog para escribir obscenidades, así que la moderación se hace necesaria. Recuerda utilizar un lenguaje correcto y espera a que sea aprobado.
Si necesitas publicar código haz click en "Conversión" para hacerlo legible.
ConversiónConversión