served 0.1.10 → 0.1.12

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 441c7ca5f9f68f1df1cae462d85d60a50b50cdc8
4
- data.tar.gz: 74b53138ad506df5fb5ad69f95f8218d7aeb1202
3
+ metadata.gz: 6caeaa76f12084ca80555e8bf472e9f85ebcae70
4
+ data.tar.gz: 006b93ac7370979237e29fffe4b49a70938684fe
5
5
  SHA512:
6
- metadata.gz: 666239cf535c226548af6e029f5c2883da475c4131291167b7ee9482953ef197362fe36489a9f62dd34b17918b42a0f91a1c6bf08434687f845a4e3746d3ce7a
7
- data.tar.gz: 472b45163683b788ddd9b023a18cd04daf8fe9897d2d31e41c972000d2fd3b1e1e955bd6ed2914f22d8208a0cfc68db309724e2f7178f59da05e7c6af19d5eb4
6
+ metadata.gz: 9bc45c23b36761e2c2a24bb7fc295f75a807969455c02347acb74d3664de0eb865716b16da51e401bbe73a50fc1ab60fa6c898ec5e816c800d02092425770697
7
+ data.tar.gz: 51e0f9ceda390a79ee3da2b1fe071ca376bf3538506d7ce6092e327e51b313200a354521b697c7b8034554c5de04db5a7b01aa33f430006a7e16dccdf52a4abc
data/.travis.yml CHANGED
@@ -1,4 +1,16 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.2
3
+ - 2.1
4
+ - 2.2.2
5
+ - 2.3.1
4
6
  before_install: gem install bundler -v 1.10.5
7
+
8
+ gemfile:
9
+ - gemfiles/3.2.gemfile
10
+ - gemfiles/4.2.gemfile
11
+ - gemfiles/5.0.gemfile
12
+
13
+ matrix:
14
+ exclude:
15
+ - gemfile: gemfiles/5.0.gemfile
16
+ rvm: 2.1
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.12
4
+ * add validation support
5
+ * add serialization support
6
+ * allow definition of individual attributes
7
+ * add resource level `headers` option
8
+ * `host_config` will be deprecated in 0.2.0
9
+ * add `Served::Attribute::Base` class
10
+
11
+ ## 0.1.11
12
+ * add resource level `reasource_name` option
13
+ * add resource level `host` option
14
+
15
+ ## 0.1.10
16
+ * make `timeout` configurable per resource
17
+
3
18
  ## 0.1.8
4
19
 
5
20
  * fix buggy GET request template expansion defaults
data/README.md CHANGED
@@ -25,12 +25,12 @@ end
25
25
  ```
26
26
 
27
27
  ## Hosts
28
- Served models derive their hostname by mapping their parent module to the ```Served::hosts``` configuration hash. For
29
- example, ```SomeService::SomeResource``` would look up its host configuration at
30
- ```Served.config.hosts['some_service']```.
28
+ Served models derive their hostname by mapping their parent module to the `Served::hosts` configuration hash. For
29
+ example, `SomeService::SomeResource` would look up its host configuration at
30
+ `Served.config.hosts['some_service']`.
31
31
 
32
32
  The host configuration accepts an (Addressable)[https://github.com/sporkmonger/addressable] template mapping
33
- ```resource``` as the resource name (derived from the model name) and ```query``` as the params. For example:
33
+ `resource` as the resource name (derived from the model name) and `query` as the params. For example:
34
34
 
35
35
  ```
36
36
  http://localhost:3000/{resource}{?query*}
@@ -44,22 +44,90 @@ maintained for backwards compatibility, however the extension will likely be rem
44
44
  Sets the request timeout in milliseconds.
45
45
 
46
46
 
47
- # Usage
47
+ # Defining a Resource
48
48
  A service model can be created by declaring a class inheriting from ```Service::Resource::Base```.
49
49
 
50
50
  ```ruby
51
51
  class SomeService::SomeResource < Served::Resource::Base
52
-
53
52
  attribute :name
54
53
  attribute :date
55
- attribute :phone_number, default: '555-555-5555'
54
+ attribute :phone_number
55
+
56
+ end
57
+ ```
58
+
59
+ ## Resource Configuration
60
+ The default configuration can be changed for individual resources. The currently available resource configuration
61
+ options are:
62
+
63
+ * **host** - the service host the request is sent to
64
+ * **headers** - the headers that are sent with the request
65
+ * **timeout** - the timeout for the individual resource
66
+ * **resource_name** - the resource_name of the resource, as applicable to the Addressable template
67
+
68
+ ## Serialization
69
+
70
+ Attributes can be serialized as Ruby objects when the `serialize:` option is passed to `#attribute`. This can be any
71
+ primitive object (`Fixnum`, `String`, `Symbol`, etc.) or any object whose initializer accepts a single `Hash` or `Array`
72
+ as an argument and responds to `to_json`. This also means that Served resources can be used as nested objects as well,
73
+ which can allow for strict request validation (as explained in the next section).
74
+
75
+ When `#save` is called on a resource, non primitive objects will be serialized for transport using their `to_json`
76
+ method, this also means that attributes can be valid `ActiveRecord` objects. Served provides a generic validatable
77
+ non-resource class called `Served::Attribute::Base` that can be used to define deep nested object mapping for
78
+ complex json data strucutres.
79
+
80
+ Example:
81
+
82
+ ```ruby
83
+ class SomeService::SomeThing < Served::Attribute::Base
84
+ attribute :id
85
+ end
86
+
87
+ class SomeService::SomeResource < Served::Resource::Base
88
+ attribute :thing, serialize: SomeService::SometThing
89
+ end
90
+ ```
56
91
 
92
+ ## Validations
93
+ `Served::Resource::Base` includes `AciveModel::Validations` and supports all validation methods with the exception of
94
+ `Uniquness`. As a shotcut validations can be passed to the `#attribute` method much in the same way as it can be passed
95
+ to the `#validate` method.
96
+
97
+ Example:
98
+
99
+ ```ruby
100
+ class SomeService::SomeResource < Served::Resource::Base
101
+ attribute :name, presence: true, format: {with: /[a-z]+/}, length: { within: (3..10) }
102
+ attribute :date
103
+
104
+ validates_each :date do |record, attr, value|
105
+ # ...
106
+ end
57
107
  end
108
+
58
109
  ```
59
110
 
111
+ When a serializer is added to an attribute if that serializer responds to `#valid?` it will be validated along with the
112
+ rest of the request. These nested validations will bubble up to errors added to the top level attribute.
113
+
114
+
115
+ ```ruby
116
+ class SomeService::SomeThing < Served::Attribute::Base
117
+ attribute :id, presence: true
118
+ end
119
+
120
+ class SomeService::SomeResource < Served::Resource::Base
121
+ attribute :thing, presence: true, serialize: SomeService::SometThing
122
+ end
123
+ ```
124
+
125
+ This allows scenarios where a data structure needs to be enforced and to f fail fast when the structure is invalid.
126
+ is particularly useful when developing internal API libraries that communicate between internal services using a uniform data model.
127
+
60
128
  ## Saving a resource
129
+
61
130
  Served follows resourceful standards. When a resource is initially saved a **POST** request will be sent
62
131
  to the service. When the resource already exists, a **PUT** request will be sent. Served determines if
63
132
  a resource is new or not based on the presence of an id.
64
133
 
65
-
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activesupport', '~> 3.2'
4
+
5
+ gemspec :path => "../"
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activesupport', '~> 4.2'
4
+
5
+ gemspec :path => "../"
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activesupport', '~> 5.0'
4
+
5
+ gemspec :path => "../"
@@ -0,0 +1,9 @@
1
+ module Served
2
+ module Attribute
3
+ class Base
4
+ include Support::Attributable
5
+ include Support::Serializable
6
+ include Support::Validatable
7
+ end
8
+ end
9
+ end
@@ -0,0 +1 @@
1
+ require_relative 'attribute/base'
@@ -5,15 +5,16 @@ module Served
5
5
  HEADERS = { 'Content-type' => 'application/json', 'Accept' => 'application/json' }
