SlideShare ist ein Scribd-Unternehmen logo
1 von 100
Downloaden Sie, um offline zu lesen
Diseño de APIs con Ruby
   Edwin Cruz @softr8
PLAN
• Que   es una API

• Como   implementar una buena API

• Usando   Ruby on Rails para implementar una
 API

• Patrones   de diseño
“   Application
    Programming
    Interface


                  “
API

  Es una manera para
     comunicar dos
aplicaciones entre ellas.
TIPOS DE API


• Library

• SDK

• Web   services
PRIMERAS API - SOAP

       Simple
       Object
       Access
       Protocol
REST

REpresentation
State
Transfer
REQUISITOS REST
REQUISITOS REST

Separación de responsabilidades
REQUISITOS REST

Separación de responsabilidades
Cliente/Servidor
REQUISITOS REST

Separación de responsabilidades
Cliente/Servidor
Sin estado
REQUISITOS REST

Separación de responsabilidades
Cliente/Servidor
Sin estado
Puede ser “Cacheable”
REQUISITOS REST

Separación de responsabilidades
Cliente/Servidor
Sin estado
Puede ser “Cacheable”
Sistema a capas
REQUISITOS REST

Separación de responsabilidades
Cliente/Servidor
Sin estado
Puede ser “Cacheable”
Sistema a capas
Interface uniforme
CRUD

Create   Altas
Read     Bajas
Update   Cambios
Delete   Consultas
REST + CRUD
REST + CRUD


   Recursos a través de URLs únicas
Usando correctamente los verbos HTTP
RECURSO
RECURSO

Cualquier accion expuesta a travez de un servidor
web
RECURSO

Cualquier accion expuesta a travez de un servidor
web
Tienen una representación en datos
RECURSO

Cualquier accion expuesta a travez de un servidor
web
Tienen una representación en datos
Con un servicio web intercambiamos
representaciones de recursos
REST-ISH + JSON
REST-ISH + JSON

       =
REST-ISH + JSON

         =
  Cosas Increibles
¿PORQUÉ UN API?
¿PORQUÉ UN API?

Aumenta la flexibilidad y utilidad de tus
              aplicaciones
¿PORQUÉ UN API?

Aumenta la flexibilidad y utilidad de tus
              aplicaciones
     Proporciona valor de negocio
¿PORQUÉ UN API?

Aumenta la flexibilidad y utilidad de tus
              aplicaciones
     Proporciona valor de negocio
 Ayuda a comunicar aplicaciones entre ellas
¿QUÉ
CARACTERÍSTICAS?
¿QUÉ
CARACTERÍSTICAS?

 Fácil de implementar y mantener
¿QUÉ
CARACTERÍSTICAS?

 Fácil de implementar y mantener
 Buen rendimiento
¿QUÉ
CARACTERÍSTICAS?

 Fácil de implementar y mantener
 Buen rendimiento
 Escalable
¿CUÁLES SON LOS
    RETOS?
¿CUÁLES SON LOS
           RETOS?
La red es un eslabón débil, GEO localizacion de los
clientes
¿CUÁLES SON LOS
           RETOS?
La red es un eslabón débil, GEO localizacion de los
clientes
Administrar Cambios
¿CUÁLES SON LOS
           RETOS?
La red es un eslabón débil, GEO localizacion de los
clientes
Administrar Cambios
Uso indebido
¿CUÁLES SON LOS
           RETOS?
La red es un eslabón débil, GEO localizacion de los
clientes
Administrar Cambios
Uso indebido
Balanceo de trafico
¿CUÁLES SON LOS
           RETOS?
La red es un eslabón débil, GEO localizacion de los
clientes
Administrar Cambios
Uso indebido
Balanceo de trafico
Picos de uso
¿CUÁLES SON LOS
           RETOS?
La red es un eslabón débil, GEO localizacion de los
clientes
Administrar Cambios
Uso indebido
Balanceo de trafico
Picos de uso
Errores
DISEÑAR UNA BUENA
        API
CONVENCIONES REST
USAR CORRECTAMENTE
    VERBOS HTTP
REST + CRUD

                       GET /api/products #Listado
{"products" :
  [
    {"product" : { "id" : 1, "name" : "Producto 1", "status" : "archived"} },
    {"product" : { "id" : 2, "name" : "Producto 2", "status" : "active" } }
  ]
}
REST + CRUD

                         GET /api/products/2 #Ver


{"product" : { "id" : 2, "name" : "Producto 2", "status" : "active" } }
REST + CRUD

                       POST /api/products #Crear

{
    "name" : "Producto 2"
}
REST + CRUD
                  PUT /api/products/2 #Actualizar


{
    "name" : "Producto dos"
}
REST + CRUD
DELETE /api/products/2 #Eliminar
VERSIONES DE LA API

• API   Interna (entre aplicaciones)

• API   Externa (aplicacion movil ? )

• API   Usuarios (publico en general)
VERSIONANDO TU API

    /int/api/products
    /ext/api/products
    /pub/api/products
VERSIONANDO TU API

 /int/api/products?version=2
 /ext/api/products?version=2
 /pub/api/products?version=2
VERSIONANDO TU API

   /v2/int/api/products
   /v2/ext/api/products
   /v2/pub/api/products
VERSIONANDO TU API


http://int.myapp.com/products
http://api.myapp.com/products
MUNDO IDEAL
MUNDO IDEAL

Uso de: Accept Header
MUNDO IDEAL

Uso de: Accept Header


Accept: application/vnd.mycompany.com;version=2,application/json
CODIGOS HTTP
200 OK
201 Created
202 Accepted

400   Bad Request
401   Unauthorized
402   Payment Required
404   Not Found
409   Conflict
422   Unprocessable Entity

500 Internal Server Error
503 Service Unavailable
CODIGOS HTTP

HTTP/1.1 200 ok
GET /v1/products
{"products" :
  [
    {"product" : { "id" : 1, "name" : "Producto 1", "status" : "archived"} },
    {"product" : { "id" : 2, "name" : "Producto 2", "status" : "active" } }
  ]
}
CODIGOS HTTP
 HTTP/1.1 201 Created
 POST /v1/products
 {
   “product”: [
     “name” : “name”
   ]
 }
CODIGOS HTTP
HTTP/1.1 400 Bad Request

{
  “errors”: [
    “Estructura JSON no valida”,
    “unexpected TSTRING, expected ‘}’ at
line 2”
  ]
}
CODIGOS HTTP

HTTP/1.1 401 Unauthorized

{
    “errors”: [
      “api_key not found”
    ]
}
CODIGOS HTTP
HTTP/1.1 401 Unauthorized

{
  “errors”: [
    “api_key no valida”,
    “api_key no puede contener
espacios”
  ]
}
CODIGOS HTTP
HTTP/1.1 401 Unauthorized

{
  “errors”: [
    “api_key no encontrada, por favor
visita http://account.myapp.com/api para
obtenerla”
  ]
}
CODIGOS HTTP
HTTP/1.1 422 Unprocessable Entity

{
  “errors”: [
     “vendor_code: no puede estar vacio”
  ],
  “documentacion”: [
     “vendor_code”: [
        “descripcion” : “Codigo asignado por proveedor”,
        “formato” : “Combinacion de tres letras seguidas de 4
numeros”,
        “ejemplo” : “SOL1234”
      ]
  ]
}
CODIGOS HTTP
HTTP/1.1 500 Internal Server Error

{
    “exception”: [
      “Base de datos no disponible”
    ]
}
CODIGOS HTTP

HTTP/1.1 503 Service Unavailable

{
    “messages”: [
      “En mantenimiento”
    ]
}
OPCIONES AVANZADAS

• Simuladores

• Autenticación

• Validadores

• Limite   de uso

• Rapidez

• Balanceo
USANDO RUBY ON
     RAILS PARA
IMLEMENTAR UNA API
APIS ON RAILS - REST
#config/routes.rb
MyApp::Application.routes.draw do
  resources :products
end




$ rake routes
    products GET       /products(.:format)            products#index
              POST     /products(.:format)            products#create
 new_product GET       /products/new(.:format)        products#new
edit_product GET       /products/:id/edit(.:format)   products#edit
     product GET       /products/:id(.:format)        products#show
              PUT      /products/:id(.:format)        products#update
              DELETE   /products/:id(.:format)        products#destroy
APIS ON RAILS - REST
#config/routes.rb
MyApp::Application.routes.draw do
  scope ‘/api’ do
    resources :products
  end
end



    products GET      /api/products(.:format)            products#index
             POST     /api/products(.:format)            products#create
 new_product GET      /api/products/new(.:format)        products#new
edit_product GET      /api/products/:id/edit(.:format)   products#edit
     product GET      /api/products/:id(.:format)        products#show
             PUT      /api/products/:id(.:format)        products#update
             DELETE   /api/products/:id(.:format)        products#destroy
APIS ON RAILS -
                VERSIONES
gem 'versionist'
#config/routes.rb
MyApp::Application.routes.draw do
  api_version(:module => 'V1', :path => 'v2') do
    resources :products
  end
