rest-core
A modular Ruby REST client collection/infrastructure

avatar Lin Jen-Shin (godfat)


avatar Lin Jen-Shin (godfat)


avatar Lin Jen-Shin (godfat)


avatar Lin Jen-Shin (godfat)


  • Programmer at Cardinal Blue
  • Programming Language
  • Functional Programming (Haskell)

avatar Lin Jen-Shin (godfat)


  • Programmer at Cardinal Blue
  • Programming Language
  • Functional Programming (Haskell)
  • Ruby

  • Quick Example

  • Quick Example
  • Rack

  • Quick Example
  • Rack
  • Difference from Rack

  • Quick Example
  • Rack
  • Difference from Rack
  • Architecture

web-services

tools

soapbox

REST
rest

Solution: rest-core

Inspired by faraday and Rack

01 Github = RestCore::Builder.client do
02 end
01 Github = RestCore::Builder.client do
02 
03 
04 
05 end
06 
07 
01 Github = RestCore::Builder.client do
02   use DefaultSite , 'https://api.github.com/users/'
03 
04 
05 end
06 
07 
01 Github = RestCore::Builder.client do
02   use DefaultSite , 'https://api.github.com/users/'
03   use JsonDecode  , true
04 
05 end
06 
07 
01 Github = RestCore::Builder.client do
02   use DefaultSite , 'https://api.github.com/users/'
03   use JsonDecode  , true
04   run RestClient
05 end
06 
07 
01 Github = RestCore::Builder.client do
02   use DefaultSite , 'https://api.github.com/users/'
03   use JsonDecode  , true
04   run RestClient
05 end
06 
07 Github.new.get('godfat')
01 Github = RestCore::Builder.client do
02   use DefaultSite , 'https://api.github.com/users/'
03   use JsonDecode  , true
04   run RestClient
05 end
06 
07 Github.new.get('godfat')
08 
09 {"type"=>"User","company"=>"cardinalblue",
10  "blog"=>"http://godfat.org","hireable"=>false,
11  "url"=>"https://api.github.com/users/godfat",
12  "followers"=>40,"html_url"=>"https://github.com/godfat",
13  "bio"=>nil,"created_at"=>"2008-05-15T18:33:24Z",
14  "avatar_url"=>"https://...","following"=>33,
15  "name"=>"Lin Jen-Shin (godfat)","location"=>"Taiwan",
16  "email"=>"godfat (XD) godfat.org","public_repos"=>62,
17  "id"=>10416,"login"=>"godfat","public_gists"=>59}
01 Github = RestCore::Builder.client do
02   use DefaultSite , 'https://api.github.com/users/'
03   use JsonDecode  , true
04   
05   run RestClient
06 end
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
01 Github = RestCore::Builder.client do
02   use DefaultSite , 'https://api.github.com/users/'
03   use JsonDecode  , true
04   use Cache       , {}, 3600
05   run RestClient
06 end
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
01 Github = RestCore::Builder.client do
02   use DefaultSite , 'https://api.github.com/users/'
03   use JsonDecode  , true
04   use Cache       , {}, 3600
05   run RestClient
06 end
07
08 client = Github.new
09 
10 
11 
12 
13 
14 
15 
16 
17 
01 Github = RestCore::Builder.client do
02   use DefaultSite , 'https://api.github.com/users/'
03   use JsonDecode  , true
04   use Cache       , {}, 3600
05   run RestClient
06 end
07
08 client = Github.new
09 client.get('godfat') # slow
10 
11 
12 
13 
14 
15 
16 
17 
01 Github = RestCore::Builder.client do
02   use DefaultSite , 'https://api.github.com/users/'
03   use JsonDecode  , true
04   use Cache       , {}, 3600
05   run RestClient
06 end
07
08 client = Github.new
09 client.get('godfat') # slow
10 client.get('godfat') # cache hit
11 
12 
13 
14 
15 
16 
17 
01 Github = RestCore::Builder.client do
02   use DefaultSite , 'https://api.github.com/users/'
03   use JsonDecode  , true
04   use Cache       , {}, 3600
05   run RestClient
06 end
07
08 client = Github.new
09 client.get('godfat') # slow
10 client.get('godfat') # cache hit
11 client.get('godfat') # cache hit
12 
13 
14 
15 
16 
17 
01 Github = RestCore::Builder.client do
02   use DefaultSite , 'https://api.github.com/users/'
03   use JsonDecode  , true
04   use Cache       , {}, 3600
05   run RestClient
06 end
07
08 client = Github.new
09 client.get('godfat') # slow
10 client.get('godfat') # cache hit
11 client.get('godfat') # cache hit
12 client.get('godfat') # cache hit
13 
14 
15 
16 
17 
01 Github = RestCore::Builder.client do
02   use DefaultSite , 'https://api.github.com/users/'
03   use JsonDecode  , true
04   
05   use Cache       , {}, 3600
06   run RestClient
07 end
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
01 Github = RestCore::Builder.client do
02   use DefaultSite , 'https://api.github.com/users/'
03   use JsonDecode  , true
04   use CommonLogger, method(:puts)
05   use Cache       , {}, 3600
06   run RestClient
07 end
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
01 Github = RestCore::Builder.client do
02   use DefaultSite , 'https://api.github.com/users/'
03   use JsonDecode  , true
04   use CommonLogger, method(:puts)
05   use Cache       , {}, 3600
06   run RestClient
07 end
08 
09 client = Github.new
10 
11 
12 
13 
14 
15 
16 
17 
01 Github = RestCore::Builder.client do
02   use DefaultSite , 'https://api.github.com/users/'
03   use JsonDecode  , true
04   use CommonLogger, method(:puts)
05   use Cache       , {}, 3600
06   run RestClient
07 end
08 
09 client = Github.new
10 client.get('godfat') # slow
11 
12 
13 
14 
15 
16 
17 
01 Github = RestCore::Builder.client do
02   use DefaultSite , 'https://api.github.com/users/'
03   use JsonDecode  , true
04   use CommonLogger, method(:puts)
05   use Cache       , {}, 3600
06   run RestClient
07 end
08 
09 client = Github.new
10 client.get('godfat') # slow
11 # RestCore: spent 1.498819 Requested https://api.github.com/users/godfat
12 
13 
14 
15 
16 
17 
01 Github = RestCore::Builder.client do
02   use DefaultSite , 'https://api.github.com/users/'
03   use JsonDecode  , true
04   use CommonLogger, method(:puts)
05   use Cache       , {}, 3600
06   run RestClient
07 end
08 
09 client = Github.new
10 client.get('godfat') # slow
11 # RestCore: spent 1.498819 Requested https://api.github.com/users/godfat
12 client.get('godfat') # cache hit
13 
14 
15 
16 
17 
01 Github = RestCore::Builder.client do
02   use DefaultSite , 'https://api.github.com/users/'
03   use JsonDecode  , true
04   use CommonLogger, method(:puts)
05   use Cache       , {}, 3600
06   run RestClient
07 end
08 
09 client = Github.new
10 client.get('godfat') # slow
11 # RestCore: spent 1.498819 Requested https://api.github.com/users/godfat
12 client.get('godfat') # cache hit
13 # RestCore: spent 2.0e-05 CacheHit https://api.github.com/users/godfat
14 # RestCore: spent 6.9e-05 Requested https://api.github.com/users/godfat
15 
16 
17 