6
6
  DEFAULT_TEMPLATE = '{/resource*}{/id}.json{?query*}'
7
7
 
8
- def initialize(host, timeout)
8
+ def initialize(host, timeout, headers={})
9
9
  host += DEFAULT_TEMPLATE unless host =~ /{.+}/
10
10
  @template = Addressable::Template.new(host)
11
11
  @timeout = timeout
12
+ @headers = HEADERS.merge(headers || {})
12
13
  end
13
14
 
14
15
  def get(endpoint, id, params={})
15
16
  HTTParty.get(@template.expand(id: id, query: params, resource: endpoint).to_s,
16
- headers: HEADERS,
17
+ headers: @headers,
17
18
  timeout: @timeout
18
19
  )
19
20
  end
@@ -21,7 +22,7 @@ module Served
21
22
  def put(endpoint, id, body, params={})
22
23
  HTTParty.put(@template.expand(id: id, query: params, resource: endpoint).to_s,
23
24
  body: body,
24
- headers: HEADERS,
25
+ headers: @headers,
25
26
  timeout: @timeout
26
27
  )
27
28
  end
@@ -29,7 +30,7 @@ module Served
29
30
  def post(endpoint, body, params={})
30
31
  HTTParty.post(@template.expand(query: params, resource: endpoint).to_s,
31
32
  body: body,
32
- headers: HEADERS,
33
+ headers: @headers,
33
34
  timeout: @timeout
34
35
  )
35
36
  end
@@ -4,9 +4,21 @@ module Served
4
4
  # services based on the namespace. Classes should be namespaced under Services::ServiceName where ServiceName is the
5
5
  # name of the service the resource lives on. The resource determines the host of the service based on this
6
6
  # this namespace and what is in the configuration.
7
+ #
8
+ # Service Resources supports some ActiveModel validations so that a developer can include client side validations
9
+ # if desired. Validation options can be passed to the #attribute class method using the same options as
10
+ # ActiveModel#validate
11
+ #
12
+ # A resource may also serialize values as specific classes, including nested resources. If serialize is set to a
13
+ # Served Resource, it will validate the nested resource as well as the top level.
7
14
  class Base
15
+ include Support::Attributable
16
+ include Support::Validatable
17
+ include Support::Serializable
18
+
8
19
  # raised when an attribute is passed to a resource that is not declared
9
- class InvalidAttributeError < StandardError; end
20
+ class InvalidAttributeError < StandardError;
21
+ end
10
22
 
11
23
  # raised when the connection receives a response from a service that does not constitute a 200
12
24
  class ServiceError < StandardError
@@ -19,49 +31,60 @@ module Served
19
31
  end
20
32
 
21
33
  class << self
22
- # declare an attribute for the resource
23
- #
24
- # @example
25
- # class SomeResource
26
- # attribute :attr1
27
- # end
28
- def attribute(name, options={})
29
- return if attributes.include?(name)
30
- attributes[name] = options
31
- attr_accessor name
32
- end
33
34
 
34
- # @return [Hash] declared attributes for the resources
35
- def attributes
36
- @attributes ||= {}
35
+
36
+ # Defines the default headers that should be used for the request.
37
+ #
38
+ # @param headers [Hash] the headers to send with each requesat
39
+ # @return headers [Hash] the default headers for the class
40
+ def headers(h={})
41
+ @headers = h unless h.empty?
42
+ @headers
37
43
  end
38
44
 
39
45
  # Looks up a resource on the service by id. For example `SomeResource.find(5)` would call `/some_resources/5`
46
+ #
47
+ # @param id [Integer] the id of the resource
48
+ # @return [Resource::Base] the resource object.
40
49
  def find(id)
41
50
  instance = new(id: id)