end



    v2_products GET      /v2/products(.:format)            V1/products#index
                POST     /v2/products(.:format)            V1/products#create
 new_v2_product GET      /v2/products/new(.:format)        V1/products#new
edit_v2_product GET      /v2/products/:id/edit(.:format)   V1/products#edit
     v2_product GET      /v2/products/:id(.:format)        V1/products#show
                PUT      /v2/products/:id(.:format)        V1/products#update
                DELETE   /v2/products/:id(.:format)        V1/products#destroy
APIS ON RAILS,
             CONTROLADOR
class V1::ProductsController < ApplicationController
  def index
    products = Product.paginate(:page => (params[:page] || 1),
                                 :per_page => (params[:per_page] || 100)).all
    render :json => products.to_json
  end
  def show
    product = Product.find(params[:id])
    render :json => product.to_json
  end
  def update
    product = Product.find(params[:id])
    product.update_attributes(params[:product])
    render :json => product.to_json
  end
  def destroy
    product = Product.find(params[:id])
    head product.destroy ? :ok : :unprocessable_entity
  end
end
APIS ON RAILS,
                CONTROLADOR
class ApplicationController < ActionController::Base
  rescue_from ActiveRecord::UnknownAttributeError, ArgumentError do |exception|
    respond_with_error(exception, 400)
  end
  rescue_from ActiveRecord::RecordNotFound do |exception|
    respond_with_error(exception, 404)
  end
  rescue_from ActiveRecord::RecordInvalid do |exception|
    respond_with_error(exception, 422, errors: exception.record.errors.messages)
  end
  rescue_from RuntimeError do |exception|
    respond_with_error(exception, 500)
  end

  private
  def respond_with_error(exception, code, errors = {})
    render json: {error: exception.class.to_s,
                  message: exception.to_s,
                  errors: errors},
           status: code
  end
end
APIS ON RAILS,
              CONTROLADOR
class V2::ProductsController < ApplicationController
  respond_to [:json, :xml, :html]
  def index
    @products = V2::Product.paginate(:page => (params[:page] || 1),
                                  :per_page => (params[:per_page] || 100)).all
    respond_with @products
  end
  def show
    @product = V2::Product.find(params[:id])
    respond_with @product
  end
  def update
    @product = V2::Product.find(params[:id])
    @product.update_attributes(params[:product])
    respond_with @product
  end
  def destroy
    @product = V2::Product.find(params[:id])
    respond_with @product.destroy
  end
end
APIS ON RAILS -
   MODELO
class V2::Product < Product

  JSON_ATTRIBUTES = {
    properties: [
       :id,
       :upc,
       :sku,
       :list_cost,
       :color,
       :dimension,
       :size,
       :created_at,
       :updated_at,
    ],
    methods: [
       :units_on_hand
    ]
  }

end
APIS ON RAILS,
             CONTROLADOR
gem ‘rabl’
class V3::ProductsController < ApplicationController
  respond_to [:json, :xml]
  def index
    @products = V3::Product.paginate(:page => (params[:page] || 1),
                                 :per_page => (params[:per_page] || 100)).all
  end
  def show
    @product = V3::Product.find(params[:id])
  end
  def update
    @product = V3::Product.find(params[:id])
    @product.update_attributes(params[:product])
  end
  def destroy
    @product = V3::Product.find(params[:id])
    render json: {}, status: @product.destroy ? :ok : :unprocessable_entity
  end
end
APIS ON RAILS
                           VISTAS
#app/views/api/v3/products/index.rabl

collection @products
attributes :id, :name, :status
node(:url) {|product| product_url(product) }
node(:current_stock) {|product| product.variants.map(&:on_hand).sum }
child :variants do
  attributes :upc, :color, :size, :on_hand
end




{"products" :
  [
    {"product" : { "id" : 1, "name" : "Producto 1", "status" : "archived", “current_stock” : 10,
      “variants” : [ {“upc” : “ASDFS”, “color” : “negro”, “size” : “M”, “on_hand” : 10} ]
      }
    }
  ]
}
APIS ON RAILS
                 VISTAS
gem ‘jbuilder’
Jbuilder.encode do |json|
  json.content format_content(@message.content)
  json.(@message, :created_at, :updated_at)

  json.author do |json|
    json.name @message.creator.name.familiar
    json.email_address @message.creator.email_address_with_name
    json.url url_for(@message.creator, format: :json)
  end

  if current_user.admin?
    json.visitors calculate_visitors(@message)
  end

  json.comments @message.comments, :content, :created_at

end
APIS ON RAILS
                 VISTAS

gem ‘active_model_serializer’
class PostSerializer < ActiveModel::Serializer
  attributes :id, :body
  attribute :title, :key => :name

  has_many :comments

  def tags
    tags.order :name
  end
end
APIS ON RAILS
           SEGURIDAD
Devise
Autenticacion Flexible para aplicaciones Rails
Compuesta de 12 modulos: database authenticable,
token authenticable, omniauthable, confirmable,
recoverable, registerable, trackable, timeoutable,
validatable, lockable
APIS ON RAILS
           SEGURIDAD
Devise
Autenticacion Flexible para aplicaciones Rails
Compuesta de 12 modulos: database authenticable,
token authenticable, omniauthable, confirmable,
recoverable, registerable, trackable, timeoutable,
validatable, lockable
APIS ON RAILS
                 SEGURIDAD
gem ‘rabl’
class V3::ProductsController < ApplicationController
  before_filter :authenticate_user!
  respond_to :json, :xml
  def index
    @products = V3::Product.paginate(:page => (params[:page] || 1),
                                 :per_page => (params[:per_page] || 100)).all
  end
  def show
    @product = V3::Product.find(params[:id])
  end
  def update
    @product = V3::Product.find(params[:id])
    @product.update_attributes(params[:product])
  end
  def destroy
    @product = V3::Product.find(params[:id])
    render json: {}, status: @product.destroy ? :ok : :unprocessable_entity
  end
end
ESCRIBIENDO PRUEBAS
APIS ON RAILS
                  PRUEBAS
describe V3::ProductsController do

  before do
    @request.env["HTTP_ACCEPT"] = "application/json"
  end

  describe "#index" do
    context "cuando no se pasa ningun atributo" do
      it "regresa los registros en paginas" do
        get :index
        response.should be_success
        data = JSON.parse(response.body)
        Product.count.should > 0
        data['products'].length.should == Product.count
      end
    end
  end
end
APIS ON RAILS
                   PRUEBAS
describe V3::ProductsController do

  before do
    @request.env["HTTP_ACCEPT"] = "application/json"
  end

  describe "#show" do
    context "pasando un id inexistente" do
      it "responde con http 404 y un mensaje de error" do
        get :show, id: -1
        response.code.should == "404"
        json_response = JSON.parse(response.body)
        json_response['error'].should == "ActiveRecord::RecordNotFound"
        json_response['message'].should == "Couldn't find Product with id=-1"
      end
    end
  end
end
APIS ON RAILS
                   PRUEBAS
describe V3::ProductsController do

  before do
    @request.env["HTTP_ACCEPT"] = "application/json"
  end

  describe "#create" do
    context "con malos atributos" do
      it "responde con un error" do
        post :create, product: {bad_key: "foo"}
        response.code.should == "400"
        json_response = JSON.parse(response.body)
        json_response['error'].should == "ActiveRecord::UnknownAttributeError"
        json_response['message'].should == "unknown attribute: bad_key"
      end
    end
  end
end
APIS ON RAILS
                   PRUEBAS
describe V3::ProductsController do

  before do
    @request.env["HTTP_ACCEPT"] = "application/json"
  end

  describe "#create" do
    context "con atributos correctos" do
      it "responde correctamente y crea el producto" do
        expect {
          post :create, product: {name: "productito"}
        }.to change(Product, :count).by(1)
      end
    end
  end
end
ROR, DEMACIADO PARA
       LAS API?

• Helpers

• Vistas

• Administracion   de assets

• Generadores   de html

