Class: ServiceStack::JsonServiceClient

Inherits:
Object
  • Object
show all
Defined in:
lib/servicestack/json_service_client.rb

Overview

Client for consuming ServiceStack APIs with generated typed DTOs.

client = ServiceStack::JsonServiceClient.new('https://example.org')
res = client.send(Hello.new(name: 'World'))
puts res.result

Constant Summary collapse

MIME_TYPE_JSON =
'application/json'

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base_url) ⇒ JsonServiceClient

Returns a new instance of JsonServiceClient.

Raises:

  • (ArgumentError)


81
82
83
84
85
86
87
88
89
# File 'lib/servicestack/json_service_client.rb', line 81

def initialize(base_url)
  raise ArgumentError, 'base_url is required' if base_url.nil? || base_url.to_s.empty?

  @base_url = base_url.to_s.sub(%r{/+$}, '')
  @headers = { 'Accept' => MIME_TYPE_JSON }
  @cookies = {}
  @timeout = 60
  set_base_path('api')
end

Class Attribute Details

.global_request_filterObject

Filters applied to every Request and Response of all clients.



78
79
80
# File 'lib/servicestack/json_service_client.rb', line 78

def global_request_filter
  @global_request_filter
end

.global_response_filterObject

Filters applied to every Request and Response of all clients.



78
79
80
# File 'lib/servicestack/json_service_client.rb', line 78

def global_response_filter
  @global_response_filter
end

Instance Attribute Details

#base_urlObject

Returns the value of attribute base_url.



71
72
73
# File 'lib/servicestack/json_service_client.rb', line 71

def base_url
  @base_url
end

#bearer_tokenObject

Returns the value of attribute bearer_token.



71
72
73
# File 'lib/servicestack/json_service_client.rb', line 71

def bearer_token
  @bearer_token
end

#cookiesObject

Returns the value of attribute cookies.



71
72
73
# File 'lib/servicestack/json_service_client.rb', line 71

def cookies
  @cookies
end

#headersObject

Returns the value of attribute headers.



71
72
73
# File 'lib/servicestack/json_service_client.rb', line 71

def headers
  @headers
end

#on_authentication_requiredObject

Returns the value of attribute on_authentication_required.



71
72
73
# File 'lib/servicestack/json_service_client.rb', line 71

def on_authentication_required
  @on_authentication_required
end

#oneway_base_urlObject

Returns the value of attribute oneway_base_url.



71
72
73
# File 'lib/servicestack/json_service_client.rb', line 71

def oneway_base_url
  @oneway_base_url
end

#passwordObject

Returns the value of attribute password.



71
72
73
# File 'lib/servicestack/json_service_client.rb', line 71

def password
  @password
end

#refresh_tokenObject

Returns the value of attribute refresh_token.



71
72
73
# File 'lib/servicestack/json_service_client.rb', line 71

def refresh_token
  @refresh_token
end

#refresh_token_uriObject

Returns the value of attribute refresh_token_uri.



71
72
73
# File 'lib/servicestack/json_service_client.rb', line 71

def refresh_token_uri
  @refresh_token_uri
end

#reply_base_urlObject

Returns the value of attribute reply_base_url.



71
72
73
# File 'lib/servicestack/json_service_client.rb', line 71

def reply_base_url
  @reply_base_url
end

#request_filterObject

Returns the value of attribute request_filter.



71
72
73
# File 'lib/servicestack/json_service_client.rb', line 71

def request_filter
  @request_filter
end

#response_filterObject

Returns the value of attribute response_filter.



71
72
73
# File 'lib/servicestack/json_service_client.rb', line 71

def response_filter
  @response_filter
end

#timeoutObject

Returns the value of attribute timeout.



71
72
73
# File 'lib/servicestack/json_service_client.rb', line 71

def timeout
  @timeout
end

#user_nameObject

Returns the value of attribute user_name.



71
72
73
# File 'lib/servicestack/json_service_client.rb', line 71

def user_name
  @user_name
end

Instance Method Details

#api(request, method: nil, args: nil) ⇒ Object

Sends a Request DTO, returning an ApiResult containing either its typed Response or the structured ResponseStatus error.



159
160
161
162
163
164
165
# File 'lib/servicestack/json_service_client.rb', line 159

def api(request, method: nil, args: nil)
  ApiResult.new(response: send(request, method: method, args: args))
rescue WebServiceException => e
  ApiResult.new(error: e.response_status || ResponseStatus.new(
    error_code: e.status_description, message: e.message
  ))
end

#authenticate(user_name, password) ⇒ Object

Signs in with UserName and Password credentials, using the Bearer Token and Session Cookies the Server returns for subsequent Requests.



190
191
192
193
194
195
# File 'lib/servicestack/json_service_client.rb', line 190

def authenticate(user_name, password)
  res = send(Authenticate.new(provider: 'credentials', user_name: user_name, password: password))
  @bearer_token = res.bearer_token unless res.bearer_token.to_s.empty?
  @refresh_token = res.refresh_token unless res.refresh_token.to_s.empty?
  res