42
51
  instance.reload
43
52
  end
44
53
 
54
+ # Get or set the resource name for the given resource used for endpoint generation
55
+ #
56
+ # @param resource [String] the name of the resource
45
57
  # @return [String] the name of the resource. `SomeResource.resource_name` will return `some_resources`
46
- def resource_name
47
- name.split('::').last.tableize
58
+ def resource_name(resource=nil)
59
+ @resource_name = resource if resource
60
+ @resource_name ||name.split('::').last.tableize
48
61
  end
49
62
 
63
+ # @deprecated returns host information
64
+ def host_config
65
+ host
66
+ end
67
+
68
+ # Get or set the host for the resource
69
+ #
70
+ # @param host [String] the resource host
50
71
  # @return [String] or [Hash] the configured host.
51
72
  # @see Services::Configuration
52
- def host_config
53
- Served.config[:hosts][parent.name.underscore.split('/')[-1]]
73
+ def host(h=nil)
74
+ @host = h if h
75
+ @host ||= Served.config[:hosts][parent.name.underscore.split('/')[-1]]
54
76
  end
55
77
 
78
+ # Get or set the timeout for the current resource
79
+ #
56
80
  # @return [Integer] allowed timeout in seconds
57
- def timeout
58
- Served.config.timeout
81
+ def timeout(sec=nil)
82
+ @timeout = sec if sec
83
+ @timeout || Served.config.timeout
59
84
  end
60
85
 
61
- # @return [Served::HTTPClient] The connection instance to the service host. Note this is not an active
62
- # connection but a passive one.
63
86
  def client
64
- @connection ||= Served::HTTPClient.new(host_config, timeout)
87
+ @connection ||= Served::HTTPClient.new(host_config, timeout, headers)
65
88
  end
66
89
 
67
90
  private
@@ -74,13 +97,7 @@ module Served
74
97
  attribute :id
75
98
  end
76
99
  end
77
- end
78
100
 
79
- # Instantiates a resource with the given attributes.
80
- #
81
- # @raise [InvalidAttributeError] in the case that an attribute is passed that is not declared
82
- def initialize(attributes={})
83
- reload_with_attributes(attributes)
84
101
  end
85
102
 
86
103
  # @see Services::Resource::Base::resource_name
@@ -111,18 +128,6 @@ module Served
111
128
  self
112
129
  end
113
130
 
114
- # renders the model as json
115
- def to_json
116
- raise InvalidPresenter, 'Presenter must respond to #to_json' unless presenter.respond_to? :to_json
117
- presenter.to_json
118
- end
119
-
120
- # override this to return a presenter to be used for serialization, otherwise all attributes will be
121
- # serialized
122
- def presenter
123
- { resource_name.singularize => attributes }
124
- end
125
-
126
131
  private
127
132
 
128
133
  def get(params={})
@@ -144,29 +149,10 @@ module Served
144
149
  JSON.parse(response.body)
145
150
  end
146
151
 
147
-
148
- def reload_with_attributes(attributes)
149
- attributes.each do |name, value|
150
- set_attribute(name.to_sym, value)
151
- end
152
- set_attribute_defaults
153
- end
154
-
155
- def set_attribute_defaults
156
- self.class.attributes.each do |attr, options|
157
- next if options[:default].nil? || send(attr)
158
- set_attribute(attr, options[:default])
159
- end
160
- end
161
-
162
- def set_attribute(name, value)
163
- raise InvalidAttributeError, "`#{name}' is not a valid attribute" unless self.class.attributes.include?(name)
164
- instance_variable_set("@#{name}", value)
165
- end
166
-
167
152
  def client
168
153
  self.class.client
169
154
  end
155
+
170
156
  end
171
157
  end
172
158
  end