• Template   engines
<Module:0x007ff271221e40>,
 ActionDispatch::Routing::Helpers,
 #<Module:0x007ff2714ad268>,
 ActionController::Base,
 ActionDispatch::Routing::RouteSet::MountedHelpers,
 HasScope,
 ActionController::Compatibility,
 ActionController::ParamsWrapper,
 ActionController::Instrumentation,
 ActionController::Rescue,
 ActiveSupport::Rescuable,
 ActionController::HttpAuthentication::Token::ControllerMethods,
 ActionController::HttpAuthentication::Digest::ControllerMethods,
 ActionController::HttpAuthentication::Basic::ControllerMethods,
 ActionController::RecordIdentifier,
 ActionController::DataStreaming,
 ActionController::Streaming,
 ActionController::ForceSSL,
 ActionController::RequestForgeryProtection,
 AbstractController::Callbacks,
 ActiveSupport::Callbacks,
 ActionController::Flash,
 ActionController::Cookies,
 ActionController::MimeResponds,
 ActionController::ImplicitRender,
 ActionController::Caching,
 ActionController::Caching::Fragments,
 ActionController::Caching::ConfigMethods,
 ActionController::Caching::Pages,
 ActionController::Caching::Actions,
 ActionController::ConditionalGet,
 ActionController::Head,
 ActionController::Renderers::All,
 ActionController::Renderers,
 ActionController::Rendering,
 ActionController::Redirecting,
 ActionController::RackDelegation,
 ActiveSupport::Benchmarkable,
 AbstractController::Logger,
 ActionController::UrlFor,
 AbstractController::UrlFor,
 ActionDispatch::Routing::UrlFor,
 ActionDispatch::Routing::PolymorphicRoutes,
 ActionController::HideActions,
 ActionController::Helpers,
 AbstractController::Helpers,
 AbstractController::AssetPaths,
 AbstractController::Translation,
 AbstractController::Layouts,
 AbstractController::Rendering,
 AbstractController::ViewPaths,
 ActionController::Metal,
 AbstractController::Base,
 ActiveSupport::Configurable,
 Object,
 ActiveSupport::Dependencies::Loadable,
 JSON::Ext::Generator::GeneratorMethods::Object,
 PP::ObjectMixin,
 Kernel,
 BasicObject
<Module:0x007ff271221e40>,
 ActionDispatch::Routing::Helpers,
 #<Module:0x007ff2714ad268>,
 ActionController::Base,
 ActionDispatch::Routing::RouteSet::MountedHelpers,
 HasScope,
 ActionController::Compatibility,
 ActionController::ParamsWrapper,
 ActionController::Instrumentation,
 ActionController::Rescue,
 ActiveSupport::Rescuable,
 ActionController::HttpAuthentication::Token::ControllerMethods,
 ActionController::HttpAuthentication::Digest::ControllerMethods,   #<Module:0x007f9211d5cd70>,
 ActionController::HttpAuthentication::Basic::ControllerMethods,     ActionDispatch::Routing::Helpers,
 ActionController::RecordIdentifier,                                 #<Module:0x007f9211f7b5e8>,
 ActionController::DataStreaming,                                    ActionController::API,
 ActionController::Streaming,                                        ActiveRecord::Railties::ControllerRuntime,
 ActionController::ForceSSL,                                         ActionDispatch::Routing::RouteSet::MountedHelpers,
 ActionController::RequestForgeryProtection,                         ActionController::Instrumentation,
 AbstractController::Callbacks,                                      ActionController::Rescue,
 ActiveSupport::Callbacks,                                           ActiveSupport::Rescuable,
 ActionController::Flash,                                            ActionController::DataStreaming,
 ActionController::Cookies,                                          ActionController::ForceSSL,
 ActionController::MimeResponds,                                     AbstractController::Callbacks,
 ActionController::ImplicitRender,                                   ActiveSupport::Callbacks,
 ActionController::Caching,                                          ActionController::ConditionalGet,
 ActionController::Caching::Fragments,                               ActionController::Head,
 ActionController::Caching::ConfigMethods,                           ActionController::Renderers::All,
 ActionController::Caching::Pages,                                   ActionController::Renderers,
 ActionController::Caching::Actions,                                 ActionController::Rendering,
 ActionController::ConditionalGet,                                   AbstractController::Rendering,
 ActionController::Head,                                             AbstractController::ViewPaths,
 ActionController::Renderers::All,                                   ActionController::Redirecting,
 ActionController::Renderers,                                        ActionController::RackDelegation,
 ActionController::Rendering,                                        ActiveSupport::Benchmarkable,
 ActionController::Redirecting,                                      AbstractController::Logger,
 ActionController::RackDelegation,                                   ActionController::UrlFor,
 ActiveSupport::Benchmarkable,                                       AbstractController::UrlFor,
 AbstractController::Logger,                                         ActionDispatch::Routing::UrlFor,
 ActionController::UrlFor,                                           ActionDispatch::Routing::PolymorphicRoutes,
 AbstractController::UrlFor,                                         ActionController::HideActions,
 ActionDispatch::Routing::UrlFor,                                    ActionController::Metal,
 ActionDispatch::Routing::PolymorphicRoutes,                         AbstractController::Base,
 ActionController::HideActions,                                      ActiveSupport::Configurable,
 ActionController::Helpers,                                          Object,
 AbstractController::Helpers,                                        JSON::Ext::Generator::GeneratorMethods::Object,
 AbstractController::AssetPaths,                                     ActiveSupport::Dependencies::Loadable,
 AbstractController::Translation,                                    PP::ObjectMixin,
 AbstractController::Layouts,                                        Kernel,
 AbstractController::Rendering,                                      BasicObject
 AbstractController::ViewPaths,
 ActionController::Metal,
 AbstractController::Base,
 ActiveSupport::Configurable,
 Object,
 ActiveSupport::Dependencies::Loadable,
 JSON::Ext::Generator::GeneratorMethods::Object,
 PP::ObjectMixin,
 Kernel,
 BasicObject
RAILS A DIETA
RAILS A DIETA
  Rails es modular
RAILS A DIETA
              Rails es modular
Para crear APIs, algunos Middlewares no son
                    necesarios
RAILS A DIETA
              Rails es modular
Para crear APIs, algunos Middlewares no son
                    necesarios

                rails-api
use ActionDispatch::Static
use Rack::Lock
use
#<ActiveSupport::Cache::Strategy::Loc
alCache::Middleware:0x007fd3b32928c0>
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActionDispatch::Cookies
use
ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use ActionDispatch::ParamsParser
use ActionDispatch::Head
use Rack::ConditionalGet
use Rack::ETag
use
ActionDispatch::BestStandardsSupport
use
use ActionDispatch::Static
use Rack::Lock
use                                     use ActionDispatch::Static
#<ActiveSupport::Cache::Strategy::Loc   use Rack::Lock
alCache::Middleware:0x007fd3b32928c0>   use
use Rack::Runtime                       #<ActiveSupport::Cache::Strategy::LocalCac
use Rack::MethodOverride                he::Middleware:0x007fe74448cf50>
use ActionDispatch::RequestId           use Rack::Runtime
use Rails::Rack::Logger                 use ActionDispatch::RequestId
use ActionDispatch::ShowExceptions      use Rails::Rack::Logger
use ActionDispatch::DebugExceptions     use ActionDispatch::ShowExceptions
use ActionDispatch::RemoteIp            use ActionDispatch::DebugExceptions
use ActionDispatch::Reloader            use ActionDispatch::RemoteIp
use ActionDispatch::Callbacks           use ActionDispatch::Reloader
use ActionDispatch::Cookies             use ActionDispatch::Callbacks
use                                     use
ActionDispatch::Session::CookieStore    ActiveRecord::ConnectionAdapters::Connecti
use ActionDispatch::Flash               onManagement
use ActionDispatch::ParamsParser        use ActiveRecord::QueryCache
use ActionDispatch::Head                use ActionDispatch::ParamsParser
use Rack::ConditionalGet                use ActionDispatch::Head
use Rack::ETag                          use Rack::ConditionalGet
use                                     use Rack::ETag
ActionDispatch::BestStandardsSupport
use
RAILS-API?

• ActiveRecord    (manejo de errores)

• Validaciones   (responder a varios formatos)

• Controladores, sistema   de rutas (versionamiento)

• Muchas   librerias(Gems)

• Autenticación   (oauth, token, basic auth)

• Mismos   web servers confiables (mismo hosting)
RAILS-API?


• REST

• CRUD
CONCLUSION
CONCLUSION


Rails es perfecto para API’s!
Gracias!

Preguntas?
              Edwin Cruz
      edwin@crowdint.com
                 @softr8

Weitere ähnliche Inhalte

Ähnlich wie Api development with rails

Continuous Integration and Deployment Best Practices on AWS
Continuous Integration and Deployment Best Practices on AWSContinuous Integration and Deployment Best Practices on AWS
Continuous Integration and Deployment Best Practices on AWSDanilo Poccia
 
Building Mobile Friendly APIs in Rails
Building Mobile Friendly APIs in RailsBuilding Mobile Friendly APIs in Rails
Building Mobile Friendly APIs in RailsJim Jeffers
 
REST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in CodeigniterREST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in CodeigniterSachin G Kulkarni
 
API Workshop: Deep dive into REST APIs
API Workshop: Deep dive into REST APIsAPI Workshop: Deep dive into REST APIs
API Workshop: Deep dive into REST APIsTom Johnson
 
Building Awesome APIs in Grails
Building Awesome APIs in GrailsBuilding Awesome APIs in Grails
Building Awesome APIs in Grailsclatimer
 
Google Cloud Endpointsによる API構築
Google Cloud Endpointsによる API構築Google Cloud Endpointsによる API構築
Google Cloud Endpointsによる API構築Keiji Ariyama
 
Developing Apps with Azure AD
Developing Apps with Azure ADDeveloping Apps with Azure AD
Developing Apps with Azure ADSharePointRadi
 
Creating Rich Server API’s for your Mobile Apps - Best Practices and Guidelines
Creating Rich Server API’s for your Mobile Apps - Best Practices and GuidelinesCreating Rich Server API’s for your Mobile Apps - Best Practices and Guidelines
Creating Rich Server API’s for your Mobile Apps - Best Practices and GuidelinesJonathan Guthrie
 
APIs REST Usables con Hypermedia por Javier Ramirez, para codemotion
APIs REST Usables con Hypermedia por Javier Ramirez, para codemotionAPIs REST Usables con Hypermedia por Javier Ramirez, para codemotion
APIs REST Usables con Hypermedia por Javier Ramirez, para codemotionjavier ramirez
 
Managing the Continuous Delivery of Code to AWS Lambda
Managing the Continuous Delivery of Code to AWS LambdaManaging the Continuous Delivery of Code to AWS Lambda
Managing the Continuous Delivery of Code to AWS LambdaAmazon Web Services
 
Creating a World-Class RESTful Web Services API
Creating a World-Class RESTful Web Services APICreating a World-Class RESTful Web Services API
Creating a World-Class RESTful Web Services APIDavid Keener
 
All Things API Presentation - Gordon Weakleim [HomeAway]
All Things API Presentation - Gordon Weakleim [HomeAway]All Things API Presentation - Gordon Weakleim [HomeAway]
All Things API Presentation - Gordon Weakleim [HomeAway]Cloud Elements
 
Araport Workshop Tutorial 2: Authentication and the Agave Profiles Service
Araport Workshop Tutorial 2: Authentication and the Agave Profiles ServiceAraport Workshop Tutorial 2: Authentication and the Agave Profiles Service
Araport Workshop Tutorial 2: Authentication and the Agave Profiles Servicestevemock
 
Api's and ember js
Api's and ember jsApi's and ember js
Api's and ember jsEdwin Cruz
 
AWS July Webinar Series: Overview: Build and Manage your APIs with Amazon API...
AWS July Webinar Series: Overview: Build and Manage your APIs with Amazon API...AWS July Webinar Series: Overview: Build and Manage your APIs with Amazon API...
AWS July Webinar Series: Overview: Build and Manage your APIs with Amazon API...Amazon Web Services
 
AWS July Webinar Series - Overview Build and Manage your APs with amazon api ...
AWS July Webinar Series - Overview Build and Manage your APs with amazon api ...AWS July Webinar Series - Overview Build and Manage your APs with amazon api ...
AWS July Webinar Series - Overview Build and Manage your APs with amazon api ...Amazon Web Services
 
Azure API Management - why should I care?
Azure API Management - why should I care?Azure API Management - why should I care?
Azure API Management - why should I care?Jouni Heikniemi
 
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram VaswaniCreating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswanivvaswani
 

Ähnlich wie Api development with rails (20)

Continuous Integration and Deployment Best Practices on AWS
Continuous Integration and Deployment Best Practices on AWSContinuous Integration and Deployment Best Practices on AWS
Continuous Integration and Deployment Best Practices on AWS
 
Building Mobile Friendly APIs in Rails
Building Mobile Friendly APIs in RailsBuilding Mobile Friendly APIs in Rails
Building Mobile Friendly APIs in Rails
 
REST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in CodeigniterREST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in Codeigniter
 
API Workshop: Deep dive into REST APIs
API Workshop: Deep dive into REST APIsAPI Workshop: Deep dive into REST APIs
API Workshop: Deep dive into REST APIs
 
Building Awesome APIs in Grails
Building Awesome APIs in GrailsBuilding Awesome APIs in Grails
Building Awesome APIs in Grails
 
Google Cloud Endpointsによる API構築
Google Cloud Endpointsによる API構築Google Cloud Endpointsによる API構築
Google Cloud Endpointsによる API構築
 
Developing Apps with Azure AD
Developing Apps with Azure ADDeveloping Apps with Azure AD
Developing Apps with Azure AD
 
Creating Rich Server API’s for your Mobile Apps - Best Practices and Guidelines
Creating Rich Server API’s for your Mobile Apps - Best Practices and GuidelinesCreating Rich Server API’s for your Mobile Apps - Best Practices and Guidelines
Creating Rich Server API’s for your Mobile Apps - Best Practices and Guidelines
 
Don't screw it up! How to build durable API
Don't screw it up! How to build durable API Don't screw it up! How to build durable API
Don't screw it up! How to build durable API
 
APIs REST Usables con Hypermedia por Javier Ramirez, para codemotion
APIs REST Usables con Hypermedia por Javier Ramirez, para codemotionAPIs REST Usables con Hypermedia por Javier Ramirez, para codemotion
APIs REST Usables con Hypermedia por Javier Ramirez, para codemotion
 
Managing the Continuous Delivery of Code to AWS Lambda
Managing the Continuous Delivery of Code to AWS LambdaManaging the Continuous Delivery of Code to AWS Lambda
Managing the Continuous Delivery of Code to AWS Lambda
 
Creating a World-Class RESTful Web Services API
Creating a World-Class RESTful Web Services APICreating a World-Class RESTful Web Services API
Creating a World-Class RESTful Web Services API
 
All Things API Presentation - Gordon Weakleim [HomeAway]
All Things API Presentation - Gordon Weakleim [HomeAway]All Things API Presentation - Gordon Weakleim [HomeAway]
All Things API Presentation - Gordon Weakleim [HomeAway]
 
Araport Workshop Tutorial 2: Authentication and the Agave Profiles Service
Araport Workshop Tutorial 2: Authentication and the Agave Profiles ServiceAraport Workshop Tutorial 2: Authentication and the Agave Profiles Service
Araport Workshop Tutorial 2: Authentication and the Agave Profiles Service
 
Api's and ember js
Api's and ember jsApi's and ember js
Api's and ember js
 
Web API with ASP.NET MVC by Software development company in india
Web API with ASP.NET  MVC  by Software development company in indiaWeb API with ASP.NET  MVC  by Software development company in india
Web API with ASP.NET MVC by Software development company in india
 
AWS July Webinar Series: Overview: Build and Manage your APIs with Amazon API...
AWS July Webinar Series: Overview: Build and Manage your APIs with Amazon API...AWS July Webinar Series: Overview: Build and Manage your APIs with Amazon API...
AWS July Webinar Series: Overview: Build and Manage your APIs with Amazon API...
 
AWS July Webinar Series - Overview Build and Manage your APs with amazon api ...
AWS July Webinar Series - Overview Build and Manage your APs with amazon api ...AWS July Webinar Series - Overview Build and Manage your APs with amazon api ...
AWS July Webinar Series - Overview Build and Manage your APs with amazon api ...
 
Azure API Management - why should I care?
Azure API Management - why should I care?Azure API Management - why should I care?
Azure API Management - why should I care?
 
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram VaswaniCreating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
 

Mehr von Edwin Cruz

Codigo Escalable WDT
Codigo Escalable WDTCodigo Escalable WDT
Codigo Escalable WDTEdwin Cruz
 
SGCE 2015 - eCommerce platforms
SGCE 2015 - eCommerce platformsSGCE 2015 - eCommerce platforms
SGCE 2015 - eCommerce platformsEdwin Cruz
 
Devops with ansible
Devops with ansibleDevops with ansible
Devops with ansibleEdwin Cruz
 
Containers in 5... 9 minutes
Containers in 5... 9 minutesContainers in 5... 9 minutes
Containers in 5... 9 minutesEdwin Cruz
 
Chilango Rails Ecommerce Lightning talk
Chilango Rails Ecommerce Lightning talkChilango Rails Ecommerce Lightning talk
Chilango Rails Ecommerce Lightning talkEdwin Cruz
 
Home made ceviche
Home made cevicheHome made ceviche
Home made cevicheEdwin Cruz
 
FSL Vallarta, mejorando el rendimiento de las aplicaciones web
FSL Vallarta, mejorando el rendimiento de las aplicaciones webFSL Vallarta, mejorando el rendimiento de las aplicaciones web
FSL Vallarta, mejorando el rendimiento de las aplicaciones webEdwin Cruz
 
Presentacion Programador Apasionado
Presentacion Programador ApasionadoPresentacion Programador Apasionado
Presentacion Programador ApasionadoEdwin Cruz
 
MagmaRails - Passionate Programmer
MagmaRails - Passionate ProgrammerMagmaRails - Passionate Programmer
MagmaRails - Passionate ProgrammerEdwin Cruz
 
Presentacion programador apasionado
Presentacion programador apasionadoPresentacion programador apasionado
Presentacion programador apasionadoEdwin Cruz
 
Migrando Rails Apps entre Cloud y Bare Metal Servers
Migrando Rails Apps entre Cloud y Bare Metal ServersMigrando Rails Apps entre Cloud y Bare Metal Servers
Migrando Rails Apps entre Cloud y Bare Metal ServersEdwin Cruz
 

Mehr von Edwin Cruz (11)

