Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additional Response Details Proposal #399

Open
gerryster opened this issue Nov 8, 2021 · 0 comments
Open

Additional Response Details Proposal #399

gerryster opened this issue Nov 8, 2021 · 0 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@gerryster
Copy link

Additional Response Details Proposal

This is not a bug but an RFC.

Problem

There are strict rate limits for several actions. For example, meeting write operations are limited to 100 requests per day per user. The Zoom API contains response headers which let the caller know how many requests remain. This information is helpful and should be available via the Zoom gem.

Example Session

Observe what happens when a meeting update rate limit is exceeded:

> for i in {1..101}; do curl -i --request PATCH --header "authorization: Bearer $JWT" --header 'content-type: application/json' --url "https://api.zoom.us/v2/meetings/$meeting_id" -d "{ \"topic\": \"my update $i\" }"; done

HTTP/2 204
date: Tue, 26 Oct 2021 02:27:48 GMT
x-zm-trackingid: v=2.0;clid=us02;rid=WEB_596ca498838a64cf86185261bcfc5a63
x-content-type-options: nosniff
cache-control: no-cache, no-store, must-revalidate, no-transform
pragma: no-cache
expires: Thu, 01 Jan 1970 00:00:00 GMT
set-cookie: zm_aid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: zm_haid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: zm_tmaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: zm_htmaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: cred=7FEE3662BDDDBE392A2ADB57E4E3E68E; Path=/; Secure; HttpOnly
vary: Origin
vary: Access-Control-Request-Method
vary: Access-Control-Request-Headers
x-ratelimit-category: Light
x-ratelimit-limit: 100
x-ratelimit-remaining: 99
set-cookie: _zm_ctaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: _zm_chtaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
x-zm-zoneid: VA
strict-transport-security: max-age=31536000; includeSubDomains
x-xss-protection: 1; mode=block
referrer-policy: strict-origin-when-cross-origin

And so on until the final two iterations. Observe the x-ratelimit-remaining response header count down:

HTTP/2 204
date: Tue, 26 Oct 2021 02:27:48 GMT
x-zm-trackingid: v=2.0;clid=us02;rid=WEB_0102974fa9c8da2687b2375d1a77d1d1
x-content-type-options: nosniff
cache-control: no-cache, no-store, must-revalidate, no-transform
pragma: no-cache
expires: Thu, 01 Jan 1970 00:00:00 GMT
set-cookie: zm_aid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: zm_haid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: zm_tmaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: zm_htmaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: cred=878CE20C3062E7F4E0A24D4370A08C30; Path=/; Secure; HttpOnly
vary: Origin
vary: Access-Control-Request-Method
vary: Access-Control-Request-Headers
x-ratelimit-category: Light
x-ratelimit-limit: 100
x-ratelimit-remaining: 0
set-cookie: _zm_ctaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: _zm_chtaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
x-zm-zoneid: VA
retry-after: 2021-10-27T00:00:00Z
strict-transport-security: max-age=31536000; includeSubDomains
x-xss-protection: 1; mode=block
referrer-policy: strict-origin-when-cross-origin

HTTP/2 429
date: Tue, 26 Oct 2021 02:27:48 GMT
content-type: application/json;charset=UTF-8
content-length: 190
x-zm-trackingid: v=2.0;clid=us02;rid=WEB_0b8fe6a9dd55d7955bd1dab3d1db8251
x-content-type-options: nosniff
cache-control: no-cache, no-store, must-revalidate, no-transform
pragma: no-cache
expires: Thu, 01 Jan 1970 00:00:00 GMT
set-cookie: zm_aid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: zm_haid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: zm_tmaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: zm_htmaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: cred=F53584C4704E4CBE7A3D77AABAB94027; Path=/; Secure; HttpOnly
vary: Origin
vary: Access-Control-Request-Method
vary: Access-Control-Request-Headers
x-ratelimit-category: Light
x-ratelimit-limit: 100
x-ratelimit-remaining: 0
set-cookie: _zm_ctaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: _zm_chtaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
x-zm-zoneid: VA
x-ratelimit-type: Daily-limit
retry-after: 2021-10-27T00:00:00Z
set-cookie: _zm_ctaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: _zm_chtaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly

{"code":429,"message":"You have exceeded the daily rate limit (100) of Meeting Create/Update API requests permitted for this particular user. You may resume these requests at GMT 00:00:00."}

Proposal

Currently, responses from this gem are instances of Hash containing the parsed JSON of the HTTP response body from Zoom or integers of the HTTP response code if the body is empty. If configured to do so, a new Zoom::Response object could be returned instead. This will contain three rate limit informational methods: ratelimit_category, ratelimit_limit, and ratelimit_remaining. These will return values corresponding to the response headers. Here is an example usage:

Zoom.configure do |c|
  c.api_key = 'my_key'
  c.api_secret = 'my_secret'
  c.object_responses = true # new option
end

meeting_id = 88888888888

client = Zoom.new
response = client.meeting_update(meeting_id: meeting_id, topic: 'my update')
response.code # 204
response.body # nil or the empty string (open to suggestion here)
response.ratelimit_category # 'Light'
response.ratelimit_limit # 100
response.ratelimit_remaining # 99

response2 = client.meeting_get(meeting_id: meeting_id)
response2.code # 200
response2.body # {"uuid"=>"dfasdfasdfasfdsdf=", "id"=>88888888888, "host_id"=>""232easdfh203, ... }
response2.ratelimit_category # 'Light'
response2.ratelimit_limit # 999999999
response2.ratelimit_remaining # 999999998

This does require an optional new response class while maintaining backward compatibility for more simplistic clients who just want the body or response code. The new response class also opens up new possibilities for features such as enhanced error information like including the HTTP response code (see #388).

I am very interested in feedback on this proposal. Additionally, I am interested submitting a pull request to add such functionality.

@kyleboe kyleboe added enhancement New feature or request help wanted Extra attention is needed labels Nov 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants