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

Add GlobalStorage API support #4

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 22 additions & 10 deletions .rspec_status
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need the file in repo?

Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
example_id | status | run_time |
----------------------- | ------ | --------------- |
./spec/sdk_spec.rb[1:1] | passed | 0.00092 seconds |
./spec/sdk_spec.rb[1:2] | passed | 0.06699 seconds |
./spec/sdk_spec.rb[1:3] | passed | 0.00039 seconds |
./spec/sdk_spec.rb[1:4] | passed | 0.00052 seconds |
./spec/sdk_spec.rb[1:5] | passed | 0.0032 seconds |
./spec/sdk_spec.rb[1:6] | passed | 0.00035 seconds |
./spec/sdk_spec.rb[1:7] | passed | 0.0003 seconds |
./spec/sdk_spec.rb[1:8] | passed | 0.00154 seconds |
example_id | status | run_time |
------------------------------------------------------- | ------ | --------------- |
./spec/monday/client_spec.rb[1:1:1] | passed | 0.00003 seconds |
./spec/monday/client_spec.rb[1:1:2] | passed | 0.00003 seconds |
./spec/monday/client_spec.rb[1:1:3] | passed | 0.00002 seconds |
./spec/monday/client_spec.rb[1:2] | passed | 0.00047 seconds |
./spec/monday/client_spec.rb[1:3] | passed | 0.00093 seconds |
./spec/monday/client_spec.rb[1:4] | passed | 0.00017 seconds |
./spec/monday/client_spec.rb[1:5:1] | passed | 0.0006 seconds |
./spec/monday/monday_api/monday_api_client_spec.rb[1:1] | passed | 0.00009 seconds |
./spec/monday/storage_spec.rb[1:1:1] | passed | 0.00003 seconds |
./spec/monday/storage_spec.rb[1:1:2] | passed | 0.00003 seconds |
./spec/monday/storage_spec.rb[1:1:3] | passed | 0.00002 seconds |
./spec/monday/storage_spec.rb[1:2:1] | passed | 0.00016 seconds |
./spec/monday/storage_spec.rb[1:2:2] | passed | 0.00014 seconds |
./spec/monday/storage_spec.rb[1:2:3] | passed | 0.00014 seconds |
./spec/monday/storage_spec.rb[1:2:4] | passed | 0.0003 seconds |
./spec/monday/storage_spec.rb[1:3:1] | passed | 0.00016 seconds |
./spec/monday/storage_spec.rb[1:3:2] | passed | 0.00017 seconds |
./spec/monday/storage_spec.rb[1:4:1] | passed | 0.00076 seconds |
./spec/monday/storage_spec.rb[1:4:2] | passed | 0.00017 seconds |
./spec/sdk_spec.rb[1:1] | passed | 0.00021 seconds |
21 changes: 21 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
AllCops:
TargetRubyVersion: 2.3

Style/FrozenStringLiteralComment:
Enabled: true
SafeAutoCorrect: true

Style/Documentation:
Enabled: false

Metrics/BlockLength:
Exclude:
- '**/spec/**/*.rb'

Metrics/MethodLength:
Exclude:
- '**/spec/**/*.rb'

Metrics/AbcSize:
Exclude:
- '**/spec/**/*.rb'
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
source "https://rubygems.org"
source 'https://rubygems.org'

# Specify your gem's dependencies in monday-sdk-ruby.gemspec
gemspec
40 changes: 21 additions & 19 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,41 @@ PATH
remote: .
specs:
monday-sdk-ruby (0.1.0)
faraday (~> 1.0)
faraday (>= 1.0, < 3.0)
json (~> 2.3)

GEM
remote: https://rubygems.org/
specs:
diff-lcs (1.3)
faraday (1.0.0)
multipart-post (>= 1.2, < 3)
json (2.3.0)
multipart-post (2.1.1)
rake (12.3.3)
rspec (3.9.0)
rspec-core (~> 3.9.0)
rspec-expectations (~> 3.9.0)
rspec-mocks (~> 3.9.0)
rspec-core (3.9.1)
rspec-support (~> 3.9.1)
rspec-expectations (3.9.1)
diff-lcs (1.5.0)
faraday (2.7.10)
faraday-net_http (>= 2.0, < 3.1)
ruby2_keywords (>= 0.0.4)
faraday-net_http (3.0.2)
json (2.6.3)
rake (13.0.6)
rspec (3.12.0)
rspec-core (~> 3.12.0)
rspec-expectations (~> 3.12.0)
rspec-mocks (~> 3.12.0)
rspec-core (3.12.2)
rspec-support (~> 3.12.0)
rspec-expectations (3.12.3)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-mocks (3.9.1)
rspec-support (~> 3.12.0)
rspec-mocks (3.12.6)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-support (3.9.2)
rspec-support (~> 3.12.0)
rspec-support (3.12.1)
ruby2_keywords (0.0.5)

PLATFORMS
ruby

DEPENDENCIES
bundler (~> 2.1)
monday-sdk-ruby!
rake (~> 12.0)
rake (>= 12.0)
rspec (~> 3.0)

BUNDLED WITH
Expand Down
167 changes: 167 additions & 0 deletions README.md
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should resolve the documentation issue

Original file line number Diff line number Diff line change
@@ -1,2 +1,169 @@
# monday-sdk-ruby

Ruby SDK for developing over the monday.com platform

---

In order to use the APIs you need to have valid access token.
It could be short lived token received from JWT payload from Authorization header (valid for 60 seconds), or you could ask users for permanent [access token with OAuth](https://developer.monday.com/apps/docs/oauth).

## GraphQL API

All the future examples requires client instance with valid access token.

```ruby
token = "short lived access token or OAuth access token"
client = Monday::Client.new(token: token)

# you can pass a custom API endpoint
client = Monday::Client.new(token: token, api: 'https://custom.api.monday.com')

# or you can pass a custom Faraday client
connection = Faraday.new do |client|
client.request :json
client.response :raise_error
client.response :json
end
client = Monday::Client.new(token: token, conn: connection)
```

For all available queries & mutations please see the documentation in the [Public API playground](https://monday.com/developers/v2/try-it-yourself)
For more references you can look at the [JavaScript SDK docs](https://developer.monday.com/apps/docs/mondayapi)

Simple query sample:

```ruby
client.api(%(
query {
me {
name
}
}
))
```

Query with passed variables

```ruby
client.api(%(
query ($boardId: Int) {
boards(ids: [$boardId]) {
id
name
}
}
), variables: { boardId: 123_456 })
```

Mutation example

```ruby
client.api(%(
mutation ($boardId: Int!, $title: String!) {
create_column(
board_id: $boardId
title: $title
column_type: text
) { id }
}
), variables: { boardId: 123_456, title: 'Sample column' })
```

## GlobalStorage API

The most of the [JavaScript SDK documentation](https://developer.monday.com/apps/docs/mondaystorage#global-level) is relevant for Ruby.

The monday apps infrastructure includes a persistent, key-value storage that developers can leverage to store data without creating their own backend and maintaining their own database.
Storage doesn't reset between major versions since it is shared across the entire app, not just an instance.

The following limits apply to both the instance and global-level methods:

- Key length limit: 256
- Storage limit per key: 6MB

### Initializing global storage

The initializing process is the same as for the GraphQL API.

```ruby
storage = Monday::Storage.new(token: token)
```

### Set a new value

```ruby
storage.set('foo', 'test')
# => {'version' => '098f6'}

storage.set('foo', 'bar')
# => {'version' => '37b51'}
```

### Get a value:

```ruby
storage.get('foo')
# => {'value' => 'bar', 'version' => '37b51'}

storage.get('not-existed-key')
# => {'value' => nil}
```

### Delete an item:

```ruby
storage.get('foo')
# => {'value' => 'bar', 'version' => '37b51'}

storage.delete('foo')

storage.get('foo')
# => {'value' => nil}
```

### Versioning

`get` and `set` each return a version identifier you can use to identify the value currently stored in a key. Whenever a write that changes the value occurs, the version identifier in the database changes. The identifier signifies whether or not a value changed from another location and prevents it from being overwritten.

```ruby
storage.get('foo')
# => {'value' => 'bar', 'version' => '37b51'}
begin
storage.set('foo', {value: 'updated', previous_version: 'wrong'})
rescue Faraday::ConflictError => exception
# the value is not changed due to the version conflict
end
```

If you want to not raise an exception, just pass your own instance of Faraday without the `raise_error` middleware:

```ruby
connection = Faraday.new do |client|
client.request :json
client.response :json
end
storage = Monday::Storage.new(token: token, conn: connection)
```

### Access data created from the frontend

All the methods allow passing shared flag to access values scope accessible for current App's frontend instance.
Values created without this flag available only for the backend.
**Values saved with and without the flag are completely separated!**

```ruby
storage.get('foo')
# => {'value' => 'bar', 'version' => '1234a'}

storage.get('foo', shared: true)
# => {'value' => nil}

storage.set('foo', 'frontend', shared: true)
# => {'version' => 'aca33'}

storage.get('foo')
# => {'value' => 'bar', 'version' => '1234a'}

storage.get('foo', shared: true)
# => {'value' => 'frontend', 'version' => 'aca33'}
```
6 changes: 3 additions & 3 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require "bundler/gem_tasks"
require "rspec/core/rake_task"
require 'bundler/gem_tasks'
require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec)

task :default => :spec
task default: :spec
11 changes: 6 additions & 5 deletions lib/sdk.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# frozen_string_literal: true

# Monday SDK is a client to use monday REST api
module Monday
end

require 'sdk/client'
require 'sdk/constants/constants'
require 'sdk/monday_api/monday-api-client'
require 'sdk/version'
require 'faraday'
require 'json'


require 'sdk/client'
require 'sdk/storage'
require 'sdk/constants/constants'
require 'sdk/monday_api/monday_api_client'
require 'sdk/version'
33 changes: 20 additions & 13 deletions lib/sdk/client.rb
Original file line number Diff line number Diff line change
@@ -1,39 +1,46 @@
# frozen_string_literal: true

# Monday Client implementation
module Monday

class MondayClientError < StandardError; end

class Client

TOKEN_MISSING_ERROR = "Should send 'token' as an option or call mondaySdk.setToken(TOKEN)".freeze
TOKEN_MISSING_ERROR = "Should send 'token' as an option or call mondaySdk.setToken(TOKEN)"

def initialize(options = {})
@token = options[:token] # @type string , Client token provided by monday.com
@api_domain = options[:api] # @type string (optional) monday api domain cna be changed, default defined in constants
@faraday_client = options[:conn] || Faraday.new # dependency injection for testing
@api_domain = options[:api] # @type string (optional) monday api domain can be changed, default defined in constants
@connection = options[:conn] # dependency injection for testing
end

# Main entry point to the client
def api(query, options = {})
token = options[:token] || @token

if token.nil? || token.empty?
raise MondayClientError.new TOKEN_MISSING_ERROR.to_s
end
raise(MondayClientError, TOKEN_MISSING_ERROR) if token.nil? || token.empty?

params = {}
params[:query] = query
params[:variables] = options[:variables] || {}

options[:api_domain] = @api_domain || MONDAY_API_URL
options[:api_domain] = api_domain


MondayApiClient.execute(params, token, @faraday_client, options)
MondayApiClient.execute(params, token, connection, options)
end

end
private

end
def api_domain
@api_domain ||= MONDAY_API_URL
end

def connection
@connection ||= Faraday.new do |client|
client.request :json

client.response :raise_error
client.response :json
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should parse JSON in the middleware, to avoid doing this by ourselves

end
end
end
end
13 changes: 8 additions & 5 deletions lib/sdk/constants/constants.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# frozen_string_literal: true

# Constants
module Monday
MONDAY_PROTOCOL = "https".freeze
MONDAY_DOMAIN = "monday.com".freeze
MONDAY_API_URL = MONDAY_PROTOCOL+"://api."+MONDAY_DOMAIN+"/v2".freeze
MONDAY_OAUTH_URL = MONDAY_PROTOCOL+"://auth."+MONDAY_DOMAIN+"/oauth2/authorize".freeze
MONDAY_OAUTH_TOKEN_URL = MONDAY_PROTOCOL+"://auth."+MONDAY_DOMAIN+"/oauth2/token".freeze
MONDAY_PROTOCOL = 'https'
MONDAY_DOMAIN = 'monday.com'
MONDAY_API_URL = "#{MONDAY_PROTOCOL}://api.#{MONDAY_DOMAIN}/v2".freeze
MONDAY_OAUTH_URL = "#{MONDAY_PROTOCOL}://auth.#{MONDAY_DOMAIN}/oauth2/authorize".freeze
MONDAY_OAUTH_TOKEN_URL = "#{MONDAY_PROTOCOL}://auth.#{MONDAY_DOMAIN}/oauth2/token".freeze
MONDAY_STORAGE_URL = "#{MONDAY_PROTOCOL}://apps-storage.#{MONDAY_DOMAIN}/app_storage_api/v2".freeze
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the new API endpoint

end
Loading