Codigo Escalable WDT
Codigo Escalable WDTCodigo Escalable WDT
Codigo Escalable WDT
 
SGCE 2015 - eCommerce platforms
SGCE 2015 - eCommerce platformsSGCE 2015 - eCommerce platforms
SGCE 2015 - eCommerce platforms
 
Devops with ansible
Devops with ansibleDevops with ansible
Devops with ansible
 
Containers in 5... 9 minutes
Containers in 5... 9 minutesContainers in 5... 9 minutes
Containers in 5... 9 minutes
 
Chilango Rails Ecommerce Lightning talk
Chilango Rails Ecommerce Lightning talkChilango Rails Ecommerce Lightning talk
Chilango Rails Ecommerce Lightning talk
 
Home made ceviche
Home made cevicheHome made ceviche
Home made ceviche
 
FSL Vallarta, mejorando el rendimiento de las aplicaciones web
FSL Vallarta, mejorando el rendimiento de las aplicaciones webFSL Vallarta, mejorando el rendimiento de las aplicaciones web
FSL Vallarta, mejorando el rendimiento de las aplicaciones web
 
Presentacion Programador Apasionado
Presentacion Programador ApasionadoPresentacion Programador Apasionado
Presentacion Programador Apasionado
 
MagmaRails - Passionate Programmer
MagmaRails - Passionate ProgrammerMagmaRails - Passionate Programmer
MagmaRails - Passionate Programmer
 
Presentacion programador apasionado
Presentacion programador apasionadoPresentacion programador apasionado
Presentacion programador apasionado
 
Migrando Rails Apps entre Cloud y Bare Metal Servers
Migrando Rails Apps entre Cloud y Bare Metal ServersMigrando Rails Apps entre Cloud y Bare Metal Servers
Migrando Rails Apps entre Cloud y Bare Metal Servers
 

Kürzlich hochgeladen

Accelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessAccelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessWSO2
 
Kuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorialKuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorialJoão Esperancinha
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFMichael Gough
 
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sectoritnewsafrica
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Jeffrey Haguewood
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Karmanjay Verma
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxAna-Maria Mihalceanu
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Mark Simos
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...Karmanjay Verma
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observabilityitnewsafrica
 

Kürzlich hochgeladen (20)

Accelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessAccelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with Platformless
 
Kuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorialKuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorial
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDF
 
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance Toolbox
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
 

Api development with rails

  • 1. Diseño de APIs con Ruby Edwin Cruz @softr8
  • 2. PLAN • Que es una API • Como implementar una buena API • Usando Ruby on Rails para implementar una API • Patrones de diseño
  • 3. Application Programming Interface “
  • 4. API Es una manera para comunicar dos aplicaciones entre ellas.
  • 5. TIPOS DE API • Library • SDK • Web services
  • 6. PRIMERAS API - SOAP Simple Object Access Protocol
  • 9. REQUISITOS REST Separación de responsabilidades
  • 10. REQUISITOS REST Separación de responsabilidades Cliente/Servidor
  • 11. REQUISITOS REST Separación de responsabilidades Cliente/Servidor Sin estado
  • 12. REQUISITOS REST Separación de responsabilidades Cliente/Servidor Sin estado Puede ser “Cacheable”
  • 13. REQUISITOS REST Separación de responsabilidades Cliente/Servidor Sin estado Puede ser “Cacheable” Sistema a capas
  • 14. REQUISITOS REST Separación de responsabilidades Cliente/Servidor Sin estado Puede ser “Cacheable” Sistema a capas Interface uniforme
  • 15. CRUD Create Altas Read Bajas Update Cambios Delete Consultas
  • 17. REST + CRUD Recursos a través de URLs únicas Usando correctamente los verbos HTTP
  • 19. RECURSO Cualquier accion expuesta a travez de un servidor web
  • 20. RECURSO Cualquier accion expuesta a travez de un servidor web Tienen una representación en datos
  • 21. RECURSO Cualquier accion expuesta a travez de un servidor web Tienen una representación en datos Con un servicio web intercambiamos representaciones de recursos
  • 24. REST-ISH + JSON = Cosas Increibles
  • 26. ¿PORQUÉ UN API? Aumenta la flexibilidad y utilidad de tus aplicaciones
  • 27. ¿PORQUÉ UN API? Aumenta la flexibilidad y utilidad de tus aplicaciones Proporciona valor de negocio
  • 28. ¿PORQUÉ UN API? Aumenta la flexibilidad y utilidad de tus aplicaciones Proporciona valor de negocio Ayuda a comunicar aplicaciones entre ellas
  • 30. ¿QUÉ CARACTERÍSTICAS? Fácil de implementar y mantener
  • 31. ¿QUÉ CARACTERÍSTICAS? Fácil de implementar y mantener Buen rendimiento
  • 32. ¿QUÉ CARACTERÍSTICAS? Fácil de implementar y mantener Buen rendimiento Escalable
  • 34. ¿CUÁLES SON LOS RETOS? La red es un eslabón débil, GEO localizacion de los clientes
  • 35. ¿CUÁLES SON LOS RETOS? La red es un eslabón débil, GEO localizacion de los clientes Administrar Cambios
  • 36. ¿CUÁLES SON LOS RETOS? La red es un eslabón débil, GEO localizacion de los clientes Administrar Cambios Uso indebido
  • 37. ¿CUÁLES SON LOS RETOS? La red es un eslabón débil, GEO localizacion de los clientes Administrar Cambios Uso indebido Balanceo de trafico
  • 38. ¿CUÁLES SON LOS RETOS? La red es un eslabón débil, GEO localizacion de los clientes Administrar Cambios Uso indebido Balanceo de trafico Picos de uso
  • 39. ¿CUÁLES SON LOS RETOS? La red es un eslabón débil, GEO localizacion de los clientes Administrar Cambios Uso indebido Balanceo de trafico Picos de uso Errores
  • 42. USAR CORRECTAMENTE VERBOS HTTP
  • 43. REST + CRUD GET /api/products #Listado {"products" : [ {"product" : { "id" : 1, "name" : "Producto 1", "status" : "archived"} }, {"product" : { "id" : 2, "name" : "Producto 2", "status" : "active" } } ] }
  • 44. REST + CRUD GET /api/products/2 #Ver {"product" : { "id" : 2, "name" : "Producto 2", "status" : "active" } }
  • 45. REST + CRUD POST /api/products #Crear { "name" : "Producto 2" }
  • 46. REST + CRUD PUT /api/products/2 #Actualizar { "name" : "Producto dos" }
  • 47. REST + CRUD DELETE /api/products/2 #Eliminar
  • 48. VERSIONES DE LA API • API Interna (entre aplicaciones) • API Externa (aplicacion movil ? ) • API Usuarios (publico en general)
  • 49. VERSIONANDO TU API /int/api/products /ext/api/products /pub/api/products
  • 50. VERSIONANDO TU API /int/api/products?version=2 /ext/api/products?version=2 /pub/api/products?version=2
  • 51. VERSIONANDO TU API /v2/int/api/products /v2/ext/api/products /v2/pub/api/products
  • 54. MUNDO IDEAL Uso de: Accept Header
  • 55. MUNDO IDEAL Uso de: Accept Header Accept: application/vnd.mycompany.com;version=2,application/json
  • 56. CODIGOS HTTP 200 OK 201 Created 202 Accepted 400 Bad Request 401 Unauthorized 402 Payment Required 404 Not Found 409 Conflict 422 Unprocessable Entity 500 Internal Server Error 503 Service Unavailable
  • 57. CODIGOS HTTP HTTP/1.1 200 ok GET /v1/products {"products" : [ {"product" : { "id" : 1, "name" : "Producto 1", "status" : "archived"} }, {"product" : { "id" : 2, "name" : "Producto 2", "status" : "active" } } ] }
  • 58. CODIGOS HTTP HTTP/1.1 201 Created POST /v1/products { “product”: [ “name” : “name” ] }
  • 59. CODIGOS HTTP HTTP/1.1 400 Bad Request { “errors”: [ “Estructura JSON no valida”, “unexpected TSTRING, expected ‘}’ at line 2” ] }
  • 60. CODIGOS HTTP HTTP/1.1 401 Unauthorized { “errors”: [ “api_key not found” ] }
  • 61. CODIGOS HTTP HTTP/1.1 401 Unauthorized { “errors”: [ “api_key no valida”, “api_key no puede contener espacios” ] }
  • 62. CODIGOS HTTP HTTP/1.1 401 Unauthorized { “errors”: [ “api_key no encontrada, por favor visita http://account.myapp.com/api para obtenerla” ] }
  • 63. CODIGOS HTTP HTTP/1.1 422 Unprocessable Entity { “errors”: [ “vendor_code: no puede estar vacio” ], “documentacion”: [ “vendor_code”: [ “descripcion” : “Codigo asignado por proveedor”, “formato” : “Combinacion de tres letras seguidas de 4 numeros”, “ejemplo” : “SOL1234” ] ] }
  • 64. CODIGOS HTTP HTTP/1.1 500 Internal Server Error { “exception”: [ “Base de datos no disponible” ] }
  • 65. CODIGOS HTTP HTTP/1.1 503 Service Unavailable { “messages”: [ “En mantenimiento” ] }
  • 66. OPCIONES AVANZADAS • Simuladores • Autenticación • Validadores • Limite de uso • Rapidez • Balanceo
  • 67. USANDO RUBY ON RAILS PARA IMLEMENTAR UNA API
  • 68. APIS ON RAILS - REST #config/routes.rb MyApp::Application.routes.draw do resources :products end $ rake routes products GET /products(.:format) products#index POST /products(.:format) products#create new_product GET /products/new(.:format) products#new edit_product GET /products/:id/edit(.:format) products#edit product GET /products/:id(.:format) products#show PUT /products/:id(.:format) products#update DELETE /products/:id(.:format) products#destroy
  • 69. APIS ON RAILS - REST #config/routes.rb MyApp::Application.routes.draw do scope ‘/api’ do resources :products end end products GET /api/products(.:format) products#index POST /api/products(.:format) products#create new_product GET /api/products/new(.:format) products#new edit_product GET /api/products/:id/edit(.:format) products#edit product GET /api/products/:id(.:format) products#show PUT /api/products/:id(.:format) products#update DELETE /api/products/:id(.:format) products#destroy
  • 70. APIS ON RAILS - VERSIONES gem 'versionist' #config/routes.rb MyApp::Application.routes.draw do api_version(:module => 'V1', :path => 'v2') do resources :products end end v2_products GET /v2/products(.:format) V1/products#index POST /v2/products(.:format) V1/products#create new_v2_product GET /v2/products/new(.:format) V1/products#new edit_v2_product GET /v2/products/:id/edit(.:format) V1/products#edit v2_product GET /v2/products/:id(.:format) V1/products#show PUT /v2/products/:id(.:format) V1/products#update DELETE /v2/products/:id(.:format) V1/products#destroy
  • 71. APIS ON RAILS, CONTROLADOR class V1::ProductsController < ApplicationController def index products = Product.paginate(:page => (params[:page] || 1), :per_page => (params[:per_page] || 100)).all render :json => products.to_json end def show product = Product.find(params[:id]) render :json => product.to_json end def update product = Product.find(params[:id]) product.update_attributes(params[:product]) render :json => product.to_json end def destroy product = Product.find(params[:id]) head product.destroy ? :ok : :unprocessable_entity end end
  • 72. APIS ON RAILS, CONTROLADOR class ApplicationController < ActionController::Base rescue_from ActiveRecord::UnknownAttributeError, ArgumentError do |exception| respond_with_error(exception, 400) end rescue_from ActiveRecord::RecordNotFound do |exception| respond_with_error(exception, 404) end rescue_from ActiveRecord::RecordInvalid do |exception| respond_with_error(exception, 422, errors: exception.record.errors.messages) end rescue_from RuntimeError do |exception| respond_with_error(exception, 500) end private def respond_with_error(exception, code, errors = {}) render json: {error: exception.class.to_s, message: exception.to_s, errors: errors}, status: code end end
  • 73. APIS ON RAILS, CONTROLADOR class V2::ProductsController < ApplicationController respond_to [:json, :xml, :html] def index @products = V2::Product.paginate(:page => (params[:page] || 1), :per_page => (params[:per_page] || 100)).all respond_with @products end def show @product = V2::Product.find(params[:id]) respond_with @product end def update @product = V2::Product.find(params[:id]) @product.update_attributes(params[:product]) respond_with @product end def destroy @product = V2::Product.find(params[:id]) respond_with @product.destroy end end
  • 74. APIS ON RAILS - MODELO class V2::Product < Product JSON_ATTRIBUTES = { properties: [ :id, :upc, :sku, :list_cost, :color, :dimension, :size, :created_at, :updated_at, ], methods: [ :units_on_hand ] } end
  • 75. APIS ON RAILS, CONTROLADOR gem ‘rabl’ class V3::ProductsController < ApplicationController respond_to [:json, :xml] def index @products = V3::Product.paginate(:page => (params[:page] || 1), :per_page => (params[:per_page] || 100)).all end def show @product = V3::Product.find(params[:id]) end def update @product = V3::Product.find(params[:id]) @product.update_attributes(params[:product]) end def destroy @product = V3::Product.find(params[:id]) render json: {}, status: @product.destroy ? :ok : :unprocessable_entity end end
  • 76. APIS ON RAILS VISTAS #app/views/api/v3/products/index.rabl collection @products attributes :id, :name, :status node(:url) {|product| product_url(product) } node(:current_stock) {|product| product.variants.map(&:on_hand).sum } child :variants do attributes :upc, :color, :size, :on_hand end {"products" : [ {"product" : { "id" : 1, "name" : "Producto 1", "status" : "archived", “current_stock” : 10, “variants” : [ {“upc” : “ASDFS”, “color” : “negro”, “size” : “M”, “on_hand” : 10} ] } } ] }
  • 77. APIS ON RAILS VISTAS gem ‘jbuilder’ Jbuilder.encode do |json| json.content format_content(@message.content) json.(@message, :created_at, :updated_at) json.author do |json| json.name @message.creator.name.familiar json.email_address @message.creator.email_address_with_name json.url url_for(@message.creator, format: :json) end if current_user.admin? json.visitors calculate_visitors(@message) end json.comments @message.comments, :content, :created_at end
  • 78. APIS ON RAILS VISTAS gem ‘active_model_serializer’ class PostSerializer < ActiveModel::Serializer attributes :id, :body attribute :title, :key => :name has_many :comments def tags tags.order :name end end
  • 79. APIS ON RAILS SEGURIDAD Devise Autenticacion Flexible para aplicaciones Rails Compuesta de 12 modulos: database authenticable, token authenticable, omniauthable, confirmable, recoverable, registerable, trackable, timeoutable, validatable, lockable
  • 80. APIS ON RAILS SEGURIDAD Devise Autenticacion Flexible para aplicaciones Rails Compuesta de 12 modulos: database authenticable, token authenticable, omniauthable, confirmable, recoverable, registerable, trackable, timeoutable, validatable, lockable
  • 81. APIS ON RAILS SEGURIDAD gem ‘rabl’ class V3::ProductsController < ApplicationController before_filter :authenticate_user! respond_to :json, :xml def index @products = V3::Product.paginate(:page => (params[:page] || 1), :per_page => (params[:per_page] || 100)).all end def show @product = V3::Product.find(params[:id]) end def update @product = V3::Product.find(params[:id]) @product.update_attributes(params[:product]) end def destroy @product = V3::Product.find(params[:id]) render json: {}, status: @product.destroy ? :ok : :unprocessable_entity end end
  • 83. APIS ON RAILS PRUEBAS describe V3::ProductsController do before do @request.env["HTTP_ACCEPT"] = "application/json" end describe "#index" do context "cuando no se pasa ningun atributo" do it "regresa los registros en paginas" do get :index response.should be_success data = JSON.parse(response.body) Product.count.should > 0 data['products'].length.should == Product.count end end end end
  • 84. APIS ON RAILS PRUEBAS describe V3::ProductsController do before do @request.env["HTTP_ACCEPT"] = "application/json" end describe "#show" do context "pasando un id inexistente" do it "responde con http 404 y un mensaje de error" do get :show, id: -1 response.code.should == "404" json_response = JSON.parse(response.body) json_response['error'].should == "ActiveRecord::RecordNotFound" json_response['message'].should == "Couldn't find Product with id=-1" end end end end
  • 85. APIS ON RAILS PRUEBAS describe V3::ProductsController do before do @request.env["HTTP_ACCEPT"] = "application/json" end describe "#create" do context "con malos atributos" do it "responde con un error" do post :create, product: {bad_key: "foo"} response.code.should == "400" json_response = JSON.parse(response.body) json_response['error'].should == "ActiveRecord::UnknownAttributeError" json_response['message'].should == "unknown attribute: bad_key" end end end end
  • 86. APIS ON RAILS PRUEBAS describe V3::ProductsController do before do @request.env["HTTP_ACCEPT"] = "application/json" end describe "#create" do context "con atributos correctos" do it "responde correctamente y crea el producto" do expect { post :create, product: {name: "productito"} }.to change(Product, :count).by(1) end end end end
  • 87. ROR, DEMACIADO PARA LAS API? • Helpers • Vistas • Administracion de assets • Generadores de html • Template engines
  • 88. <Module:0x007ff271221e40>, ActionDispatch::Routing::Helpers, #<Module:0x007ff2714ad268>, ActionController::Base, ActionDispatch::Routing::RouteSet::MountedHelpers, HasScope, ActionController::Compatibility, ActionController::ParamsWrapper, ActionController::Instrumentation, ActionController::Rescue, ActiveSupport::Rescuable, ActionController::HttpAuthentication::Token::ControllerMethods, ActionController::HttpAuthentication::Digest::ControllerMethods, ActionController::HttpAuthentication::Basic::ControllerMethods, ActionController::RecordIdentifier, ActionController::DataStreaming, ActionController::Streaming, ActionController::ForceSSL, ActionController::RequestForgeryProtection, AbstractController::Callbacks, ActiveSupport::Callbacks, ActionController::Flash, ActionController::Cookies, ActionController::MimeResponds, ActionController::ImplicitRender, ActionController::Caching, ActionController::Caching::Fragments, ActionController::Caching::ConfigMethods, ActionController::Caching::Pages, ActionController::Caching::Actions, ActionController::ConditionalGet, ActionController::Head, ActionController::Renderers::All, ActionController::Renderers, ActionController::Rendering, ActionController::Redirecting, ActionController::RackDelegation, ActiveSupport::Benchmarkable, AbstractController::Logger, ActionController::UrlFor, AbstractController::UrlFor, ActionDispatch::Routing::UrlFor, ActionDispatch::Routing::PolymorphicRoutes, ActionController::HideActions, ActionController::Helpers, AbstractController::Helpers, AbstractController::AssetPaths, AbstractController::Translation, AbstractController::Layouts, AbstractController::Rendering, AbstractController::ViewPaths, ActionController::Metal, AbstractController::Base, ActiveSupport::Configurable, Object, ActiveSupport::Dependencies::Loadable, JSON::Ext::Generator::GeneratorMethods::Object, PP::ObjectMixin, Kernel, BasicObject
  • 89. <Module:0x007ff271221e40>, ActionDispatch::Routing::Helpers, #<Module:0x007ff2714ad268>, ActionController::Base, ActionDispatch::Routing::RouteSet::MountedHelpers, HasScope, ActionController::Compatibility, ActionController::ParamsWrapper, ActionController::Instrumentation, ActionController::Rescue, ActiveSupport::Rescuable, ActionController::HttpAuthentication::Token::ControllerMethods, ActionController::HttpAuthentication::Digest::ControllerMethods, #<Module:0x007f9211d5cd70>, ActionController::HttpAuthentication::Basic::ControllerMethods, ActionDispatch::Routing::Helpers, ActionController::RecordIdentifier, #<Module:0x007f9211f7b5e8>, ActionController::DataStreaming, ActionController::API, ActionController::Streaming, ActiveRecord::Railties::ControllerRuntime, ActionController::ForceSSL, ActionDispatch::Routing::RouteSet::MountedHelpers, ActionController::RequestForgeryProtection, ActionController::Instrumentation, AbstractController::Callbacks, ActionController::Rescue, ActiveSupport::Callbacks, ActiveSupport::Rescuable, ActionController::Flash, ActionController::DataStreaming, ActionController::Cookies, ActionController::ForceSSL, ActionController::MimeResponds, AbstractController::Callbacks, ActionController::ImplicitRender, ActiveSupport::Callbacks, ActionController::Caching, ActionController::ConditionalGet, ActionController::Caching::Fragments, ActionController::Head, ActionController::Caching::ConfigMethods, ActionController::Renderers::All, ActionController::Caching::Pages, ActionController::Renderers, ActionController::Caching::Actions, ActionController::Rendering, ActionController::ConditionalGet, AbstractController::Rendering, ActionController::Head, AbstractController::ViewPaths, ActionController::Renderers::All, ActionController::Redirecting, ActionController::Renderers, ActionController::RackDelegation, ActionController::Rendering, ActiveSupport::Benchmarkable, ActionController::Redirecting, AbstractController::Logger, ActionController::RackDelegation, ActionController::UrlFor, ActiveSupport::Benchmarkable, AbstractController::UrlFor, AbstractController::Logger, ActionDispatch::Routing::UrlFor, ActionController::UrlFor, ActionDispatch::Routing::PolymorphicRoutes, AbstractController::UrlFor, ActionController::HideActions, ActionDispatch::Routing::UrlFor, ActionController::Metal, ActionDispatch::Routing::PolymorphicRoutes, AbstractController::Base, ActionController::HideActions, ActiveSupport::Configurable, ActionController::Helpers, Object, AbstractController::Helpers, JSON::Ext::Generator::GeneratorMethods::Object, AbstractController::AssetPaths, ActiveSupport::Dependencies::Loadable, AbstractController::Translation, PP::ObjectMixin, AbstractController::Layouts, Kernel, AbstractController::Rendering, BasicObject AbstractController::ViewPaths, ActionController::Metal, AbstractController::Base, ActiveSupport::Configurable, Object, ActiveSupport::Dependencies::Loadable, JSON::Ext::Generator::GeneratorMethods::Object, PP::ObjectMixin, Kernel, BasicObject
  • 91. RAILS A DIETA Rails es modular
  • 92. RAILS A DIETA Rails es modular Para crear APIs, algunos Middlewares no son necesarios
  • 93. RAILS A DIETA Rails es modular Para crear APIs, algunos Middlewares no son necesarios rails-api
  • 94. use ActionDispatch::Static use Rack::Lock use #<ActiveSupport::Cache::Strategy::Loc alCache::Middleware:0x007fd3b32928c0> use Rack::Runtime use Rack::MethodOverride use ActionDispatch::RequestId use Rails::Rack::Logger use ActionDispatch::ShowExceptions use ActionDispatch::DebugExceptions use ActionDispatch::RemoteIp use ActionDispatch::Reloader use ActionDispatch::Callbacks use ActionDispatch::Cookies use ActionDispatch::Session::CookieStore use ActionDispatch::Flash use ActionDispatch::ParamsParser use ActionDispatch::Head use Rack::ConditionalGet use Rack::ETag use ActionDispatch::BestStandardsSupport use
  • 95. use ActionDispatch::Static use Rack::Lock use use ActionDispatch::Static #<ActiveSupport::Cache::Strategy::Loc use Rack::Lock alCache::Middleware:0x007fd3b32928c0> use use Rack::Runtime #<ActiveSupport::Cache::Strategy::LocalCac use Rack::MethodOverride he::Middleware:0x007fe74448cf50> use ActionDispatch::RequestId use Rack::Runtime use Rails::Rack::Logger use ActionDispatch::RequestId use ActionDispatch::ShowExceptions use Rails::Rack::Logger use ActionDispatch::DebugExceptions use ActionDispatch::ShowExceptions use ActionDispatch::RemoteIp use ActionDispatch::DebugExceptions use ActionDispatch::Reloader use ActionDispatch::RemoteIp use ActionDispatch::Callbacks use ActionDispatch::Reloader use ActionDispatch::Cookies use ActionDispatch::Callbacks use use ActionDispatch::Session::CookieStore ActiveRecord::ConnectionAdapters::Connecti use ActionDispatch::Flash onManagement use ActionDispatch::ParamsParser use ActiveRecord::QueryCache use ActionDispatch::Head use ActionDispatch::ParamsParser use Rack::ConditionalGet use ActionDispatch::Head use Rack::ETag use Rack::ConditionalGet use use Rack::ETag ActionDispatch::BestStandardsSupport use
  • 96. RAILS-API? • ActiveRecord (manejo de errores) • Validaciones (responder a varios formatos) • Controladores, sistema de rutas (versionamiento) • Muchas librerias(Gems) • Autenticación (oauth, token, basic auth) • Mismos web servers confiables (mismo hosting)
  • 100. Gracias! Preguntas? Edwin Cruz edwin@crowdint.com @softr8

Hinweis der Redaktion

  1. \n
  2. Mi plan es hablarles acerca de las famosas y muy comunmente usadas APIs, como implementar una buena API que todo mundo quedra usarla y como ruby on rails te ayudara a hacerla en muy poco tiempo\n
  3. dicho de una manera mas sencilla:\n\n
  4. Asi como las interfaces de usuario ayudan a los usuarios a comunicarse con las aplicaciones, las apis ayudan a comunicar dos softwares distintos entre ellos\n
  5. Estas son algunos ejemplos de APIs, pueden ser tanto como librerias como SDK&amp;#x2019;s, el problema con esto, es que generalmente tienen que ser usadas en el mismo lenguaje de programacion, por ejemplo Net::HTTP es un ejemplo de la API de ruby para establecer conexiones http\n
  6. Estas fueron las primeras API&amp;#x2019;s que se empezaron a consumir en el mundo web, luego llegaron las wsdl&amp;#x2019;s y generalmente eran con mensajes en xml demaciaaado complejas, en esta platica quiero enfocarme a algunas mejores practicas para implementar apis usando las nuevas caracteristicas que se agregaron al http 1.1, especificamente al famoso REST\n
  7. REST nacio en la implementacion de HTTP 1.1, de alguna manera fue mejora del 1.0, y no es mas que un estilo o convension para transferir datos entre el servidor web y el navegador. REST es una manera de organizar recursos con url&amp;#x2019;s unicas por lo tanto, es un patron de dise&amp;#xF1;o para web services\n\nQue requisitos debe tener una aplicacion para ser RESTful ?\n
  8. El server se encarga del almacenamiento, el cliente se encarga de la UI y del estado.\n\nSin estado significa que ninguna llamada REST depende de llamadas pasadas, ocea que el servidor no mantiene ningun valor del cliente en sesion \n\nLa respuesta puede ser cacheable por el cliente o no, se debe de expresar explicitamente, para evitar que el cliente tenga copias obsoletas - Incrementa escalabilidad -\n\nEl cliente nunca podra saber si esta conectado al servidor final - balanceo de cargar, cache -\n\nInterface uniforme es que tiene que ser lo m&amp;#xE1;s explicito posible el mensaje\n\n
  9. El server se encarga del almacenamiento, el cliente se encarga de la UI y del estado.\n\nSin estado significa que ninguna llamada REST depende de llamadas pasadas, ocea que el servidor no mantiene ningun valor del cliente en sesion \n\nLa respuesta puede ser cacheable por el cliente o no, se debe de expresar explicitamente, para evitar que el cliente tenga copias obsoletas - Incrementa escalabilidad -\n\nEl cliente nunca podra saber si esta conectado al servidor final - balanceo de cargar, cache -\n\nInterface uniforme es que tiene que ser lo m&amp;#xE1;s explicito posible el mensaje\n\n
  10. El server se encarga del almacenamiento, el cliente se encarga de la UI y del estado.\n\nSin estado significa que ninguna llamada REST depende de llamadas pasadas, ocea que el servidor no mantiene ningun valor del cliente en sesion \n\nLa respuesta puede ser cacheable por el cliente o no, se debe de expresar explicitamente, para evitar que el cliente tenga copias obsoletas - Incrementa escalabilidad -\n\nEl cliente nunca podra saber si esta conectado al servidor final - balanceo de cargar, cache -\n\nInterface uniforme es que tiene que ser lo m&amp;#xE1;s explicito posible el mensaje\n\n
  11. El server se encarga del almacenamiento, el cliente se encarga de la UI y del estado.\n\nSin estado significa que ninguna llamada REST depende de llamadas pasadas, ocea que el servidor no mantiene ningun valor del cliente en sesion \n\nLa respuesta puede ser cacheable por el cliente o no, se debe de expresar explicitamente, para evitar que el cliente tenga copias obsoletas - Incrementa escalabilidad -\n\nEl cliente nunca podra saber si esta conectado al servidor final - balanceo de cargar, cache -\n\nInterface uniforme es que tiene que ser lo m&amp;#xE1;s explicito posible el mensaje\n\n
  12. El server se encarga del almacenamiento, el cliente se encarga de la UI y del estado.\n\nSin estado significa que ninguna llamada REST depende de llamadas pasadas, ocea que el servidor no mantiene ningun valor del cliente en sesion \n\nLa respuesta puede ser cacheable por el cliente o no, se debe de expresar explicitamente, para evitar que el cliente tenga copias obsoletas - Incrementa escalabilidad -\n\nEl cliente nunca podra saber si esta conectado al servidor final - balanceo de cargar, cache -\n\nInterface uniforme es que tiene que ser lo m&amp;#xE1;s explicito posible el mensaje\n\n
  13. El server se encarga del almacenamiento, el cliente se encarga de la UI y del estado.\n\nSin estado significa que ninguna llamada REST depende de llamadas pasadas, ocea que el servidor no mantiene ningun valor del cliente en sesion \n\nLa respuesta puede ser cacheable por el cliente o no, se debe de expresar explicitamente, para evitar que el cliente tenga copias obsoletas - Incrementa escalabilidad -\n\nEl cliente nunca podra saber si esta conectado al servidor final - balanceo de cargar, cache -\n\nInterface uniforme es que tiene que ser lo m&amp;#xE1;s explicito posible el mensaje\n\n
  14. operaciones comunes en sistemas de informacion, generalmente todo gira alrededor de estas operaciones basicas\n
  15. \n
  16. Representacion en datos, basicamente es un documento que se va a transferir del servidor al cliente\n\nOrigen de alguna informacion en especifico\n
  17. Representacion en datos, basicamente es un documento que se va a transferir del servidor al cliente\n\nOrigen de alguna informacion en especifico\n
  18. Representacion en datos, basicamente es un documento que se va a transferir del servidor al cliente\n\nOrigen de alguna informacion en especifico\n
  19. Hace un momento comentaba de que los primeros web services usaban estructuras de datos basadas en definiciones xml, llegaban a ser mensajes demaciado grandes, y era complicado para un humano leerlas, entonces que pasa, si usamos una estructura mas sensilla?\nPorque JSON ?, si se te complica hacer una estructura con json, algo estas haciendo mal, mensajes son muy cortos, human readable, gzip\n
  20. Hace un momento comentaba de que los primeros web services usaban estructuras de datos basadas en definiciones xml, llegaban a ser mensajes demaciado grandes, y era complicado para un humano leerlas, entonces que pasa, si usamos una estructura mas sensilla?\nPorque JSON ?, si se te complica hacer una estructura con json, algo estas haciendo mal, mensajes son muy cortos, human readable, gzip\n
  21. Ejemplo: middleware\n
  22. Ejemplo: middleware\n
  23. Ejemplo: middleware\n
  24. Como va a estar abierto a m&amp;#xE1;s personas, ejemplo de clientes, cuotas, \nnada de prametros ocultos, cuando regrese errores que los haga bien descriptivo\nbuena documentacion, eventos,\n
  25. Como va a estar abierto a m&amp;#xE1;s personas, ejemplo de clientes, cuotas, \nnada de prametros ocultos, cuando regrese errores que los haga bien descriptivo\nbuena documentacion, eventos,\n
  26. Como va a estar abierto a m&amp;#xE1;s personas, ejemplo de clientes, cuotas, \nnada de prametros ocultos, cuando regrese errores que los haga bien descriptivo\nbuena documentacion, eventos,\n
  27. administracion de cambios\nsi tienes duda de que publicar en tu api, no la publiques, alguien mas la va a implementar y tendras que soportarla\n
  28. administracion de cambios\nsi tienes duda de que publicar en tu api, no la publiques, alguien mas la va a implementar y tendras que soportarla\n
  29. administracion de cambios\nsi tienes duda de que publicar en tu api, no la publiques, alguien mas la va a implementar y tendras que soportarla\n
  30. administracion de cambios\nsi tienes duda de que publicar en tu api, no la publiques, alguien mas la va a implementar y tendras que soportarla\n
  31. administracion de cambios\nsi tienes duda de que publicar en tu api, no la publiques, alguien mas la va a implementar y tendras que soportarla\n
  32. administracion de cambios\nsi tienes duda de que publicar en tu api, no la publiques, alguien mas la va a implementar y tendras que soportarla\n
  33. \n
  34. Una buena API siempre debe seguir convenciones REST, basicamente es seguir la convencion de un buen patron de dise&amp;#xF1;o para solucionar este problema.\n\n
  35. GET, POST, DELETE, PUT, etc\n
  36. \n
  37. \n
  38. \n
  39. \n
  40. no regresaria ningun contenido, solo un http status code\n
  41. \n
  42. \n
  43. muy dificil de adminsitrar, porque un solo controlador se encargaria de despachar todas las versiones\n
  44. \n
  45. \n
  46. La informacion contenida en el header la utiliza el cliente y el servidor para ponerse de acuerdo como van a transmitir la informacion, esto significa que el cliente le esta diciendo al servidor que el soporta la version 2 de la api, y que debe regresarsela en modo json\n
  47. La informacion contenida en el header la utiliza el cliente y el servidor para ponerse de acuerdo como van a transmitir la informacion, esto significa que el cliente le esta diciendo al servidor que el soporta la version 2 de la api, y que debe regresarsela en modo json\n
  48. 401, Se excede la cuota mensual\n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. Mashery\nLimite de uso, para limitar a los usuarios de no hacer mal uso de los recursos, CDN pero para APIS, Balanceo de cargas\nOauth\nSandbox para probar\nbloqueo de IP&amp;#x2019;s, Accesos basados en roles\n
  59. se puede aprovechar al maximo lo que rails ofrece para crear apis muy poderosa, rails ya tiene REST implementado, sistema de cache, autenticacion, logging de eventos, MVC, observers, se puede extender su funcionalidad muy facil, por ejemplo montarle un fulltext search engine como solr, es muy facil escribir pruebas unitarias\n
  60. Rails ya nos da todo para hacer aplicaciones REST\n
  61. Rails soporta namespaces para los recurcos nativamente, pero puede llegar a ser un problema al resolver los nombres de los controladores, para esto alguien mas ya hizo algo al respecto\n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. Funciona transparente con el .to_json, active_model_serializer es bueno para aplicaciones web que usan javascript frameworks como ember o backbone\n
  71. \n
  72. \n
  73. \n
  74. Las pruebas son muy importantes al momento de desarrollar cualquier software, existen herramientas que hacen de esto literalmente un placer, muy facil de automatizar las pruebas\n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. basico para una api\n
  82. basico para una api\n
  83. basico para una api\n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n