amelia bedelia

Cody Fauser, James MacAulay, Edward Ocampo-Gooding, John Guenin, “Rails in a nutshell Chapter 4. Active Resource”, public translation into Russian from English More about this translation.

Translate into another language.

Глава 4. Active Resource

Сегодня, более чем когда-либо, приложения должны уметь работать не только с клиентами на основе веб-браузеров, но и с другими приложениями в качестве клиентов. Для достижения такого взаимодействия веб-приложения обычно предлагают веб-сервисные API. Веб-сервисные API реализуют удаленный доступ к приложению через сеть, такой как Интернет. В прошлом веб-сервисные API обычно реализовывались с помощью сложного и большого SOAP-протокола, который сложен для понимания и реализации. С появлением Rails и развитием REST веб-сервисов мы получили более быстрый и простой способ реализации и работы с веб-сервисами.

Rails позволяет легко предоставить несколько различных типов контента, или представлений, как ресурсов предоставляемых действием контроллера . Возможность предоставить несколько представлений ресурса
через одно действие контроллера позволяет включить поддержку клиентских приложений, не работающих на базе HTML браузера , путем добавления нескольких строк кода, который возвращает ресурс в нужном клиенту представлении.
При этом логика и структура контроллера сохраняется, что дает преимущество в совместимости с новыми клиентами.

Active Resource provides the tools to quickly and easily consume REST based web services conforming to the Rails RESTful URI structure and protocol conventions. Active Resource automatically maps the response from any conforming service to rich Ruby objects. Active Resource also provides all the lifecycle methods needed to easily find, create, update, and delete resources without having to write any code.

Amelia Beldelia

class Person < ActiveResource::Base

self.site = "http://webservice.example.com"

end

With only this simple subclass of ActiveResource::Base and a site definition, which tells Active Resource the base endpoint URI of the remote web service, it is possible to find, create, update, and delete resources :

# Build and save a new person

person = Person.new(:name => "Cody", :title => "Developer")

person.save # => true

# Find an existing person

person = Person.find(1)

# Access a dynamically generated attribute

person.title # => "Developer"

# Update the attribute

person.title = "Unemployed"

# Save changes back to the remote service

person.save # => true

# Delete the person

person.destroy # => true

As you can see, the functionality of an Active Resource based model is very similar to that of an Active Record based model. The only difference being that the data source is a remote web service rather than a SQL database. This chapter provides coverage of all the main functionality of Active Resource and shows you how Active Resource works under the hood so that you can implement your own RESTful Rails web services.

<h2>Прежде чем начать</h2>

Active Resource включен в Rails, но если вы хотите использовать Active Resource в вашем проект вам надо убедится что :active_resource исключен из блока инициализации фраймворков в файле конфигурации config/environment.rb

# убедитесь что в кофиге НЕТ такой строчки

config.frameworks -= [ :active_resource ]

Background

Active Resource is only a small piece of a much larger puzzle. Active Resource is dependent on the remote web service conforming to the Rails RESTful URL structure and data serialization conventions. The web service does not have to be provided by a Rails application, but this is the most common case because Rails makes it so easy to create a RESTful, web service enabled application.

There are two benefits to understanding Active Resource. The first benefit is the ability to quickly and easily create an Active Resource client for someone else's web service. The second benefit is being able to easily expose your own application to Active Resource clients. We're going to take a look under the hood at the communication between an Active Resource client and a Rails application in order to build a complete understanding of web services in Rails.

Active Resource is able to easily consume a web service offered by Rails application conforming to a RESTful architecture because of the consistent URL layout and behavior Representational State Transfer (REST) imposes on the application. REST works with the concept of resources, which are sources of information that can be uniquely addressed by a URI. Clients of an application exchange representations of resources via HTTP. Multiple different representations of a single resource may be available from a single URI. In terms of Rails, multiple different formats of a resource are available from a single controller action, based on the format requested by the client. Active Resource works by specifically asking the Rails application for an XML or JSON representation of a resource, whereas a client's browser would request the HTTP representation.

1 comment

1.

Glenn Goodrich Posted 4 days and 14 hours ago

HTTP or HTML?

Another principle of REST is the use of a constrained set of well defined operations. In Rails the well defined set of operations are based on the different HTTP verbs available. The HTTP verbs GET, POST, PUT, and DELETE map to the standard create, read, update, and delete (CRUD) operations offered by a Rails controller. Instead of specifying the operation to be performed through the request URI like show in /customers/show/15, a RESTful application would send an HTTP GET request to the resource's member URI /customers/15. A member URI, such as /customers/15, uniquely addresses an individual resource, whereas a collection URI, such as /customers, addresses the entire set of resources. Using the HTTP verb in conjunction with the resource URI to specify the desired operation eliminates redundancy and utilizes the well defined underlying HTTP protocol specifications.

Active Resource relies on the server providing the appropriate HTTP status code with each response. This allows Active Resource to accurately communicate any failure conditions that might occur. All status codes between 200 and 399 are considered successful, except for 301 and 302, which are redirects. One other exception is when the server returns the 422 Unprocessable Entity status code, which indicates that validation of the resource failed. In this case, Active Resource rescues the exception and parses the errors returned in the response body so that they are accessible to the client code. We'll take a closer look at validation and errors later in the chapter. Table 4.1, “Active Resource Exceptions” shows the exceptions raised for each different HTTP status code.