end

#create_url_from_dto(method, request) ⇒ Object

The URL a Request DTO is sent to, appending the populated DTO properties to the QueryString for Requests without a Body.



275
276
277
278
279
280
# File 'lib/servicestack/json_service_client.rb', line 275

def create_url_from_dto(method, request)
  url = combine_with(@reply_base_url, type_name_of(request))
  return url if has_request_body?(method)

  append_query_string(url, to_hash(request))
end

#delete(request, args: nil) ⇒ Object



148
# File 'lib/servicestack/json_service_client.rb', line 148

def delete(request, args: nil) = send(request, method: HttpMethods::DELETE, args: args)

#delete_url(path, response_as: nil, args: nil) ⇒ Object



216
217
218
# File 'lib/servicestack/json_service_client.rb', line 216

def delete_url(path, response_as: nil, args: nil)
  send_url(path, method: HttpMethods::DELETE, response_as: response_as, args: args)
end

#get(request, args: nil) ⇒ Object



144
# File 'lib/servicestack/json_service_client.rb', line 144

def get(request, args: nil) = send(request, method: HttpMethods::GET, args: args)

#get_url(path, response_as: nil, args: nil) ⇒ Object

Sends a GET Request to a custom relative path or absolute URL.



200
201
202
# File 'lib/servicestack/json_service_client.rb', line 200

def get_url(path, response_as: nil, args: nil)
  send_url(path, method: HttpMethods::GET, response_as: response_as, args: args)
end

#patch(request, body: nil, args: nil) ⇒ Object



147
# File 'lib/servicestack/json_service_client.rb', line 147

def patch(request, body: nil, args: nil) = send(request, method: HttpMethods::PATCH, body: body, args: args)

#patch_url(path, body: nil, response_as: nil, args: nil) ⇒ Object



212
213
214
# File 'lib/servicestack/json_service_client.rb', line 212

def patch_url(path, body: nil, response_as: nil, args: nil)
  send_url(path, method: HttpMethods::PATCH, body: body, response_as: response_as, args: args)
end

#post(request, body: nil, args: nil) ⇒ Object



145
# File 'lib/servicestack/json_service_client.rb', line 145

def post(request, body: nil, args: nil) = send(request, method: HttpMethods::POST, body: body, args: args)

#post_file_with_request(request, file, args: nil) ⇒ Object

Uploads a file with a Request DTO as a multipart/form-data Request, returning its typed Response, e.g:

File.open('photo.png', 'rb') do |file|
client.post_file_with_request(UploadPhoto.new(album: 'Holiday'),
  ServiceStack::UploadFile.new(field_name: 'file', file_name: 'photo.png',
                               content_type: 'image/png', stream: file))
end


240
241
242
# File 'lib/servicestack/json_service_client.rb', line 240

def post_file_with_request(request, file, args: nil)
  post_files_with_request(request, [file], args: args)
end

#post_files_with_request(request, files, args: nil) ⇒ Object

Uploads multiple files with a Request DTO as a multipart/form-data Request.



245
246
247
248
# File 'lib/servicestack/json_service_client.rb', line 245

def post_files_with_request(request, files, args: nil)
  url = create_url_from_dto(HttpMethods::POST, request)
  post_files_with_request_url(url, request, files, response_as: resolve_response_type(request), args: args)
end

#post_files_with_request_url(path, request, files, response_as: nil, args: nil) ⇒ Object

Uploads files with a Request DTO to a custom relative path or absolute URL.



251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/servicestack/json_service_client.rb', line 251

def post_files_with_request_url(path, request, files, response_as: nil, args: nil)
  boundary = "----ServiceStackFormBoundary#{SecureRandom.hex(12)}"
  body = multipart_body(boundary, request, files)

  json = execute(HttpMethods::POST, to_absolute_url(path), body, args: args,
                                                                content_type: "multipart/form-data; boundary=#{boundary}")
  return nil if response_as.nil?
  return json if response_as == String

  parsed = json.to_s.strip.empty? ? {} : JSON.parse(json)
  return parsed unless response_as.respond_to?(:from_hash)

  response_as.from_hash(parsed)
end

#post_url(path, body: nil, response_as: nil, args: nil) ⇒ Object



204
205
206
# File 'lib/servicestack/json_service_client.rb', line 204

def post_url(path, body: nil, response_as: nil, args: nil)
  send_url(path, method: HttpMethods::POST, body: body, response_as: response_as, args: args)
end

#publish(request) ⇒ Object

Sends a Request DTO to a one-way endpoint, ignoring any Response.



182
183
184
185
186
# File 'lib/servicestack/json_service_client.rb', line 182

def publish(request)
  url = combine_with(@oneway_base_url, type_name_of(request))
  execute(HttpMethods::POST, url, request)
  nil
end

#put(request, body: nil, args: nil) ⇒ Object



