amelia bedelia |
- Statistics
- Participants
- Translate into Russian
- Translation result
- 15% translated in draft.
Глава 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
Original (English): Rails in a nutshell Chapter 4. Active Resource
Translation: © MIke, unionups, shopov.vitaliy, skr1p7, andrey19997447, Ghost, 2468013579 .
