Class: Parse::Request

Inherits:
Object
  • Object
show all
Defined in:
lib/parse/client/request.rb

Overview

This class represents a Parse request.

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(method, uri, body: nil, headers: nil, opts: {}) ⇒ Request

Creates a new request

Parameters:

  • method (String)

    the HTTP method

  • uri (String)

    the API path of the request (without the host)

  • body (Hash) (defaults to: nil)

    the body (or parameters) of this request.

  • headers (Hash) (defaults to: nil)

    additional headers to send in this request.

  • opts (Hash) (defaults to: {})

    additional optional parameters.

Options Hash (opts:):

  • :request_id (String)

    custom request ID for idempotency

  • :idempotent (Boolean)

    force enable/disable idempotency for this request



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/parse/client/request.rb', line 102

def initialize(method, uri, body: nil, headers: nil, opts: {})
  @tag = 0
  method = method.downcase.to_sym
  unless method == :get || method == :put || method == :post || method == :delete
    raise ArgumentError, "Invalid method #{method} for request : '#{uri}'"
  end

  self.method = method
  self.path = uri
  self.body = body
  self.headers = headers || {}
  self.opts = opts || {}

  # Handle request ID for idempotency
  setup_request_id
end

Class Attribute Details

.assume_server_idempotencyBoolean

Returns operator assertion that the Parse Server is configured with idempotencyOptions covering the write paths the SDK targets. When true, a request that carries a stable X-Parse-Request-Id header becomes safe for Client to transparently RETRY on an ambiguous failure (500/503/dropped connection) even when it is a POST or an atomic-op write — Parse Server deduplicates the replay server-side, so the write applies AT MOST ONCE.

The replay does NOT transparently return the original response, though: Parse Server rejects the duplicate with error 159, which the SDK raises as Error::DuplicateRequestError. A caller relying on this retry must rescue that error (the original write already landed) and re-fetch by its own key if it needs the result.

Default false. Sending the X-Parse-Request-Id header is harmless on its own, but ASSUMING the server deduplicates when it does not would double-apply the write on retry. Only set this true when Parse Server's idempotencyOptions is actually configured to cover those paths (it is OFF by default on Parse Server).

Returns:

  • (Boolean)

    operator assertion that the Parse Server is configured with idempotencyOptions covering the write paths the SDK targets. When true, a request that carries a stable X-Parse-Request-Id header becomes safe for Client to transparently RETRY on an ambiguous failure (500/503/dropped connection) even when it is a POST or an atomic-op write — Parse Server deduplicates the replay server-side, so the write applies AT MOST ONCE.

    The replay does NOT transparently return the original response, though: Parse Server rejects the duplicate with error 159, which the SDK raises as Error::DuplicateRequestError. A caller relying on this retry must rescue that error (the original write already landed) and re-fetch by its own key if it needs the result.

    Default false. Sending the X-Parse-Request-Id header is harmless on its own, but ASSUMING the server deduplicates when it does not would double-apply the write on retry. Only set this true when Parse Server's idempotencyOptions is actually configured to cover those paths (it is OFF by default on Parse Server).



83
84
85
# File 'lib/parse/client/request.rb', line 83

def assume_server_idempotency
  @assume_server_idempotency
end

.enable_request_idBoolean

Returns whether to automatically generate request IDs for idempotency.

Returns:

  • (Boolean)

    whether to automatically generate request IDs for idempotency



52
53
54
# File 'lib/parse/client/request.rb', line 52

def enable_request_id
  @enable_request_id
end

.idempotent_methodsArray<Symbol>

Returns HTTP methods that should include request IDs.

Returns:

  • (Array<Symbol>)

    HTTP methods that should include request IDs



60
61
62
# File 'lib/parse/client/request.rb', line 60

def idempotent_methods
  @idempotent_methods
end

.request_id_headerString

Returns the header name to use for request IDs.

Returns:

  • (String)

    the header name to use for request IDs



56
57
58
# File 'lib/parse/client/request.rb', line 56

def request_id_header
  @request_id_header
end

Instance Attribute Details

#bodyObject

Returns the value of attribute body.



# File 'lib/parse/client/request.rb', line 17

#cacheBoolean

Returns unused by Parse::Request itself; retained as a plain accessor for callers that stash a cache handle or flag directly on the request object rather than through opts[:cache].

Returns:

  • (Boolean)

    unused by Parse::Request itself; retained as a plain accessor for callers that stash a cache handle or flag directly on the request object rather than through opts[:cache].



38
# File 'lib/parse/client/request.rb', line 38

attr_accessor :method, :path, :body, :headers, :opts, :cache

#headersObject

Returns the value of attribute headers.



38
39
40
# File 'lib/parse/client/request.rb', line 38

def headers
  @headers
end

#methodObject

Returns the value of attribute method.



# File 'lib/parse/client/request.rb', line 11

#optsHash

Returns per-request options consumed by Client#request when it builds the HTTP headers for this request. Recognized keys:

  • :cachefalse sends Cache-Control: no-cache; :write_only skips the cache read but still writes the response; a Numeric overrides the cache expiration (seconds) for this request only.
  • :use_master_keyfalse forces the master key off for this request even if the client has one configured.
  • :session_token — a session token to authenticate this request as a specific user, bypassing the client's default auth context.
  • :idempotent — explicitly enables/disables idempotency-header generation for this request, overriding the class-level defaults.
  • :request_id — a caller-supplied idempotency key; see enable_idempotency!.

