Skip to content

Commit 0d7b3d0

Browse files
committed
Merge pull request googleapis#87 from sgomes/new_programming_interface
New programming interface for the client library
2 parents b05de26 + 876ddda commit 0d7b3d0

File tree

7 files changed

+1285
-0
lines changed

7 files changed

+1285
-0
lines changed

lib/google/api_client/service.rb

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
# Copyright 2013 Google Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
require 'google/api_client'
16+
require 'google/api_client/service/stub_generator'
17+
require 'google/api_client/service/resource'
18+
require 'google/api_client/service/request'
19+
require 'google/api_client/service/result'
20+
require 'google/api_client/service/batch'
21+
22+
module Google
23+
class APIClient
24+
25+
##
26+
# Experimental new programming interface at the API level.
27+
# Hides Google::APIClient. Designed to be easier to use, with less code.
28+
#
29+
# @example
30+
# calendar = Google::APIClient::Service.new('calendar', 'v3')
31+
# result = calendar.events.list('calendarId' => 'primary').execute()
32+
class Service
33+
include Google::APIClient::Service::StubGenerator
34+
extend Forwardable
35+
36+
# Cache for discovered APIs.
37+
@@discovered = {}
38+
39+
##
40+
# Creates a new Service.
41+
#
42+
# @param [String, Symbol] api_name
43+
# The name of the API this service will access.
44+
# @param [String, Symbol] api_version
45+
# The version of the API this service will access.
46+
# @param [Hash] options
47+
# The configuration parameters for the service.
48+
# @option options [Symbol, #generate_authenticated_request] :authorization
49+
# (:oauth_1)
50+
# The authorization mechanism used by the client. The following
51+
# mechanisms are supported out-of-the-box:
52+
# <ul>
53+
# <li><code>:two_legged_oauth_1</code></li>
54+
# <li><code>:oauth_1</code></li>
55+
# <li><code>:oauth_2</code></li>
56+
# </ul>
57+
# @option options [Boolean] :auto_refresh_token (true)
58+
# The setting that controls whether or not the api client attempts to
59+
# refresh authorization when a 401 is hit in #execute. If the token does
60+
# not support it, this option is ignored.
61+
# @option options [String] :application_name
62+
# The name of the application using the client.
63+
# @option options [String] :application_version
64+
# The version number of the application using the client.
65+
# @option options [String] :host ("www.googleapis.com")
66+
# The API hostname used by the client. This rarely needs to be changed.
67+
# @option options [String] :port (443)
68+
# The port number used by the client. This rarely needs to be changed.
69+
# @option options [String] :discovery_path ("/discovery/v1")
70+
# The discovery base path. This rarely needs to be changed.
71+
# @option options [String] :ca_file
72+
# Optional set of root certificates to use when validating SSL connections.
73+
# By default, a bundled set of trusted roots will be used.
74+
# @option options [#generate_authenticated_request] :authorization
75+
# The authorization mechanism for requests. Used only if
76+
# `:authenticated` is `true`.
77+
# @option options [TrueClass, FalseClass] :authenticated (default: true)
78+
# `true` if requests must be signed or somehow
79+
# authenticated, `false` otherwise.
80+
# @option options [TrueClass, FalseClass] :gzip (default: true)
81+
# `true` if gzip enabled, `false` otherwise.
82+
# @option options [Faraday::Connection] :connection
83+
# A custom connection to be used for all requests.
84+
def initialize(api_name, api_version, options = {})
85+
@api_name = api_name.to_s
86+
if api_version.nil?
87+
raise ArgumentError,
88+
"API version must be set"
89+
end
90+
@api_version = api_version.to_s
91+
if options && !options.respond_to?(:to_hash)
92+
raise ArgumentError,
93+
"expected options Hash, got #{options.class}"
94+
end
95+
96+
params = {}
97+
[:application_name, :application_version, :authorization, :host, :port,
98+
:discovery_path, :auto_refresh_token, :key, :user_ip,
99+
:ca_file].each do |option|
100+
if options.include? option
101+
params[option] = options[option]
102+
end
103+
end
104+
105+
@client = Google::APIClient.new(params)
106+
@client.logger = options[:logger] if options.include? :logger
107+
108+
@connection = options[:connection] || @client.connection
109+
110+
@options = options
111+
112+
# Cache discovered APIs in memory.
113+
# Not thread-safe, but the worst that can happen is a cache miss.
114+
unless @api = @@discovered[[api_name, api_version]]
115+
@@discovered[[api_name, api_version]] = @api = @client.discovered_api(
116+
api_name, api_version)
117+
end
118+
119+
generate_call_stubs(self, @api)
120+
end
121+
122+
##
123+
# Logger for the Service.
124+
#
125+
# @return [Logger]
126+
# The logger instance.
127+
def_delegators :@client, :logger, :logger=
128+
129+
##
130+
# Returns the authorization mechanism used by the service.
131+
#
132+
# @return [#generate_authenticated_request] The authorization mechanism.
133+
def_delegators :@client, :authorization, :authorization=
134+
135+
##
136+
# The setting that controls whether or not the service attempts to
137+
# refresh authorization when a 401 is hit during an API call.
138+
#
139+
# @return [Boolean]
140+
def_delegators :@client, :auto_refresh_token, :auto_refresh_token=
141+
142+
##
143+
# The application's API key issued by the API console.
144+
#
145+
# @return [String] The API key.
146+
def_delegators :@client, :key, :key=
147+
148+
##
149+
# The Faraday/HTTP connection used by this service.
150+
#
151+
# @return [Faraday::Connection]
152+
attr_accessor :connection
153+
154+
##
155+
# Prepares a Google::APIClient::BatchRequest object to make batched calls.
156+
# @param [Array] calls
157+
# Optional array of Google::APIClient::Service::Request to initialize
158+
# the batch request with.
159+
# @param [Proc] block
160+
# Callback for every call's response. Won't be called if a call defined
161+
# a callback of its own.
162+
#
163+
# @yield [Google::APIClient::Service::Result]
164+
# block to be called when result ready
165+
def batch(calls = nil, &block)
166+
Google::APIClient::Service::BatchRequest.new(self, calls, &block)
167+
end
168+
169+
##
170+
# Executes an API request.
171+
# Do not call directly; this method is only used by Request objects when
172+
# executing.
173+
#
174+
# @param [Google::APIClient::Service::Request,
175+
# Google::APIClient::Service::BatchCall] request
176+
# The request to be executed.
177+
def execute(request)
178+
if request.instance_of? Google::APIClient::Service::Request
179+
params = {:api_method => request.method,
180+
:parameters => request.parameters,
181+
:connection => @connection}
182+
if request.respond_to? :body
183+
if request.body.respond_to? :to_hash
184+
params[:body_object] = request.body
185+
else
186+
params[:body] = request.body
187+
end
188+
end
189+
if request.respond_to? :media
190+
params[:media] = request.media
191+
end
192+
[:authenticated, :gzip].each do |option|
193+
if @options.include? option
194+
params[option] = @options[option]
195+
end
196+
end
197+
result = @client.execute(params)
198+
return Google::APIClient::Service::Result.new(request, result)
199+
elsif request.instance_of? Google::APIClient::Service::BatchRequest
200+
@client.execute(request.base_batch)
201+
end
202+
end
203+
end
204+
end
205+
end
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# Copyright 2013 Google Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
require 'google/api_client/service/result'
16+
require 'google/api_client/batch'
17+
18+
module Google
19+
class APIClient
20+
class Service
21+
22+
##
23+
# Helper class to contain the result of an individual batched call.
24+
#
25+
class BatchedCallResult < Result
26+
# @return [Fixnum] Index of the call
27+
def call_index
28+
return @base_result.response.call_id.to_i - 1
29+
end
30+
end
31+
32+
##
33+
#
34+
#
35+
class BatchRequest
36+
##
37+
# Creates a new batch request.
38+
# This class shouldn't be instantiated directly, but rather through
39+
# Service.batch.
40+
#
41+
# @param [Array] calls
42+
# List of Google::APIClient::Service::Request to be made.
43+
# @param [Proc] block
44+
# Callback for every call's response. Won't be called if a call
45+
# defined a callback of its own.
46+
#
47+
# @yield [Google::APIClient::Service::Result]
48+
# block to be called when result ready
49+
def initialize(service, calls, &block)
50+
@service = service
51+
@base_batch = Google::APIClient::BatchRequest.new
52+
@global_callback = block if block_given?
53+
54+
if calls && calls.length > 0
55+
calls.each do |call|
56+
add(call)
57+
end
58+
end
59+
end
60+
61+
##
62+
# Add a new call to the batch request.
63+
#
64+
# @param [Google::APIClient::Service::Request] call
65+
# the call to be added.
66+
# @param [Proc] block
67+
# callback for this call's response.
68+
#
69+
# @return [Google::APIClient::Service::BatchRequest]
70+
# the BatchRequest, for chaining
71+
#
72+
# @yield [Google::APIClient::Service::Result]
73+
# block to be called when result ready
74+
def add(call, &block)
75+
if !block_given? && @global_callback.nil?
76+
raise BatchError, 'Request needs a block'
77+
end
78+
callback = block || @global_callback
79+
base_call = {
80+
:api_method => call.method,
81+
:parameters => call.parameters
82+
}
83+
@base_batch.add(base_call) do |base_result|
84+
result = Google::APIClient::Service::BatchedCallResult.new(
85+
call, base_result)
86+
callback.call(result)
87+
end
88+
return self
89+
end
90+
91+
##
92+
# Executes the batch request.
93+
def execute
94+
@service.execute(self)
95+
end
96+
97+
attr_reader :base_batch
98+
99+
end
100+
101+
end
102+
end
103+
end

0 commit comments

Comments
 (0)