146
# File 'lib/servicestack/json_service_client.rb', line 146

def put(request, body: nil, args: nil) = send(request, method: HttpMethods::PUT, body: body, args: args)

#put_url(path, body: nil, response_as: nil, args: nil) ⇒ Object



208
209
210
# File 'lib/servicestack/json_service_client.rb', line 208

def put_url(path, body: nil, response_as: nil, args: nil)
  send_url(path, method: HttpMethods::PUT, body: body, response_as: response_as, args: args)
end

#send(request, method: nil, body: nil, args: nil) ⇒ Object Also known as: send_dto

Sends a Request DTO with the HTTP Method it's annotated with, returning its typed Response.

Note this overrides Object#send, use send or send_dto for Ruby's dynamic dispatch.



137
138
139
140
141
# File 'lib/servicestack/json_service_client.rb', line 137

def send(request, method: nil, body: nil, args: nil)
  method ||= resolve_http_method(request)
  execute_typed(method, create_url_from_dto(method, request), body || request,
                resolve_response_type(request), args: args)
end

#send_all(requests) ⇒ Object

Sends multiple Request DTOs of the same Type in a single Request.



168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/servicestack/json_service_client.rb', line 168

def send_all(requests)
  return [] if requests.nil? || requests.empty?

  # Brackets are encoded so the batch URL is a valid URI
  url = combine_with(@reply_base_url, "#{type_name_of(requests.first)}%5B%5D")
  response_type = resolve_response_type(requests.first)
  json = execute(HttpMethods::POST, url, requests)
  parsed = json.to_s.empty? ? [] : JSON.parse(json)
  return parsed unless response_type

  parsed.map { |x| response_type.from_hash(x) }
end

#send_url(path, method: HttpMethods::GET, body: nil, response_as: nil, args: nil) ⇒ Object

Sends a Request to a custom relative path or absolute URL.



221
222
223
# File 'lib/servicestack/json_service_client.rb', line 221

def send_url(path, method: HttpMethods::GET, body: nil, response_as: nil, args: nil)
  execute_typed(method, to_absolute_url(path), body, response_as, args: args)
end

#send_url_string(path, method: HttpMethods::GET, body: nil, args: nil) ⇒ Object

Sends a Request to a custom URL, returning its raw Response Body.



226
227
228
# File 'lib/servicestack/json_service_client.rb', line 226

def send_url_string(path, method: HttpMethods::GET, body: nil, args: nil)
  execute(method, to_absolute_url(path), body, args: args)
end

#send_void(request, args: nil) ⇒ Object

Sends a Request DTO that doesn't return a Response Body.



151
152
153
154
155
# File 'lib/servicestack/json_service_client.rb', line 151

def send_void(request, args: nil)
  method = resolve_http_method(request)
  execute(method, create_url_from_dto(method, request), request, args: args)
  nil
end

#set_base_path(base_path = '') ⇒ Object

Changes the base path Request DTOs are sent to, e.g. 'api'. Use an empty base_path for the /json/reply pre-defined routes.



93
94
95
96
97
98
99
100
101
102
# File 'lib/servicestack/json_service_client.rb', line 93

def set_base_path(base_path = '')
  if base_path.nil? || base_path.to_s.empty?
    @reply_base_url = combine_with(@base_url, 'json/reply')
    @oneway_base_url = combine_with(@base_url, 'json/oneway')
  else
    @reply_base_url = combine_with(@base_url, base_path)
    @oneway_base_url = combine_with(@base_url, base_path)
  end
  self
end

#set_bearer_token(token) ⇒ Object

Sets the JWT or API Key sent in the Bearer Authorization header.



105
106
107
108
# File 'lib/servicestack/json_service_client.rb', line 105

def set_bearer_token(token)
  @bearer_token = token
  self
end

#set_credentials(user_name, password) ⇒ Object

Sets the UserName and Password sent in the HTTP Basic Auth header.



118
119
120
121
122
# File 'lib/servicestack/json_service_client.rb', line 118

def set_credentials(user_name, password)
  @user_name = user_name
  @password = password
  self
end

#set_header(name, value) ⇒ Object

Sets a HTTP Header sent with each Request.



125
126
127
128
# File 'lib/servicestack/json_service_client.rb', line 125

def set_header(name, value)
  @headers[name] = value
  self
end

#set_refresh_token(token) ⇒ Object

Sets the Refresh Token used to fetch a new Bearer Token when a Request returns 401 Unauthorized.



112
113
114
115
# File 'lib/servicestack/json_service_client.rb', line 112

def set_refresh_token(token)
  @refresh_token = token
  self
end

#to_absolute_url(path_or_url) ⇒ Object

Converts a relative path into an absolute URL of this client.



267
268
269
270
271
# File 'lib/servicestack/json_service_client.rb', line 267

def to_absolute_url(path_or_url)
  return path_or_url if path_or_url.to_s.start_with?('http://', 'https://')

  combine_with(@base_url, path_or_url)
end