@@ -0,0 +1,67 @@
1
+ module Served
2
+ module Support
3
+ module Attributable
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+
8
+ # declare an attribute for the resource
9
+ #
10
+ # @example
11
+ # class SomeResource
12
+ # attribute :attr1
13
+ # end
14
+ #
15
+ # @param name [Symbol] the name of the attribute
16
+ def attribute(name, options={})
17
+ return if attributes.include?(name)
18
+ attributes[name] = options
19
+ attr_accessor name
20
+ end
21
+
22
+ # declare a set of attributes by name
23
+ #
24
+ # @example
25
+ # class SomeResource
26
+ # attributes :attr1, :attr2
27
+ # end
28
+ #
29
+ # @param *attributes [Array] a list of attributes for the resource
30
+ # @return [Hash] declared attributes for the resources
31
+ def attributes(*args)
32
+ args.each { |a| attribute a } unless args.empty?
33
+ @attributes ||= {}
34
+ end
35
+
36
+ end
37
+
38
+ def initialize(options={})
39
+ reload_with_attributes(options)
40
+ end
41
+
42
+ private
43
+
44
+ def reload_with_attributes(attributes)
45
+ attributes.each do |name, value|
46
+ set_attribute(name.to_sym, value)
47
+ end
48
+ set_attribute_defaults
49
+ end
50
+
51
+ def set_attribute_defaults
52
+ self.class.attributes.each do |attr, options|
53
+ next if options[:default].nil? || send(attr)
54
+ set_attribute(attr, options[:default])
55
+ end
56
+ end
57
+
58
+ def set_attribute(name, value)
59
+ raise InvalidAttributeError, "`#{name}' is not a valid attribute" unless self.class.attributes.include?(name)
60
+ instance_variable_set("@#{name}", value)
61
+ end
62
+
63
+ end
64
+
65
+
66
+ end
67
+ end
@@ -0,0 +1,66 @@
1
+ module Served
2
+ module Support
3
+ module Serializable
4
+ extend ActiveSupport::Concern
5
+
6
+ # Specialized class serializers
7
+ SERIALIZERS = {
8
+ Fixnum => {call: :to_i},
9
+ String => {call: :to_s},
10
+ Symbol => {call: :to_sym},
11
+ Float => {call: :to_f}
12
+ }
13
+
14
+ included do
15
+ include Attributable
16
+ prepend Prepend
17
+ end
18
+
19
+ class InvalidPresenter < StandardError
20
+ end
21
+
22
+ module Prepend
23
+
24
+ def set_attribute(name, value)
25
+ return unless self.class.attributes[name]
26
+ if serializer = self.class.attributes[name][:serialize]
27
+ if serializer.is_a? Proc
28
+ value = serializer.call(value)
29
+ elsif s = SERIALIZERS[serializer]
30
+ value = value.send(s[:call]) if s[:call] && value.respond_to?(s[:call])
31
+ value = s[:converter].call(value) if s[:converter]
32
+ else
33
+ value = serializer.new(value)
34
+ end
35
+ end
36
+ super
37
+ end
38
+
39
+
40
+ end
41
+
42
+ module ClassMethods
43
+
44
+ private
45
+
46
+ def serializer_for_attribute(attr, serializer)
47
+ attributes[attr][:serializer] = serializer
48
+ end
49
+
50
+ end
51
+
52
+ # renders the model as json
53
+ def to_json
54
+ raise InvalidPresenter, 'Presenter must respond to #to_json' unless presenter.respond_to? :to_json
55
+ presenter.to_json
56
+ end
57
+
58
+ # override this to return a presenter to be used for serialization, otherwise all attributes will be
59
+ # serialized
60
+ def presenter
61
+ {resource_name.singularize => attributes}
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,66 @@
1
+ module Served
2
+ module Support
3
+ # Resource validation functionality
4
+ module Validatable
5
+ extend ActiveSupport::Concern
6
+
7
+ # Supported Validation Types
8
+ SUPPORTED_VALIDATIONS = [
9
+ :presence,
10
+ :numericality,
11
+ :format,
12
+ :inclusion,
13
+ :confirmation
14
+ ]
15
+
16
+ included do
17
+ include ActiveModel::Validations
18
+ singleton_class.prepend ClassMethods::Prepend
19
+ prepend Prepend
20
+ end
21
+
22
+ module Prepend
23
+
24
+ def save
25
+ return false unless valid?
26
+ super
27
+ end
28
+
29
+
30
+ protected
31
+
32
+ def run_validations!
33
+ super
34
+ self.class.attributes.each_key do |attribute|
35
+ attr = send(attribute)
36
+ errors.add(attribute, :invalid) if attr.respond_to?(:valid?) && !attr.valid?
37
+ end
38
+ errors.empty?
39
+ end
40
+
41
+ end
42
+
43
+ module ClassMethods
44
+ module Prepend
45
+
46
+ def attribute(name, options={})
47
+ super
48
+ set_validations_for_attribute(name, options)
49
+ end
50
+
51
+ end
52
+
53
+ private
54
+
55
+ # Sets up any validations for the attribute
56
+ def set_validations_for_attribute(name, options)
57
+ SUPPORTED_VALIDATIONS.each do |validation|
58
+ validates name, validation => options[validation] if options[validation]
59
+ end
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,3 @@
1
+ require_relative 'support/attributable'
2
+ require_relative 'support/serializable'
3
+ require_relative 'support/validatable'
@@ -1,3 +1,3 @@
1
1
  module Served
