hateoas 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/.rvmrc +1 -0
- data/.travis.yml +8 -0
- data/README.md +18 -107
- data/Rakefile +47 -0
- data/hateoas.gemspec +2 -0
- data/lib/hateoas.rb +59 -28
- data/lib/hateoas/version.rb +1 -1
- metadata +59 -61
- data/SPEC.md +0 -146
data/.gitignore
CHANGED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm --create use 1.9.3@hateoas
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,120 +1,31 @@
|
|
1
|
+
# Hateoas
|
1
2
|
|
2
|
-
|
3
|
-
=====
|
3
|
+
This is a Ruby gem that lets you interact with hypermedia APIs.
|
4
4
|
|
5
|
-
|
6
|
-
interface to navigate through pages, submitting forms, and caching local
|
7
|
-
responses.
|
5
|
+
It's very much in development. You shouldn't use it for anything other than giggles. And maybe Unicorns.
|
8
6
|
|
9
|
-
|
7
|
+
## Installation
|
10
8
|
|
11
|
-
|
9
|
+
Add this line to your application's Gemfile:
|
12
10
|
|
13
|
-
|
11
|
+
gem 'hateoas'
|
14
12
|
|
15
|
-
|
16
|
-
==========
|
13
|
+
And then execute:
|
17
14
|
|
18
|
-
|
15
|
+
$ bundle
|
19
16
|
|
20
|
-
|
21
|
-
gem install hateoas
|
22
|
-
```
|
17
|
+
Or install it yourself as:
|
23
18
|
|
24
|
-
|
25
|
-
=====
|
19
|
+
$ gem install hateoas
|
26
20
|
|
27
|
-
|
28
|
-
API. We'll pretend that you're writing an API to your own blogging
|
29
|
-
software, since blogs are the Rails "Hello world" project.
|
21
|
+
## Usage
|
30
22
|
|
31
|
-
|
23
|
+
Read the code. More to come when I feel like _anything_ is stable.
|
32
24
|
|
33
|
-
|
34
|
-
-------------
|
25
|
+
## Contributing
|
35
26
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
Hateoas.base_uri = "http://api.hackety-hack.com"
|
42
|
-
```
|
43
|
-
|
44
|
-
HATEOAS has environment variables that make it easy to hit your local copy in
|
45
|
-
development mode. By default, HATEOAS assumes you're using pow, and so it will
|
46
|
-
append '.dev' onto the end of your `base_uri` when it is in development
|
47
|
-
mode. To use something else, set the `development_base_uri`:
|
48
|
-
|
49
|
-
```
|
50
|
-
HATEOAS.develoment_base_uri = "http://localhost:9292"
|
51
|
-
```
|
52
|
-
|
53
|
-
The `HATEOAS_ENV` variable will control which configuration is used. Just like
|
54
|
-
Rails, there are development, test, and production modes.
|
55
|
-
|
56
|
-
In my own APIs, I prefer to use URIs for my rel attributes. If you also do
|
57
|
-
this, there's an optional variable that makes using URIs simpler. Without it,
|
58
|
-
here's how you navigate to the 'new post' page, then the 'new comments'
|
59
|
-
page:
|
60
|
-
|
61
|
-
```
|
62
|
-
Hateoas::DSL.click_link("/rels/new-post")
|
63
|
-
Hateoas::DSL.click_link("/rels/new-comments")
|
64
|
-
```
|
65
|
-
|
66
|
-
And with it:
|
67
|
-
|
68
|
-
```
|
69
|
-
Hateoas.rel_namespace = "rels"
|
70
|
-
|
71
|
-
Hateoas::DSL.click_link("new-post")
|
72
|
-
Hateoas::DSL.click_link("new-comments")
|
73
|
-
```
|
74
|
-
|
75
|
-
Groovy?
|
76
|
-
|
77
|
-
DSL
|
78
|
-
---
|
79
|
-
|
80
|
-
HATEOAS provides a `DSL` module with all of the DSL methods you'll need. You
|
81
|
-
can use these methods in two ways: One is to reference them by using their fully
|
82
|
-
qualified names:
|
83
|
-
|
84
|
-
```
|
85
|
-
Hateoas::DSL.click_link("new-post")
|
86
|
-
```
|
87
|
-
|
88
|
-
Optionally, if you're building your own infrastructure around all of this, you
|
89
|
-
can include the module inside your own class:
|
90
|
-
|
91
|
-
```
|
92
|
-
class MyApi
|
93
|
-
include Hateoas::DSL
|
94
|
-
|
95
|
-
def navigate(path)
|
96
|
-
click_link(path)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
```
|
100
|
-
|
101
|
-
The rest of this documentation will simply use `visit` rather than
|
102
|
-
`Hateoas::DSL.visit`.
|
103
|
-
|
104
|
-
Navigation
|
105
|
-
----------
|
106
|
-
|
107
|
-
If you read the previous section, you've got this one figured out: simply give
|
108
|
-
a rel to the `click_link` method:
|
109
|
-
|
110
|
-
```
|
111
|
-
click_link("new-post")
|
112
|
-
```
|
113
|
-
|
114
|
-
Getting Data Back
|
115
|
-
-----------------
|
116
|
-
|
117
|
-
You can access the data on the current page by using the `current_page`
|
118
|
-
method.
|
119
|
-
|
120
|
-
[homepage]: http://steveklabnik.github.com/cereal
|
27
|
+
1. Fork it
|
28
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
30
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
31
|
+
5. Create new Pull Request
|
data/Rakefile
CHANGED
@@ -1 +1,48 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
+
require 'rake/clean'
|
3
|
+
|
4
|
+
begin
|
5
|
+
# Bring in Rocco tasks
|
6
|
+
require 'rocco/tasks'
|
7
|
+
Rocco::make 'docs/'
|
8
|
+
|
9
|
+
desc 'Build rocco docs'
|
10
|
+
task :docs => :rocco
|
11
|
+
directory 'docs/'
|
12
|
+
|
13
|
+
file 'docs/index.html' => 'docs/lib/hateoas.html' do |f|
|
14
|
+
cp 'docs/lib/hateoas.html', 'docs/index.html', :preserve => true
|
15
|
+
end
|
16
|
+
task :docs => 'docs/index.html'
|
17
|
+
CLEAN.include 'docs/index.html'
|
18
|
+
|
19
|
+
# Alias for docs task
|
20
|
+
task :doc => :docs
|
21
|
+
|
22
|
+
# GITHUB PAGES ===============================================================
|
23
|
+
|
24
|
+
desc 'Update gh-pages branch'
|
25
|
+
task :pages => ['docs/.git', :docs] do
|
26
|
+
rev = `git rev-parse --short HEAD`.strip
|
27
|
+
Dir.chdir 'docs' do
|
28
|
+
sh "git add *.html"
|
29
|
+
sh "git commit -m 'rebuild pages from #{rev}'" do |ok,res|
|
30
|
+
if ok
|
31
|
+
verbose { puts "gh-pages updated" }
|
32
|
+
sh "git push -q o HEAD:gh-pages"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Update the pages/ directory clone
|
39
|
+
file 'docs/.git' => ['docs/', '.git/refs/heads/gh-pages'] do |f|
|
40
|
+
sh "cd docs && git init -q && git remote add o ../.git" if !File.exist?(f.name)
|
41
|
+
sh "cd docs && git fetch -q o && git reset -q --hard o/gh-pages && touch ."
|
42
|
+
end
|
43
|
+
CLOBBER.include 'docs/.git'
|
44
|
+
|
45
|
+
rescue LoadError => e
|
46
|
+
puts "Something with rocco didn't load, you can't build the docs! Try bundle install?"
|
47
|
+
end
|
48
|
+
|
data/hateoas.gemspec
CHANGED
data/lib/hateoas.rb
CHANGED
@@ -1,43 +1,74 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
require '
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
require 'forwardable'
|
4
|
+
require 'nokogiri'
|
4
5
|
|
5
6
|
module Hateoas
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
7
|
+
module MediaType
|
8
|
+
def self.included(including_class)
|
9
|
+
including_class.class_eval do
|
10
|
+
def self.media_type(type)
|
11
|
+
@media_type = type
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.serialization(type)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.element(*elements)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.attribute(*attributes)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.relation(*relations)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.action(*actions)
|
27
|
+
@actions = actions
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.actions
|
31
|
+
@actions
|
32
|
+
end
|
15
33
|
end
|
16
34
|
end
|
17
35
|
|
18
|
-
|
19
|
-
|
20
|
-
|
36
|
+
class Request
|
37
|
+
extend Forwardable
|
38
|
+
def_delegators :@uri, :request_uri, :hostname, :port
|
21
39
|
|
22
|
-
|
23
|
-
|
24
|
-
|
40
|
+
def initialize(url, media_type)
|
41
|
+
@uri = URI(url)
|
42
|
+
@media_type = media_type
|
43
|
+
end
|
25
44
|
|
26
|
-
|
27
|
-
|
45
|
+
def get
|
46
|
+
req = Net::HTTP::Get.new(request_uri)
|
47
|
+
req['Accept'] = @media_type
|
48
|
+
|
49
|
+
Net::HTTP.start(hostname, port) {|http| http.request(req) }.body
|
50
|
+
end
|
28
51
|
end
|
29
52
|
|
30
|
-
|
53
|
+
def media_type; @media_type; end
|
54
|
+
def data; @data; end
|
55
|
+
|
56
|
+
def actions
|
57
|
+
self.class.actions.select{|rel| relation_exists?(rel) }
|
58
|
+
end
|
31
59
|
|
32
|
-
|
33
|
-
|
60
|
+
def initialize(uri)
|
61
|
+
@data = Nokogiri::XML(Request.new(uri, @media_type).get)
|
62
|
+
end
|
34
63
|
|
35
|
-
def
|
36
|
-
|
37
|
-
|
38
|
-
end
|
64
|
+
def relation_exists?(rel)
|
65
|
+
@data.xpath("//*[@rel='#{rel}']").first
|
66
|
+
end
|
39
67
|
|
40
|
-
|
68
|
+
def transition(rel)
|
69
|
+
node = @data.xpath("//*[@rel='#{rel}']").first
|
70
|
+
return unless node
|
71
|
+
@data = Nokogiri::XML(Request.new(node[:href], @media_type).get)
|
41
72
|
end
|
42
73
|
end
|
43
74
|
end
|
data/lib/hateoas/version.rb
CHANGED
metadata
CHANGED
@@ -1,100 +1,98 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: hateoas
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 0
|
9
|
-
- 1
|
10
|
-
version: 0.0.1
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Steve Klabnik
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-02-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: mechanize
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70282849544420 !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
26
|
-
- -
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
segments:
|
30
|
-
- 0
|
31
|
-
version: "0"
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
32
22
|
type: :runtime
|
33
|
-
|
34
|
-
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70282849544420
|
25
|
+
- !ruby/object:Gem::Dependency
|
35
26
|
name: rspec
|
27
|
+
requirement: &70282849543940 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
36
34
|
prerelease: false
|
37
|
-
|
35
|
+
version_requirements: *70282849543940
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
requirement: &70282849543520 !ruby/object:Gem::Requirement
|
38
39
|
none: false
|
39
|
-
requirements:
|
40
|
-
- -
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
|
43
|
-
segments:
|
44
|
-
- 0
|
45
|
-
version: "0"
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
46
44
|
type: :development
|
47
|
-
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70282849543520
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: pygmentize
|
49
|
+
requirement: &70282849543100 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70282849543100
|
48
58
|
description: A set of tools to help build clients for Hypermedia APIs.
|
49
|
-
email:
|
59
|
+
email:
|
50
60
|
- steve@steveklabnik.com
|
51
61
|
executables: []
|
52
|
-
|
53
62
|
extensions: []
|
54
|
-
|
55
63
|
extra_rdoc_files: []
|
56
|
-
|
57
|
-
files:
|
64
|
+
files:
|
58
65
|
- .gitignore
|
66
|
+
- .rvmrc
|
67
|
+
- .travis.yml
|
59
68
|
- Gemfile
|
60
69
|
- README.md
|
61
70
|
- Rakefile
|
62
|
-
- SPEC.md
|
63
71
|
- hateoas.gemspec
|
64
72
|
- lib/hateoas.rb
|
65
73
|
- lib/hateoas/version.rb
|
66
74
|
homepage: http://steveklabnik.github.com/hateoas
|
67
75
|
licenses: []
|
68
|
-
|
69
76
|
post_install_message:
|
70
77
|
rdoc_options: []
|
71
|
-
|
72
|
-
require_paths:
|
78
|
+
require_paths:
|
73
79
|
- lib
|
74
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
81
|
none: false
|
76
|
-
requirements:
|
77
|
-
- -
|
78
|
-
- !ruby/object:Gem::Version
|
79
|
-
|
80
|
-
|
81
|
-
- 0
|
82
|
-
version: "0"
|
83
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
87
|
none: false
|
85
|
-
requirements:
|
86
|
-
- -
|
87
|
-
- !ruby/object:Gem::Version
|
88
|
-
|
89
|
-
segments:
|
90
|
-
- 0
|
91
|
-
version: "0"
|
88
|
+
requirements:
|
89
|
+
- - ! '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
92
|
requirements: []
|
93
|
-
|
94
93
|
rubyforge_project:
|
95
|
-
rubygems_version: 1.8.
|
94
|
+
rubygems_version: 1.8.16
|
96
95
|
signing_key:
|
97
96
|
specification_version: 3
|
98
97
|
summary: Build easy clients for Hypermedia APIs.
|
99
98
|
test_files: []
|
100
|
-
|
data/SPEC.md
DELETED
@@ -1,146 +0,0 @@
|
|
1
|
-
|
2
|
-
About
|
3
|
-
=====
|
4
|
-
|
5
|
-
HATEOAS helps you build hypermedia API clients, by providing a simple
|
6
|
-
interface to navigate through pages, submitting forms, and caching local
|
7
|
-
responses.
|
8
|
-
|
9
|
-
The current version is 0.0.1.
|
10
|
-
|
11
|
-
Find out more at [the hateoas homepage][homepage].
|
12
|
-
|
13
|
-
Installing
|
14
|
-
==========
|
15
|
-
|
16
|
-
Become a HATEr by using Rubygems:
|
17
|
-
|
18
|
-
```
|
19
|
-
gem install hateoas
|
20
|
-
```
|
21
|
-
|
22
|
-
Usage
|
23
|
-
=====
|
24
|
-
|
25
|
-
Primarily, you'll use HATEOAS to help create your own gem to interact with your
|
26
|
-
API. We'll pretend that you're writing an API to your own blogging
|
27
|
-
software, since blogs are the Rails "Hello world" project.
|
28
|
-
|
29
|
-
Right now, HATEOAS assumes that you use XHTML5 to drive your API.
|
30
|
-
|
31
|
-
Configuration
|
32
|
-
-------------
|
33
|
-
|
34
|
-
The first thing you need to do is configure HATEOAS. Congratulations on
|
35
|
-
creating a hypermedia API; it means the configuration is minimal! Simply
|
36
|
-
assign your root URI like this:
|
37
|
-
|
38
|
-
```
|
39
|
-
Hateoas.base_uri = "http://api.hackety-hack.com"
|
40
|
-
```
|
41
|
-
|
42
|
-
HATEOAS has environment variables that make it easy to hit your local copy in
|
43
|
-
development mode. By default, HATEOAS assumes you're using pow, and so it will
|
44
|
-
append '.dev' onto the end of your `base_uri` when it is in development
|
45
|
-
mode. To use something else, set the `development_base_uri`:
|
46
|
-
|
47
|
-
```
|
48
|
-
HATEOAS.develoment_base_uri = "http://localhost:9292"
|
49
|
-
```
|
50
|
-
|
51
|
-
The `HATEOAS_ENV` variable will control which configuration is used. Just like
|
52
|
-
Rails, there are development, test, and production modes.
|
53
|
-
|
54
|
-
In my own APIs, I prefer to use URIs for my rel attributes. If you also do
|
55
|
-
this, there's an optional variable that makes using URIs simpler. Without it,
|
56
|
-
here's how you navigate to the 'new post' page, then the 'new comments'
|
57
|
-
page:
|
58
|
-
|
59
|
-
```
|
60
|
-
Hateoas::DSL.click_link("/rels/new-post")
|
61
|
-
Hateoas::DSL.click_link("/rels/new-comments")
|
62
|
-
```
|
63
|
-
|
64
|
-
And with it:
|
65
|
-
|
66
|
-
```
|
67
|
-
Hateoas.rel_namespace = "rels"
|
68
|
-
|
69
|
-
Hateoas::DSL.click_link("new-post")
|
70
|
-
Hateoas::DSL.click_link("new-comments")
|
71
|
-
```
|
72
|
-
|
73
|
-
Groovy?
|
74
|
-
|
75
|
-
DSL
|
76
|
-
---
|
77
|
-
|
78
|
-
HATEOAS provides a `DSL` module with all of the DSL methods you'll need. You
|
79
|
-
can use these methods in two ways: One is to reference them by using their fully
|
80
|
-
qualified names:
|
81
|
-
|
82
|
-
```
|
83
|
-
Hateoas::DSL.click_link("new-post")
|
84
|
-
```
|
85
|
-
|
86
|
-
Optionally, if you're building your own infrastructure around all of this, you
|
87
|
-
can include the module inside your own class:
|
88
|
-
|
89
|
-
```
|
90
|
-
class MyApi
|
91
|
-
include Hateoas::DSL
|
92
|
-
|
93
|
-
def navigate(path)
|
94
|
-
click_link(path)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
```
|
98
|
-
|
99
|
-
The rest of this documentation will simply use `visit` rather than
|
100
|
-
`Hateoas::DSL.visit`.
|
101
|
-
|
102
|
-
Navigation
|
103
|
-
----------
|
104
|
-
|
105
|
-
If you read the previous section, you've got this one figured out: simply give
|
106
|
-
a rel to the `click_link` method:
|
107
|
-
|
108
|
-
```
|
109
|
-
click_link("new-post")
|
110
|
-
```
|
111
|
-
|
112
|
-
Getting Data Back
|
113
|
-
-----------------
|
114
|
-
|
115
|
-
You can access the data on the current page by using the `current_page`
|
116
|
-
method.
|
117
|
-
|
118
|
-
Forms
|
119
|
-
-----
|
120
|
-
|
121
|
-
There are a few methods to interact with forms:
|
122
|
-
|
123
|
-
```
|
124
|
-
fill_in('First Name', :with => 'John')
|
125
|
-
fill_in('Password', :with => 'Seekrit')
|
126
|
-
fill_in('Description', :with => 'Really Long Text...')
|
127
|
-
choose('A Radio Button')
|
128
|
-
check('A Checkbox')
|
129
|
-
uncheck('A Checkbox')
|
130
|
-
attach_file('Image', '/path/to/image.jpg')
|
131
|
-
select('Option', :from => 'Select Box')
|
132
|
-
```
|
133
|
-
|
134
|
-
Caching
|
135
|
-
-------
|
136
|
-
|
137
|
-
HATEOAS includes a client-side cache, and respects HTTP caching directives.
|
138
|
-
This helps with performance, and keeps network connections down.
|
139
|
-
|
140
|
-
Authorization
|
141
|
-
-------------
|
142
|
-
|
143
|
-
Authentication
|
144
|
-
--------------
|
145
|
-
|
146
|
-
[homepage]: http://steveklabnik.github.com/cereal
|