Returns:

  • (Hash)

    per-request options consumed by Client#request when it builds the HTTP headers for this request. Recognized keys:

    • :cachefalse sends Cache-Control: no-cache; :write_only skips the cache read but still writes the response; a Numeric overrides the cache expiration (seconds) for this request only.
    • :use_master_keyfalse forces the master key off for this request even if the client has one configured.
    • :session_token — a session token to authenticate this request as a specific user, bypassing the client's default auth context.
    • :idempotent — explicitly enables/disables idempotency-header generation for this request, overriding the class-level defaults.
    • :request_id — a caller-supplied idempotency key; see enable_idempotency!.


38
# File 'lib/parse/client/request.rb', line 38

attr_accessor :method, :path, :body, :headers, :opts, :cache

#pathObject

Returns the value of attribute path.



# File 'lib/parse/client/request.rb', line 14

#request_idString

Returns unique identifier for this request to enable idempotency.

Returns:

  • (String)

    unique identifier for this request to enable idempotency



46
47
48
# File 'lib/parse/client/request.rb', line 46

def request_id
  @request_id
end

Class Method Details

.configure_idempotency(enabled: true, methods: [:post, :put, :patch], header: "X-Parse-Request-Id", assume_server_dedup: false) ⇒ Object

Configures idempotency settings

Parameters:

  • enabled (Boolean) (defaults to: true)

    whether to enable idempotency

  • methods (Array<Symbol>) (defaults to: [:post, :put, :patch])

    HTTP methods to apply idempotency to

  • header (String) (defaults to: "X-Parse-Request-Id")

    header name to use for request IDs

  • assume_server_dedup (Boolean) (defaults to: false)

    sets assume_server_idempotency (default false). Pass true ONLY when Parse Server idempotencyOptions is configured for the targeted paths.



289
290
291
292
293
294
# File 'lib/parse/client/request.rb', line 289

def self.configure_idempotency(enabled: true, methods: [:post, :put, :patch], header: "X-Parse-Request-Id", assume_server_dedup: false)
  self.enable_request_id = enabled
  self.idempotent_methods = methods
  self.request_id_header = header
  self.assume_server_idempotency = assume_server_dedup
end

.disable_idempotency!Object

Disables request ID generation globally. Also clears assume_server_idempotency so writes are never treated as retry-safe once the header is no longer sent.



277
278
279
280
# File 'lib/parse/client/request.rb', line 277

def self.disable_idempotency!
  self.enable_request_id = false
  self.assume_server_idempotency = false
end

.enable_idempotency!(methods: [:post, :put, :patch], header: "X-Parse-Request-Id", assume_server_dedup: nil) ⇒ Object

Enables request ID generation globally

Parameters:

  • methods (Array<Symbol>) (defaults to: [:post, :put, :patch])

    HTTP methods to apply idempotency to

  • header (String) (defaults to: "X-Parse-Request-Id")

    header name to use for request IDs

  • assume_server_dedup (Boolean, nil) (defaults to: nil)

    when non-nil, also sets assume_server_idempotency — pass true ONLY when Parse Server's idempotencyOptions is configured, to additionally make writes retry-safe. Leave nil (default) to send the header without changing the retry posture.



267
268
269
270
271
272
# File 'lib/parse/client/request.rb', line 267

def self.enable_idempotency!(methods: [:post, :put, :patch], header: "X-Parse-Request-Id", assume_server_dedup: nil)
  self.enable_request_id = true
  self.idempotent_methods = methods
  self.request_id_header = header
  self.assume_server_idempotency = assume_server_dedup unless assume_server_dedup.nil?
end

Instance Method Details

#==(r) ⇒ Boolean

Returns:

  • (Boolean)


131
132
133
134
# File 'lib/parse/client/request.rb', line 131

def ==(r)
  return false unless r.is_a?(Request)
  @method == r.method && @path == r.path && @body == r.body && @headers == r.headers
end

#as_jsonHash

Returns JSON encoded hash.

Returns:

  • (Hash)

    JSON encoded hash



126
127
128
# File 'lib/parse/client/request.rb', line 126

def as_json
  signature.as_json
end

#idempotent?Boolean

Checks if this request has idempotency enabled

Returns:

  • (Boolean)


253
254
255
# File 'lib/parse/client/request.rb', line 253

def idempotent?
  @request_id.present? && @headers[self.class.request_id_header].present?
end

#queryHash

The parameters of this request if the HTTP method is GET.

Returns:



121
122
123
# File 'lib/parse/client/request.rb', line 121

def query
  body if @method == :get
end

#signatureHash

Signature provies a way for us to compare different requests objects. Two requests objects are the same if they have the same signature.

Returns:

  • (Hash)

    A hash representing this request.



139
140
141
# File 'lib/parse/client/request.rb', line 139

def signature
  { method: @method.upcase, path: @path, body: @body }
end

#to_sString

Returns:



149
150
151
# File 'lib/parse/client/request.rb', line 149

def to_s
  "#{@method.to_s.upcase} #{@path}"
end

#with_idempotency(custom_id = nil) ⇒ self

Enables idempotency for this specific request

Parameters:

  • custom_id (String) (defaults to: nil)

    optional custom request ID to use

Returns:

  • (self)

    for method chaining



235
236
237
238
239
240
# File 'lib/parse/client/request.rb', line 235

def with_idempotency(custom_id = nil)
  @opts[:idempotent] = true
  @opts[:request_id] = custom_id if custom_id
  setup_request_id
  self
end

#without_idempotencyself

Disables idempotency for this specific request

Returns:

  • (self)

    for method chaining



244
245
246
247
248
249
# File 'lib/parse/client/request.rb', line 244

def without_idempotency
  @opts[:idempotent] = false
  @request_id = nil
  @headers.delete(self.class.request_id_header)
  self
end