acfs 0.5.1 → 0.6.0
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.
- checksums.yaml +4 -4
- data/README.md +74 -32
- data/acfs.gemspec +1 -0
- data/lib/acfs.rb +12 -3
- data/lib/acfs/middleware/base.rb +1 -1
- data/lib/acfs/middleware/json_decoder.rb +2 -1
- data/lib/acfs/middleware/msgpack_decoder.rb +26 -0
- data/lib/acfs/model/query_methods.rb +36 -17
- data/lib/acfs/request.rb +3 -0
- data/lib/acfs/request/callbacks.rb +7 -2
- data/lib/acfs/response/formats.rb +3 -3
- data/lib/acfs/version.rb +2 -2
- data/spec/acfs/middleware/msgpack_decoder_spec.rb +45 -0
- data/spec/acfs/request/callbacks_spec.rb +14 -2
- data/spec/acfs/response/formats_spec.rb +4 -4
- data/spec/acfs_spec.rb +32 -0
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36f33bb4ccf82d17ac10c0c1a142476817229231
|
4
|
+
data.tar.gz: a881457d71f8437c9f81466e928eb4e7cb57df90
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fcb651f2c3c488d05fdebcd2a63ac2c6612a5d19188519456a1d690cccfe6fdc7786aeeddef7ae6dd30170aa9cc11a4b342037d2102ed4eb67d1b983950e8922
|
7
|
+
data.tar.gz: eed4cc6c2c6dd9071c40c22fc5786541e7c5e615e708affe2d772e5d7a6e2c9005cb2d97e664bef9acad7cf222fa16904282797a7da1b27c4255a586c65f1aeb
|
data/README.md
CHANGED
@@ -10,10 +10,10 @@ TODO: Write a gem description
|
|
10
10
|
|
11
11
|
Add this line to your application's Gemfile:
|
12
12
|
|
13
|
-
gem 'acfs', '0.
|
13
|
+
gem 'acfs', '0.6.0'
|
14
14
|
|
15
|
-
**Note:** Acfs is under development.
|
16
|
-
|
15
|
+
**Note:** Acfs is under development. I'll try to avoid changes to the public
|
16
|
+
API but internal APIs may change quite often.
|
17
17
|
|
18
18
|
And then execute:
|
19
19
|
|
@@ -25,71 +25,113 @@ Or install it yourself as:
|
|
25
25
|
|
26
26
|
## Usage
|
27
27
|
|
28
|
-
|
28
|
+
First you need to define your service(s):
|
29
29
|
|
30
30
|
```ruby
|
31
|
-
class
|
32
|
-
|
33
|
-
|
34
|
-
attribute :name, :string
|
35
|
-
attribute :age, :integer, default: 15
|
31
|
+
class UserService < Acfs::Service
|
32
|
+
self.base_url = 'http://users.myapp.org'
|
36
33
|
end
|
37
|
-
|
38
|
-
MyModel.attributes # => { "name" => "", "age" => 15 }
|
39
|
-
|
40
|
-
mo = MyModel.new name: 'Johnny', age: 12
|
41
|
-
mo.name # => "Johnny"
|
42
|
-
mo.age = '13'
|
43
|
-
mo.age # => 13
|
44
|
-
mo.attributes # => { "name" => "Johnny", "age" => 13 }
|
45
34
|
```
|
46
35
|
|
47
|
-
|
36
|
+
This specifies where the `UserService` can be reached. You can now create some
|
37
|
+
models representing resources serviced by the `UserService`.
|
48
38
|
|
49
39
|
```ruby
|
50
|
-
class MyService < Acfs::Service
|
51
|
-
self.base_url = 'http://acc.srv'
|
52
|
-
end
|
53
|
-
|
54
40
|
class User
|
55
41
|
include Acfs::Model
|
56
|
-
service
|
42
|
+
service UserService # Associate `User` model with `UserService`.
|
43
|
+
|
44
|
+
# Define model attributes and types
|
45
|
+
# Types are needed to parse and generate request and response payload.
|
46
|
+
|
47
|
+
attribute :id, :uuid # Types can be classes or symbols.
|
48
|
+
# Symbols will be used to load a class from `Acfs::Model::Attributes` namespace.
|
49
|
+
# Eg. `:uuid` will load class `Acfs::Model::Attributes::Uuid`.
|
50
|
+
|
51
|
+
attribute :name, :string, default: 'Anonymous'
|
52
|
+
attribute :age, ::Acfs::Model::Attributes::Integer # Or use :integer
|
57
53
|
|
58
|
-
attribute :id, :integer
|
59
54
|
end
|
55
|
+
```
|
60
56
|
|
57
|
+
The service and model classes can be shipped as a gem or git submodule to be
|
58
|
+
included by the frontend application(s).
|
59
|
+
|
60
|
+
You can use the model there:
|
61
|
+
|
62
|
+
```ruby
|
61
63
|
@user = User.find 14
|
62
64
|
|
63
65
|
@user.loaded? #=> false
|
64
66
|
|
65
67
|
Acfs.run # This will run all queued request as parallel as possible.
|
66
68
|
# For @user the following URL will be requested:
|
67
|
-
# `http://
|
69
|
+
# `http://users.myapp.org/users/14`
|
68
70
|
|
69
71
|
@model.name # => "..."
|
70
72
|
|
71
73
|
@users = User.all
|
72
74
|
@users.loaded? #=> false
|
73
75
|
|
74
|
-
Acfs.run # Will request `http://
|
76
|
+
Acfs.run # Will request `http://users.myapp.org/users`
|
75
77
|
|
76
78
|
@users #=> [<User>, ...]
|
77
79
|
```
|
78
80
|
|
81
|
+
If you need multiple resources or dependent resources first define a "plan"
|
82
|
+
how they can be loaded:
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
@user = User.find(5) do |user|
|
86
|
+
# Block will be executed right after user with id 5 is loaded
|
87
|
+
|
88
|
+
# You can load additional resources also from other services
|
89
|
+
# Eg. fetch comments from `CommentSerivce`. The line below will
|
90
|
+
# load comments from `http://comments.myapp.org/comments?user=5`
|
91
|
+
@comments = Comment.where user: user.id
|
92
|
+
|
93
|
+
# You can load multiple resources in parallel if you have multiple
|
94
|
+
# ids.
|
95
|
+
@friends = User.find 1, 4, 10 do |friends|
|
96
|
+
# This block will be executed when all friends are loaded.
|
97
|
+
# [ ... ]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
Acfs.run # This call will fire all request as parallel as possible.
|
102
|
+
# The sequence above would look similar to:
|
103
|
+
#
|
104
|
+
# Start Fin
|
105
|
+
# |===================| `Acfs.run`
|
106
|
+
# |====| /users/5
|
107
|
+
# | |==============| /comments?user=5
|
108
|
+
# | |======| /users/1
|
109
|
+
# | |=======| /users/4
|
110
|
+
# | |======| /users/10
|
111
|
+
|
112
|
+
# Now we can access all resources:
|
113
|
+
|
114
|
+
@user.name # => "John
|
115
|
+
@comments.size # => 25
|
116
|
+
@friends[0].name # => "Miraculix"
|
117
|
+
|
79
118
|
## TODO
|
80
119
|
|
81
|
-
*
|
120
|
+
* Create/Update operations
|
121
|
+
* High level features
|
122
|
+
** Pagination? Filtering? (If service API provides such features.)
|
123
|
+
** Messaging Queue support for services and models
|
82
124
|
* Documentation
|
83
125
|
|
84
126
|
## Contributing
|
85
127
|
|
86
128
|
1. Fork it
|
87
129
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
130
|
+
3a. Add specs for your feature
|
131
|
+
3b. Implement your feature
|
132
|
+
3c. Commit your changes (`git commit -am 'Add some feature'`)
|
133
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
134
|
+
5. Create new Pull Request
|
93
135
|
|
94
136
|
## License
|
95
137
|
|
data/acfs.gemspec
CHANGED
data/lib/acfs.rb
CHANGED
@@ -17,6 +17,7 @@ module Acfs
|
|
17
17
|
autoload :Base
|
18
18
|
autoload :Print
|
19
19
|
autoload :JsonDecoder
|
20
|
+
autoload :MessagePackDecoder, 'acfs/middleware/msgpack_decoder'
|
20
21
|
end
|
21
22
|
|
22
23
|
module Adapter
|
@@ -33,9 +34,9 @@ module Acfs
|
|
33
34
|
end
|
34
35
|
|
35
36
|
def queue(req, &block)
|
36
|
-
request =
|
37
|
+
request = Request.new req
|
37
38
|
request.on_complete &block if block_given?
|
38
|
-
|
39
|
+
middleware.call request
|
39
40
|
end
|
40
41
|
|
41
42
|
def adapter
|
@@ -43,7 +44,9 @@ module Acfs
|
|
43
44
|
end
|
44
45
|
|
45
46
|
def middleware
|
46
|
-
@middleware ||=
|
47
|
+
@middleware ||= proc do |request|
|
48
|
+
adapter.queue request
|
49
|
+
end
|
47
50
|
end
|
48
51
|
|
49
52
|
def use(klass, options = {})
|
@@ -54,5 +57,11 @@ module Acfs
|
|
54
57
|
@middlewares << klass
|
55
58
|
@middleware = klass.new(middleware, options)
|
56
59
|
end
|
60
|
+
|
61
|
+
def clear
|
62
|
+
@middleware = nil
|
63
|
+
@middlewares = nil
|
64
|
+
end
|
57
65
|
end
|
58
66
|
end
|
67
|
+
|
data/lib/acfs/middleware/base.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'msgpack'
|
2
|
+
require 'action_dispatch'
|
3
|
+
|
4
|
+
module Acfs
|
5
|
+
module Middleware
|
6
|
+
|
7
|
+
# Register msgpack mime type
|
8
|
+
::Mime::Type.register 'application/x-msgpack', :msgpack
|
9
|
+
|
10
|
+
# A middleware to decode Message Pack responses.
|
11
|
+
#
|
12
|
+
class MessagePackDecoder < Base
|
13
|
+
|
14
|
+
CONTENT_TYPES = %w(application/x-msgpack)
|
15
|
+
|
16
|
+
def response(response, nxt)
|
17
|
+
response.data = ::MessagePack.load(response.body) if message_pack?(response)
|
18
|
+
nxt.call response
|
19
|
+
end
|
20
|
+
|
21
|
+
def message_pack?(response)
|
22
|
+
CONTENT_TYPES.include? response.content_type
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -21,25 +21,15 @@ module Acfs::Model
|
|
21
21
|
# Try to load a resource by given id.
|
22
22
|
#
|
23
23
|
# Example
|
24
|
-
# User.find(5)
|
24
|
+
# User.find(5) # Will query `http://base.url/users/5`
|
25
|
+
# User.find(1, 2, 5) # Will return collection and will query
|
26
|
+
# # `http://base.url/users/1`, `http://base.url/users/2`
|
27
|
+
# # and `http://base.url/users/5` parallel
|
25
28
|
#
|
26
|
-
def find(
|
27
|
-
|
28
|
-
|
29
|
-
request = case id
|
30
|
-
when Hash
|
31
|
-
Acfs::Request.new url, params: id
|
32
|
-
else
|
33
|
-
Acfs::Request.new url(id.to_s)
|
34
|
-
end
|
29
|
+
def find(*attrs, &block)
|
30
|
+
opts = attrs.extract_options!
|
35
31
|
|
36
|
-
|
37
|
-
model.attributes = response.data
|
38
|
-
model.loaded!
|
39
|
-
block.call model unless block.nil?
|
40
|
-
end
|
41
|
-
|
42
|
-
model
|
32
|
+
attrs.size > 1 ? find_multiple(attrs, opts, &block) : find_single(attrs[0], opts, &block)
|
43
33
|
end
|
44
34
|
|
45
35
|
# Try to load all resources.
|
@@ -61,6 +51,35 @@ module Acfs::Model
|
|
61
51
|
collection
|
62
52
|
end
|
63
53
|
alias :where :all
|
54
|
+
|
55
|
+
private
|
56
|
+
def find_single(id, opts, &block)
|
57
|
+
model = self.new
|
58
|
+
|
59
|
+
request = Acfs::Request.new url(id.to_s)
|
60
|
+
service.queue(request) do |response|
|
61
|
+
model.attributes = response.data
|
62
|
+
model.loaded!
|
63
|
+
block.call model unless block.nil?
|
64
|
+
end
|
65
|
+
|
66
|
+
model
|
67
|
+
end
|
68
|
+
|
69
|
+
def find_multiple(ids, opts, &block)
|
70
|
+
::Acfs::Collection.new.tap do |collection|
|
71
|
+
counter = 0
|
72
|
+
ids.each do |id|
|
73
|
+
find_single id, opts do |resource|
|
74
|
+
collection << resource
|
75
|
+
if (counter += 1) == ids.size
|
76
|
+
collection.loaded!
|
77
|
+
block.call collection unless block.nil?
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
64
83
|
end
|
65
84
|
end
|
66
85
|
end
|
data/lib/acfs/request.rb
CHANGED
@@ -21,7 +21,7 @@ module Acfs
|
|
21
21
|
# @return [ Acfs::Request ] The request itself.
|
22
22
|
#
|
23
23
|
def on_complete(&block)
|
24
|
-
callbacks
|
24
|
+
callbacks.insert 0, block if block_given?
|
25
25
|
self
|
26
26
|
end
|
27
27
|
|
@@ -38,9 +38,14 @@ module Acfs
|
|
38
38
|
# @return [ Acfs::Request ] The request itself.
|
39
39
|
#
|
40
40
|
def complete!(response)
|
41
|
-
|
41
|
+
call_callback response, 0
|
42
42
|
self
|
43
43
|
end
|
44
|
+
|
45
|
+
private
|
46
|
+
def call_callback(res, index)
|
47
|
+
callbacks[index].call res, proc { |res| call_callback res, index + 1 } if index < callbacks.size
|
48
|
+
end
|
44
49
|
end
|
45
50
|
end
|
46
51
|
end
|
@@ -6,15 +6,15 @@ module Acfs
|
|
6
6
|
# Quick accessors for format handling.
|
7
7
|
module Formats
|
8
8
|
|
9
|
-
def
|
10
|
-
@
|
9
|
+
def content_type
|
10
|
+
@content_type ||= begin
|
11
11
|
content_type = headers['Content-Type'].split(/;\s*\w+="?\w+"?/).first
|
12
12
|
Mime::Type.parse(content_type).first
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
def json?
|
17
|
-
|
17
|
+
content_type == Mime::JSON
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
data/lib/acfs/version.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Acfs::Middleware::MessagePackDecoder do
|
4
|
+
let(:data) { [{id: 1, name: "Anon"},{id: 2, name:"John", friends: [ 1 ]}] }
|
5
|
+
let(:body) { data.to_param }
|
6
|
+
let(:headers) { {} }
|
7
|
+
let(:request) { Acfs::Request.new "fubar" }
|
8
|
+
let(:response) { Acfs::Response.new request, 200, headers, body }
|
9
|
+
let(:decoder) { Acfs::Middleware::MessagePackDecoder.new lambda { |req| req } }
|
10
|
+
|
11
|
+
before do
|
12
|
+
decoder.call request
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'with Message Pack response' do
|
16
|
+
let(:headers) { { 'Content-Type' => 'application/x-msgpack' } }
|
17
|
+
let(:body) { MessagePack.dump data }
|
18
|
+
|
19
|
+
it 'should decode body data' do
|
20
|
+
request.complete! response
|
21
|
+
|
22
|
+
expect(response.data).to be == data.map(&:stringify_keys)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with invalid response' do
|
27
|
+
let(:headers) { { 'Content-Type' => 'application/x-msgpack' } }
|
28
|
+
let(:body) { MessagePack.dump(data)[4..-4] }
|
29
|
+
|
30
|
+
it 'should raise an error' do
|
31
|
+
expect { request.complete! response }.to raise_error(MessagePack::MalformedFormatError)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'without Message Pack response' do
|
36
|
+
let(:headers) { { 'Content-Type' => 'application/text' } }
|
37
|
+
let(:body) { data.to_json }
|
38
|
+
|
39
|
+
it 'should not decode non-MessagePack encoded responses' do
|
40
|
+
request.complete! response
|
41
|
+
|
42
|
+
expect(response.data).to be_nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -17,7 +17,7 @@ describe Acfs::Request::Callbacks do
|
|
17
17
|
request.on_complete &callback
|
18
18
|
|
19
19
|
expect(request.callbacks).to have(2).item
|
20
|
-
expect(request.callbacks[
|
20
|
+
expect(request.callbacks[0]).to be == callback
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -25,10 +25,22 @@ describe Acfs::Request::Callbacks do
|
|
25
25
|
let(:response) { Acfs::Response.new(request) }
|
26
26
|
|
27
27
|
it 'should trigger registered callbacks with given response' do
|
28
|
-
callback.should_receive(:call).with(response)
|
28
|
+
callback.should_receive(:call).with(response, kind_of(Proc))
|
29
29
|
|
30
30
|
request.on_complete &callback
|
31
31
|
request.complete! response
|
32
32
|
end
|
33
|
+
|
34
|
+
it 'should trigger multiple callback in reverted insertion order' do
|
35
|
+
check = []
|
36
|
+
|
37
|
+
request.on_complete { |res, nxt| check << 1; nxt.call res }
|
38
|
+
request.on_complete { |res, nxt| check << 2; nxt.call res }
|
39
|
+
request.on_complete { |res, nxt| check << 3; nxt.call res }
|
40
|
+
|
41
|
+
request.complete! response
|
42
|
+
|
43
|
+
expect(check).to be == [3, 2, 1]
|
44
|
+
end
|
33
45
|
end
|
34
46
|
end
|
@@ -11,9 +11,9 @@ describe Acfs::Response::Formats do
|
|
11
11
|
context 'with JSON mimetype' do
|
12
12
|
let(:mime_type) { 'application/json' }
|
13
13
|
|
14
|
-
describe '#
|
14
|
+
describe '#content_type' do
|
15
15
|
it 'should return Mime::JSON' do
|
16
|
-
expect(response.
|
16
|
+
expect(response.content_type).to be == Mime::JSON
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -26,9 +26,9 @@ describe Acfs::Response::Formats do
|
|
26
26
|
context 'with charset option' do
|
27
27
|
let(:mime_type) { 'application/json; charset=utf8' }
|
28
28
|
|
29
|
-
describe '#
|
29
|
+
describe '#content_type' do
|
30
30
|
it 'should return Mime::JSON' do
|
31
|
-
expect(response.
|
31
|
+
expect(response.content_type).to be == Mime::JSON
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
data/spec/acfs_spec.rb
CHANGED
@@ -3,11 +3,15 @@ require 'spec_helper'
|
|
3
3
|
describe "Acfs" do
|
4
4
|
|
5
5
|
before do
|
6
|
+
Acfs.clear
|
6
7
|
Acfs.use Acfs::Middleware::JsonDecoder
|
8
|
+
Acfs.use Acfs::Middleware::MessagePackDecoder
|
7
9
|
|
8
10
|
headers = { 'Content-Type' => 'application/json' }
|
9
11
|
stub_request(:get, "http://users.example.org/users").to_return(:body => '[{"id":1,"name":"Anon","age":12},{"id":2,"name":"John","age":26}]', headers: headers)
|
10
12
|
stub_request(:get, "http://users.example.org/users/2").to_return(:body => '{"id":2,"name":"John","age":26}', headers: headers)
|
13
|
+
stub_request(:get, "http://users.example.org/users/3").to_return(:body => '{"id":2,"name":"Miraculix","age":122}', headers: headers)
|
14
|
+
stub_request(:get, "http://users.example.org/users/100").to_return(:body => '{"id":2,"name":"Jimmy","age":45}', headers: headers)
|
11
15
|
stub_request(:get, "http://users.example.org/users/2/friends").to_return(:body => '[{"id":1,"name":"Anon","age":12}]', headers: headers)
|
12
16
|
stub_request(:get, "http://comments.example.org/comments?user=2").to_return(:body => '[{"id":1,"text":"Comment #1"},{"id":2,"text":"Comment #2"}]', headers: headers)
|
13
17
|
end
|
@@ -24,6 +28,34 @@ describe "Acfs" do
|
|
24
28
|
expect(@user.age).to be == 26
|
25
29
|
end
|
26
30
|
|
31
|
+
it 'should load multiple single resources' do
|
32
|
+
@users = MyUser.find(2, 3, 100) do |users|
|
33
|
+
# This block should be called only after *all* resources are loaded.
|
34
|
+
@john = users[0]
|
35
|
+
@mirx = users[1]
|
36
|
+
@jimy = users[2]
|
37
|
+
end
|
38
|
+
|
39
|
+
expect(@users).to_not be_loaded
|
40
|
+
|
41
|
+
Acfs.run
|
42
|
+
|
43
|
+
expect(@users).to be_loaded
|
44
|
+
expect(@users).to have(3).items
|
45
|
+
|
46
|
+
expect(@users[0].name).to be == 'John'
|
47
|
+
expect(@users[0].age).to be == 26
|
48
|
+
expect(@users[0]).to be == @john
|
49
|
+
|
50
|
+
expect(@users[1].name).to be == 'Miraculix'
|
51
|
+
expect(@users[1].age).to be == 122
|
52
|
+
expect(@users[1]).to be == @mirx
|
53
|
+
|
54
|
+
expect(@users[2].name).to be == 'Jimmy'
|
55
|
+
expect(@users[2].age).to be == 45
|
56
|
+
expect(@users[2]).to be == @jimy
|
57
|
+
end
|
58
|
+
|
27
59
|
it 'should load multiple resources' do
|
28
60
|
@users = MyUser.all
|
29
61
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acfs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Graichen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-04-
|
11
|
+
date: 2013-04-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -164,6 +164,20 @@ dependencies:
|
|
164
164
|
- - '>='
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: msgpack
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - '>='
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
167
181
|
description: API Client For Services
|
168
182
|
email:
|
169
183
|
- jg@altimos.de
|
@@ -188,6 +202,7 @@ files:
|
|
188
202
|
- lib/acfs/collection.rb
|
189
203
|
- lib/acfs/middleware/base.rb
|
190
204
|
- lib/acfs/middleware/json_decoder.rb
|
205
|
+
- lib/acfs/middleware/msgpack_decoder.rb
|
191
206
|
- lib/acfs/middleware/print.rb
|
192
207
|
- lib/acfs/model.rb
|
193
208
|
- lib/acfs/model/attributes.rb
|
@@ -207,6 +222,7 @@ files:
|
|
207
222
|
- lib/acfs/service.rb
|
208
223
|
- lib/acfs/version.rb
|
209
224
|
- spec/acfs/middleware/json_decoder_spec.rb
|
225
|
+
- spec/acfs/middleware/msgpack_decoder_spec.rb
|
210
226
|
- spec/acfs/request/callbacks_spec.rb
|
211
227
|
- spec/acfs/request_spec.rb
|
212
228
|
- spec/acfs/response/formats_spec.rb
|
@@ -243,6 +259,7 @@ specification_version: 4
|
|
243
259
|
summary: An abstract API base client for service oriented application.
|
244
260
|
test_files:
|
245
261
|
- spec/acfs/middleware/json_decoder_spec.rb
|
262
|
+
- spec/acfs/middleware/msgpack_decoder_spec.rb
|
246
263
|
- spec/acfs/request/callbacks_spec.rb
|
247
264
|
- spec/acfs/request_spec.rb
|
248
265
|
- spec/acfs/response/formats_spec.rb
|