2012-08-02 6 views
6

¿Cómo puedo usar un servicio JSON como modelo para una aplicación Rails 3.2?Uso de un servicio JSON como modelo Rails

Me gustaría vincular los métodos del modelo con las solicitudes JSON, p.

  • MyModel.create para generar una solicitud JSON para crear un nuevo registro
  • MyModel.find para generar una solicitud JSON para recuperar un registro y decodificar la respuesta JSON en un objeto de modelo

¿Cuál es la manera preferida para construir este tipo de funcionalidad? Una opción que estoy viendo es crear un adaptador personalizado DataMapper.

Gracias.

Actualización:
Tenga en cuenta que no puedo usar ActiveResource porque esto requiere el servicio JSON para responder de una manera determinada, lo cual no es así en este caso.

Respuesta

3

Respuesta corta: depende de su servicio JSON.

¿El servicio es RESTful, para empezar? Si es así, estás de suerte. ActiveResource es dead, así que no aconsejaría usarlo, pero el código en sí proporcionaría un buen punto de partida para crear un conjunto de métodos de envoltura como create y find para acceder a su API y manipular registros de la misma forma que ActiveRecord crea y consulta registros en el DB. Eso es relativamente fácil si su API es RESTful porque rails is built around RESTful-ness, por lo que la asignación entre los dos se vuelve mucho más limpia.

This article lo resume así:

rieles hace que sea muy fácil de construir servicios Web que siguen los principios descanso y el trabajo igual de bien con los navegadores web y la web programable. De hecho, mucha de esa simplicidad proviene directamente de seguir estos principios. No tuvimos que decirle a nuestro cliente cómo crear, leer, actualizar o eliminar el recurso, todos seguidos del uso de los métodos HTTP adecuados. Todo lo que teníamos que hacer era señalar a nuestro cliente en el lugar correcto.

Si su servicio es no REST, que a juzgar por los comentarios sobre otras cuestiones que creo que es quizás el caso, entonces usted tendrá su trabajo cortado para usted. ActiveModel no hará este trabajo por usted: create se define en ActiveRecord::Persistence, y find se define en ActiveRecord::FinderMethods. No están en ActiveModel.ActiveResource puede reproducirlos con bastante facilidad porque hace suposiciones sobre el tipo de servicio con el que interactúa (es decir, que es RESTful, más algunas otras cosas).

Lo que ofrece es ActiveModel todas las otras cosas que hace que los carriles tan útil para tratar con los modelos: el sistema de validación, los métodos de serialización, el seguimiento de los cambios de atributos sucia, devoluciones de llamada (before_save, after_save, etc.), traducción/localización, y así. Todas estas funciones son muy útiles, pero aún así te dejan el problema de envolver tus llamadas API.

Así que aquí es lo que yo recomendaría, basado en mi aunque sea una experiencia limitada (ver mi nota final sobre eso):

  1. En primer lugar, echar un vistazo de cerca a su API y averiguar lo cerca que está de ser Sosegado. Si es no RESTful, tendrá que pensar en cómo solucionar esto para poder tratarlo como un servicio RESTful. Una buena referencia sobre cómo hacerlo es O'Reilly's RESTful Web Services (específicamente el Capítulo 2, "Escritura de clientes del servicio web").
  2. Cree un envoltorio API que implemente create, find y cualquier otra funcionalidad similar a ActiveRecord que desee tener. Probablemente desee utilizar una gema como Faraday o HTTParty para realizar solicitudes a la API en lugar de trabajar directamente con Net :: HTTP. (Nunca he usado DataMapper, así que no puedo comentar sobre eso.)
  3. Incluye los elementos de ActiveModel que quieras usar para hacer que tu clase de contenedor sea más parecida a un modelo de rieles: validaciones, serialización, etc. En Rails 4, puedes de hecho incluye todo usando los nuevos barebones ActiveModel::Model.

Eso le ayudará a usar su servicio JSON como modelo de Rails.

Para el registro, mi experiencia en la implementación de este tipo de cosas se limita a crear un contenedor API (en proceso) para acceder a una API XML. El contenedor tiene una clase que incluye validadores de ActiveModel para validar consultas a la API. He encontrado que los validadores de ActiveModel son realmente útiles para garantizar que se acceda correctamente a la API, pero el contenedor solo sirve para obtener registros de la API, no para crearlos o actualizarlos, por lo que la interfaz es mucho más fácil de lo que esperaba. estarás construyendo.

+0

Gracias por una respuesta tan completa. Afortunadamente, el servicio JSON es RESTful, es solo que no responde de la manera esperada por ActiveResource. Evitaré ActiveResource ahora que sé que está muerto y, en su lugar, leeré el artículo de DZone al que te has vinculado. ¡Gracias de nuevo! – gjb

+0

¡Oh, son buenas noticias!En ese caso, la tarea no debería ser demasiado difícil. Aunque no estés usando ActiveResource, puedes intentar echar un vistazo al código para ver cómo funciona. –

+0

En caso de que todavía esté trabajando en esto, algunas otras gemas que pueden ser útiles: https://github.com/filtersquad/api_smith https://github.com/remiprev/her https://github.com/ apotonick/rugido –

0

Hago esto en mi gema "otrs_connector" ... No funcionará para su servicio pero puede darle una idea de cómo hacerlo ... El enfoque que tomé puede no ser el mejor y necesita ser refactorado un poco, pero funciona, y bastante bien en eso.

+0

Gracias, voy a echar un vistazo a esto. – gjb

1

Creo que lo que estás buscando es ActiveResource, se puede utilizar en lugar de ActiveRecord a trabajar con un API REST JSON ver this link y this (apidock)

+0

Gracias. Desafortunadamente, esto parece requerir que la API JSON responda de cierta manera, y no con la que estoy trabajando. Por ejemplo, responde con 'OK' si se crea un nuevo registro, en lugar de una representación JSON del nuevo registro. – gjb

1

La mejor manera de hacer esto es poner en práctica un ActiveModel. Este railscast cubre los conceptos básicos.

+0

Gracias, echaré un vistazo a eso. ¿Cuál es la ventaja de ActiveModel sobre DataMapper? – gjb

+0

ActiveModel está incluido con Rails, por lo que obtendrá un mejor soporte para él de forma inmediata. –

0

Si el servicio web está fuera de la "manera normal" de hacer las cosas, recomendaría HTTParty. Es bastante fácil hacer un Proxy al servicio web que responde como usted lo desee.

Por ejemplo, aquí es su ejemplo de acceso a la línea de tiempo de Twitter

class Twitter 
    include HTTParty 
    base_uri 'twitter.com' 

    def initialize(u, p) 
    @auth = {:username => u, :password => p} 
    end 

    # which can be :friends, :user or :public 
    # options[:query] can be things like since, since_id, count, etc. 
    def timeline(which=:friends, options={}) 
    options.merge!({:basic_auth => @auth}) 
    self.class.get("/statuses/#{which}_timeline.json", options) 
    end 

    def post(text) 
    options = { :query => {:status => text}, :basic_auth => @auth } 
    self.class.post('/statuses/update.json', options) 
    end 
end 

twitter = Twitter.new(config['email'], config['password']) 
pp twitter.timeline 
+0

Gracias, esta es una alternativa interesante, pero preferiría que el servicio JSON funcione como un modelo tradicional de Rails. – gjb

Cuestiones relacionadas