Таблица 4.1. Исключения создаваемые Active Resource

Исключения на базе статусов HTTP протокола

301, 302 ActiveResource::Redirection

400 ActiveResource::BadRequest

401 ActiveResource::UnauthorizedAccess

403 ActiveResource::ForbiddenAccess

404 ActiveResource::ResourceNotFound

405 ActiveResource::MethodNotAllowed

409 ActiveResource::ResourceConflict

422 ActiveResource::ResourceInvalid

401 - 499 ActiveResource::ClientError

500 - 599 ActiveResource::ServerError

и другие ActiveResource::ConnectionError

В следующих частях мы рассмотрим код клиента и сервера и как они соотносятся к друг другу. Это поможет вам лучше понять Active Resource и как Rails использует соглашения REST и HTTP протоколов для упрощения приложения. Более подробную информацию по REST вы можете найти по ссылке ( пропущено )

Клиент и Сервер

Давайте создадим клиента для веб сервиса на базе RESTful Rails предоставляющего информацию о покупателях. Серверная часть будет простым Rails приложением состоящим из контроллера CustomersController и модели Customer. Клиентом будет простое приложение на базе Active Resource которое мы назовем Api::Customer. Общая архитектура клиента и сервера будет рассмотрена в этой главе и показана на рисунке 4.1 "Общий обзор RESTful Rails веб сервиса"

Figure 4.1. High level overview of a RESTful Rails web service.

High level overview of a RESTful Rails web service.

Клиент к Веб сервису

Так как клиент к Active Resource скорее всего будет написан для стороннего веб-сервиса, то мало вероятно что и код клиентской и серверной части будет расположен в одном Rails проекте. Поэтому вы можете разместить код Api::Customer в app/models/api/customer.rb в вашем Rails проекте, либо вынести его в отдельный проект.
Модель Api::Customer будет выглядеть следующим образом:

Пример 4.1 Простая модель с использованием Active Resource

module Api

class Customer < ActiveResource::Base

self.site = 'http://localhost:3000'

end

end

Примечание

по соглашению Rails имя ресурса будет сформировано из имени класса переводом его в нижний регистр и добавления подчеркиваний. (те CustomerItem превратится customer_item)

Если Вам нужно что бы название класса и имя ресурса, необходимого для удаленного сервиса, отличались вы можете его задать с помощью ActiveResource::Base.element_name class accessor:

class PersonResource < ActiveResource::Base

self.element_name = "person"

end

В данном случае мы изменили название модели Api что бы отличать ее от модели Active Record в вашего веб приложения. Это позволяет работать с каждой моделью без разночтений, и позволяет обоим моделям существовать и в одном проекте. Если у вас будет два класса Customer в проекте, то это просто не будет работать т.к. при запуске возникнет TypeError из за несоответствия классов прародителей. Использование модели Active Record внутри модуля, никак не повлияет на то как модель будет взаимодействовать с удаленным веб сервисом.

Модели Active Resource необходимо предоставить URI адрес веб сервиса, т.е. сайт.
Вы можете задать сайт для всех под классов задав значение
ActiveResource::Base.site. Вы так же можете задать или переопределить сайт для любого из подклассов аналогичным образом.
ActiveResource использует заданный сайт, названия класса и REST соглашения что бы получить правильные URL для доступа к удаленному ресурсу.
А теперь мы рассмотрим реализацию веб сервиса.

Веб сервис

The web service used for the examples in this chapter is provided by a simple Rails controller called CustomersController that conforms to the Rails RESTful URI structure. For the sake of simplicity the controller will only return XML representations of customer resources.

In order for Rails to properly route requests for a resource to the proper controller and action, the application needs a resource definition in config/routes.rb:

ActionController::Routing::Routes.draw do |map|

map.resources :customers, :collection => { :oldest => :get, :adults => :get }

end

The map.resources :customers call indicates that there is a CustomersController providing access to customer resources. The call defines the standard Rails routes for the customer resource and also defines two custom routes: oldest, and adults. The custom routes will be used for retrieving resources based on custom URIs in the next section. Both custom routes operate on the collection and only accept GET requests. The combination of HTTP verb and request URI is shown in Table 4.2, “RESTful Rails HTTP to controller action mapping” and is also shown in the comment above each controller action in Example 4.2, “A simple controller providing a RESTful web service.”.

Table 4.2. RESTful Rails HTTP to controller action mapping

HTTP Verb Request URI Controller Action

The id in URI would be replaced by the ID of the resource in a request.

GET /customers index

GET /customers/id show

POST /customers create

PUT /customers/id update

DELETE /customers/id destroy

GET /customers/oldest oldest

GET /customers/adults adults

The implementation of the controller used throughout the chapter can be seen in Example 4.2, “A simple controller providing a RESTful web service.”.

Example 4.2. A simple controller providing a RESTful web service.

class CustomersController < ApplicationController

# GET /customers.xml

def index

@customers = Customer.find(:all)

respond_to do |format|

format.xml { render :xml => @customers }

end

end

# GET /customers/1.xml

def show

Pages: ← previous Ctrl next
1 2 3 4

Original (English): Rails in a nutshell Chapter 4. Active Resource

Translation: © MIke, unionups, shopov.vitaliy, skr1p7, andrey19997447, Ghost, 2468013579 .

translated.by crowd

Like this translation? Share it or bookmark!