2
- VERSION = '0.1.10'
2
+ VERSION = '0.1.12'
3
3
  end
data/lib/served.rb CHANGED
@@ -2,11 +2,14 @@ require 'httparty'
2
2
  require 'active_support/configurable'
3
3
  require 'active_support/core_ext/string'
4
4
  require 'active_support/core_ext/module'
5
+ require 'active_model'
5
6
 
6
7
  require 'served/engine'
7
8
  require 'served/version'
8
9
  require 'served/http_client'
10
+ require 'served/support'
9
11
  require 'served/resource'
12
+ require 'served/attribute'
10
13
 
11
14
  module Served
12
15
  include ActiveSupport::Configurable
data/served.gemspec CHANGED
@@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.add_dependency 'httparty'
23
23
  spec.add_dependency 'activesupport', '>= 3.2'
24
24
  spec.add_dependency 'addressable', '>= 2.4.0'
25
+ spec.add_dependency 'activemodel', '>= 3.2'
25
26
 
26
27
  spec.add_development_dependency 'bundler', '~> 1.10'
27
28
  spec.add_development_dependency 'rake', '~> 10.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: served
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jarod Reid
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-04-18 00:00:00.000000000 Z
11
+ date: 2017-02-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 2.4.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: activemodel
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '3.2'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '3.2'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: bundler
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -113,11 +127,20 @@ files:
113
127
  - Rakefile
114
128
  - bin/console
115
129
  - bin/setup
130
+ - gemfiles/3.2.gemfile
131
+ - gemfiles/4.2.gemfile
132
+ - gemfiles/5.0.gemfile
116
133
  - lib/served.rb
134
+ - lib/served/attribute.rb
135
+ - lib/served/attribute/base.rb
117
136
  - lib/served/engine.rb
118
137
  - lib/served/http_client.rb
119
138
  - lib/served/resource.rb
120
139
  - lib/served/resource/base.rb
140
+ - lib/served/support.rb
141
+ - lib/served/support/attributable.rb
142
+ - lib/served/support/serializable.rb
143
+ - lib/served/support/validatable.rb
121
144
  - lib/served/version.rb
122
145
  - served.gemspec
123
146
  homepage: http://github.com/fugufish/served
@@ -140,10 +163,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
140
163
  version: '0'
141
164
  requirements: []
142
165
  rubyforge_project:
143
- rubygems_version: 2.4.8
166
+ rubygems_version: 2.6.10
144
167
  signing_key:
145
168
  specification_version: 4
146
169
  summary: Served provides an easy to use model layer for communicating with disributed
147
170
  Rails based Services.
148
171
  test_files: []
149
- has_rdoc: