Skip to content

Commit

Permalink
Rewrite API to match JS SDK semantics
Browse files Browse the repository at this point in the history
A number of changes to conform to the standards set up in the official JS SDK.

- Resources are now namespaced on the client. Rather than calling
  `client#get_users`, for example, you now call `client#users.list`.
- Prefer `list` and `retrieve` over `get`.
- Rename endpoints to resources.
- Not all API interactions deal with resources. `search` is moved into
  its own operations/ folder.
  • Loading branch information
mgmarlow committed May 23, 2021
1 parent 9682574 commit d21210c
Show file tree
Hide file tree
Showing 22 changed files with 351 additions and 163 deletions.
71 changes: 44 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,41 @@ And then execute:

$ bundle install

Or install it yourself as:

$ gem install notion-sdk-ruby

## Usage

Initialize `Notion::Client` with your app's [integration secret](https://developers.notion.com/docs/getting-started#create-a-new-integration).

```rb
require "notion-sdk-ruby"
client = Notion::Client.new(token: ENV["NOTION_API_SECRET"])

# get users
client.get_users
```

## API reference

### Databases

#### #get_database
#### databases#retrieve

[API reference](https://developers.notion.com/reference/get-database)

```rb
client.get_database("668d797c-76fa-4934-9b05-ad288df2d136")
client.databases.retrieve("668d797c-76fa-4934-9b05-ad288df2d136")
```

#### #get_databases
#### databases#list

[API reference](https://developers.notion.com/reference/get-databases)

```rb
client.get_databases
client.databases.list
```

#### #query_database
#### databases#query

[API reference](https://developers.notion.com/reference/post-database-query)

```rb
client.query_database("668d797c-76fa-4934-9b05-ad288df2d136", {
client.databases.query("668d797c-76fa-4934-9b05-ad288df2d136", {
"filter": {
"or": [
{
Expand Down Expand Up @@ -75,16 +76,20 @@ client.query_database("668d797c-76fa-4934-9b05-ad288df2d136", {

### Pages

#### #get_page
#### pages#retrieve

[API reference](https://developers.notion.com/reference/get-page)

```rb
client.get_page("b55c9c91-384d-452b-81db-d1ef79372b75")
client.pages.retrieve("b55c9c91-384d-452b-81db-d1ef79372b75")
```

#### #create_page
#### pages#create

[API reference](https://developers.notion.com/reference/post-page)

```rb
client.create_page({
client.pages.create({
"parent": { "database_id": "48f8fee9cd794180bc2fec0398253067" },
"properties": {
"Name": {
Expand Down Expand Up @@ -116,10 +121,12 @@ client.create_page({
})
```

#### #update_page
#### pages#update

[API reference](https://developers.notion.com/reference/patch-page)

```rb
client.update_page("b55c9c91-384d-452b-81db-d1ef79372b75", {
client.pages.update("b55c9c91-384d-452b-81db-d1ef79372b75", {
"properties": {
"In stock": { "checkbox": true }
}
Expand All @@ -128,18 +135,22 @@ client.update_page("b55c9c91-384d-452b-81db-d1ef79372b75", {

### Blocks

#### #get_block_children
#### blocks#children#list

[API reference](https://developers.notion.com/reference/get-block-children)

```rb
client.get_block_children("b55c9c91-384d-452b-81db-d1ef79372b75", {
client.blocks.children.list("b55c9c91-384d-452b-81db-d1ef79372b75", {
page_size: 100
})
```

#### #append_block_children
#### blocks#children#append

[API reference](https://developers.notion.com/reference/patch-block-children)

```rb
client.append_block_children("b54c9c91-384d-452b-81db-d1ef79372b75", {
client.blocks.children.append("b54c9c91-384d-452b-81db-d1ef79372b75", {
"children": [
{
"object": "block",
Expand Down Expand Up @@ -169,20 +180,26 @@ client.append_block_children("b54c9c91-384d-452b-81db-d1ef79372b75", {

### Users

#### #get_user
#### users#retrieve

[API reference](https://developers.notion.com/reference/get-user)

```rb
client.get_user("d40e767c-d7af-4b18-a86d-55c61f1e39a4")
client.users.retrieve("d40e767c-d7af-4b18-a86d-55c61f1e39a4")
```

#### #get_users
#### users#list

[API reference](https://developers.notion.com/reference/get-users)

```rb
client.get_users
client.users.list
```

### Search

[API reference](https://developers.notion.com/reference/post-search)

#### #search

```rb
Expand Down
1 change: 1 addition & 0 deletions bin/console
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ require 'dotenv/load'
require "notion-sdk-ruby"

$client = Notion::Client.new(token: ENV["API_SECRET"])
$client2 = Notion::Client.new(token: ENV["API_SECRET"])

Pry.start
17 changes: 15 additions & 2 deletions lib/notion-sdk-ruby.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
require "httparty"
require "forwardable"

require "notion-sdk-ruby/version"

require "notion-sdk-ruby/config"
require "notion-sdk-ruby/resources/blocks"
require "notion-sdk-ruby/resources/databases"
require "notion-sdk-ruby/resources/pages"
require "notion-sdk-ruby/resources/search"
require "notion-sdk-ruby/resources/users"
require "notion-sdk-ruby/resources"
require "notion-sdk-ruby/operations/search"
require "notion-sdk-ruby/error"
require "notion-sdk-ruby/request_client"
require "notion-sdk-ruby/client"

module Notion
@config = Config.new

class << self
extend Forwardable

attr_reader :config

def_delegators :@config, :api_token, :api_token=
end
end
43 changes: 10 additions & 33 deletions lib/notion-sdk-ruby/client.rb
Original file line number Diff line number Diff line change
@@ -1,48 +1,25 @@
module Notion
class Client
include HTTParty
include Resources

base_uri "https://api.notion.com"
headers "Content-Type": "application/json"
include Operations::Search

def initialize(token:)
self.class.headers({Authorization: "Bearer #{token}"})
end

private

def get(*args, &block)
response = self.class.get(*args, &block)
raise_on_failure(response)
end

def post(*args, &block)
response = self.class.post(*args, &block)
raise_on_failure(response)
Notion.api_token = token
end

def patch(*args, &block)
response = self.class.patch(*args, &block)
raise_on_failure(response)
def blocks
Blocks.new
end

def put(*args, &block)
response = self.class.put(*args, &block)
raise_on_failure(response)
def databases
Databases.new
end

def delete(*args, &block)
response = self.class.delete(*args, &block)
raise_on_failure(response)
def pages
Pages.new
end

def raise_on_failure(response)
if response.success?
response
else
raise ErrorFactory.create(response)
end
def users
Users.new
end
end
end
5 changes: 5 additions & 0 deletions lib/notion-sdk-ruby/config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module Notion
class Config
attr_accessor :api_token
end
end
4 changes: 2 additions & 2 deletions lib/notion-sdk-ruby/error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ module Notion
}

class ErrorFactory
def self.create(error = nil)
return NotionError.new("Unknown error.") if error.nil? || error["message"].nil?
def self.create(error = {})
return NotionError.new("Unknown error.") if error["message"].nil?

if API_ERROR_CODE.value?(error["code"])
APIResponseError.new(error["message"], body: error)
Expand Down
9 changes: 9 additions & 0 deletions lib/notion-sdk-ruby/operations/search.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Notion
module Operations
module Search
def search(body)
RequestClient.active_client.post("/v1/search", body: body.to_json)
end
end
end
end
49 changes: 49 additions & 0 deletions lib/notion-sdk-ruby/request_client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
module Notion
class RequestClient
include HTTParty

base_uri "https://api.notion.com"
headers "Content-Type": "application/json"

def self.active_client
RequestClient.new(Notion.config)
end

def initialize(config)
self.class.headers Authorization: "Bearer #{config.api_token}"
end

def get(*args, &block)
response = self.class.get(*args, &block)
raise_on_failure(response)
end

def post(*args, &block)
response = self.class.post(*args, &block)
raise_on_failure(response)
end

def patch(*args, &block)
response = self.class.patch(*args, &block)
raise_on_failure(response)
end

def put(*args, &block)
response = self.class.put(*args, &block)
raise_on_failure(response)
end

def delete(*args, &block)
response = self.class.delete(*args, &block)
raise_on_failure(response)
end

def raise_on_failure(response)
if response.success?
response
else
raise ErrorFactory.create(response)
end
end
end
end
9 changes: 0 additions & 9 deletions lib/notion-sdk-ruby/resources.rb

This file was deleted.

16 changes: 11 additions & 5 deletions lib/notion-sdk-ruby/resources/blocks.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
module Notion
module Blocks
def get_block_children(id, params: {})
get("/v1/blocks/#{id}/children", query: params)
class Blocks
def children
Children.new
end
end

class Children
def list(block_id, query: {})
RequestClient.active_client.get("/v1/blocks/#{block_id}/children", query: query)
end

def append_block_children(id, body)
patch("/v1/blocks/#{id}/children", body: body.to_json)
def append(block_id, body)
RequestClient.active_client.patch("/v1/blocks/#{block_id}/children", body: body.to_json)
end
end
end
14 changes: 7 additions & 7 deletions lib/notion-sdk-ruby/resources/databases.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
module Notion
module Databases
def get_database(id)
get("/v1/databases/#{id}")
class Databases
def retrieve(id)
RequestClient.active_client.get("/v1/databases/#{id}")
end

def get_databases
get("/v1/databases")
def list
RequestClient.active_client.get("/v1/databases")
end

def query_database(id, body)
post("/v1/databases/#{id}/query", body: body.to_json)
def query(id, body)
RequestClient.active_client.post("/v1/databases/#{id}/query", body: body.to_json)
end
end
end
Loading

0 comments on commit d21210c

Please sign in to comment.