Web Application as servers

client-server

server-client

Web Application as clients

The History

CGI (Common Gateway Interface)

FastCGI

SCGI (Simple CGI)

Mongrel

Rack (from WSGI)






rack


01 
02   (middleware (middleware (middleware app)))
03 
04 
05 
06 

01 -- --> --> --> --> --> --> --> --> --> -->
02   (middleware (middleware (middleware app)))
03 -- <-- <-- <-- <-- <-- <-- <-- <-- <-- <--
04 
05 
06 

01 -- --> --> --> --> --> --> --> --> --> -->
02   (middleware (middleware (middleware app)))
03 -- <-- <-- <-- <-- <-- <-- <-- <-- <-- <--
04 
05 app        :: env -> response
06 

01 -- --> --> --> --> --> --> --> --> --> -->
02   (middleware (middleware (middleware app)))
03 -- <-- <-- <-- <-- <-- <-- <-- <-- <-- <--
04 
05 app        :: env -> response
06 middleware :: app -> app

01 
02   (middleware (middleware (middleware app)))
03 --                                    __^ app
04 
05 app        :: env -> response
06 middleware :: app -> app

01 
02   (middleware (middleware (middleware app)))
03 --                                    __^ app
04 --                         _____________^ app
05 app        :: env -> response
06 middleware :: app -> app

01 
02   (middleware (middleware (middleware app)))
03 --                                    __^ app
04 --                         _____________^ app
05 --             _________________________^ app
06 middleware :: app -> app

01 
02   (middleware (middleware (middleware app)))
03 --                                    __^ app
04 --                         _____________^ app
05 --             _________________________^ app
06 -- _____________________________________^ app

Composable and Reusable

Why not do the same for
Web Application as clients?

client-server

server-client

rack

middleware-large

But actually clients are more complex...

multiple-clients