giraph 0.1.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 +7 -0
- data/.gitignore +5 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +50 -0
- data/Rakefile +6 -0
- data/bin/console +11 -0
- data/bin/setup +8 -0
- data/giraph.gemspec +32 -0
- data/lib/giraph/extensions/field.rb +33 -0
- data/lib/giraph/remote/connector.rb +53 -0
- data/lib/giraph/remote/mutation.rb +20 -0
- data/lib/giraph/remote/query.rb +61 -0
- data/lib/giraph/remote/response.rb +14 -0
- data/lib/giraph/resolver.rb +31 -0
- data/lib/giraph/schema.rb +48 -0
- data/lib/giraph/subquery.rb +72 -0
- data/lib/giraph/version.rb +3 -0
- data/lib/giraph.rb +13 -0
- metadata +150 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 200536c7e29c300962bf1e9306f3656852b19a88
|
4
|
+
data.tar.gz: b6c30010a1e6406d47ca41d96ca66dd09dc3a00e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 922c37a7505fac9f68bf53611b4a1a0d139a5fa88a9f40e59a7b2886513d6a29d259b4c3e32f2654063c5f1c3d4ba014c56d80cd5a8ece5a310ee39f233c8e18
|
7
|
+
data.tar.gz: eb2a773e12531711f3abd82e72b2fc80c7cda9ce954f472eb86261c64fe947e21348ba6a4476e9ca87f4b6f0e48a0ac0c3ad2eb0fa09e7928e36b870b4f0ce85
|
data/.gitignore
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.3.1
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Upserve
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# Giraph
|
2
|
+
|
3
|
+
_(Pronounced with a G as in GIF)_
|
4
|
+
|
5
|
+
Ever wanted to have multiple GraphQL endpoints presented under one?
|
6
|
+
|
7
|
+
Ever felt like interactions between micro-services are not DRY enough?
|
8
|
+
|
9
|
+
If so, you'll feel right at home with Giraph.
|
10
|
+
|
11
|
+
Giraph allows you to plug-in a remote GraphQL endpoint under another one as a regular field.
|
12
|
+
You can now plug a remote GraphQL endpoint in as a field anywhere within your type hierarchy,
|
13
|
+
allow clients to send a single unified query, have the remote servers resolve their respective
|
14
|
+
sub-queries and return a valid response that all seamlessly comes together.
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
Add this line to your application's Gemfile:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
gem 'giraph'
|
22
|
+
```
|
23
|
+
|
24
|
+
And then execute:
|
25
|
+
|
26
|
+
$ bundle
|
27
|
+
|
28
|
+
Or install it yourself as:
|
29
|
+
|
30
|
+
$ gem install giraph
|
31
|
+
|
32
|
+
## Usage
|
33
|
+
|
34
|
+
TODO: Write usage instructions here
|
35
|
+
|
36
|
+
## Development
|
37
|
+
|
38
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
39
|
+
|
40
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
41
|
+
|
42
|
+
## Contributing
|
43
|
+
|
44
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/upserve/giraph.
|
45
|
+
|
46
|
+
|
47
|
+
## License
|
48
|
+
|
49
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
50
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "giraph"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
require "pry"
|
11
|
+
Pry.start
|
data/bin/setup
ADDED
data/giraph.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'giraph/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'giraph'
|
8
|
+
spec.version = Giraph::VERSION
|
9
|
+
spec.authors = ['Erman Celen']
|
10
|
+
spec.email = ['erman@upserve.com']
|
11
|
+
|
12
|
+
spec.summary = 'Composable GraphQL for micro-services'
|
13
|
+
spec.description = 'Expose a remote GraphQL endpoint within another as a regular field'
|
14
|
+
spec.homepage = 'https://github.com/upserve/giraph'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = 'bin'
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
|
+
spec.require_paths = ['lib']
|
22
|
+
|
23
|
+
spec.required_ruby_version = '~> 2.1'
|
24
|
+
|
25
|
+
spec.add_runtime_dependency 'graphql', '0.15.3'
|
26
|
+
|
27
|
+
spec.add_development_dependency 'bundler', '~> 1.11'
|
28
|
+
spec.add_development_dependency 'pry'
|
29
|
+
spec.add_development_dependency 'pry-byebug'
|
30
|
+
spec.add_development_dependency 'rake'
|
31
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
32
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Giraph
|
2
|
+
# Wrapped methods on GraphQL::Field class
|
3
|
+
module Extensions
|
4
|
+
module Field
|
5
|
+
# Wrap the 'resolve' method on Field so that we can
|
6
|
+
# intercept the registered resolution Proc and resolve
|
7
|
+
# on already-resolved values from the JSON returned
|
8
|
+
# to the sub-query through the remote endpoint
|
9
|
+
def resolve(object, arguments, context)
|
10
|
+
# Giraph always parses a remote response with a special Hash
|
11
|
+
# class called 'Giraph::Remote::Response', which is a no-op sub-class
|
12
|
+
# of Hash. This way we can easily recognize this special
|
13
|
+
# "resolve on already resolved response" case while still
|
14
|
+
# allowing regular Hash to be resolved normally.
|
15
|
+
if object.instance_of? Giraph::Remote::Response
|
16
|
+
# If the field was aliased, response will be keyed by the alias
|
17
|
+
field = context.ast_node.alias || context.ast_node.name
|
18
|
+
object[field.to_sym]
|
19
|
+
else
|
20
|
+
# Not Giraph, let it through...
|
21
|
+
super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Monkey-patch GraphQL Field class to wrap the default 'resolve'
|
29
|
+
module GraphQL
|
30
|
+
class Field
|
31
|
+
prepend Giraph::Extensions::Field
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Giraph
|
2
|
+
module Remote
|
3
|
+
class InvalidResponse < StandardError; end
|
4
|
+
|
5
|
+
# sends the reconstructed subquery request and parses the response.
|
6
|
+
class Connector
|
7
|
+
def initialize(endpoint)
|
8
|
+
@endpoint = endpoint
|
9
|
+
end
|
10
|
+
|
11
|
+
# The resolver method for the connection field.
|
12
|
+
def resolve(context, query_string, query_variables)
|
13
|
+
# Remote can return data, error or totally freak out,
|
14
|
+
# we handle all here, and note anything of relevance
|
15
|
+
result = run_query(query_string, query_variables)
|
16
|
+
return_data_or_raise(result) do |exception|
|
17
|
+
# Tack on details for host's version of the query
|
18
|
+
exception.ast_node = context.ast_node
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def run_query(query, variable)
|
25
|
+
Net::HTTP.post_form(URI(@endpoint), query: query, variables: variable)
|
26
|
+
end
|
27
|
+
|
28
|
+
def return_data_or_raise(response, &block)
|
29
|
+
result = Remote::Response.from_json(response.body)
|
30
|
+
|
31
|
+
# Remote returned a valid result set, pass it through
|
32
|
+
return result[:data] if result[:data]
|
33
|
+
|
34
|
+
# Remote returned a GraphQL error, raise it as such
|
35
|
+
raise remote_execution_error(result[:errors], block)
|
36
|
+
rescue JSON::ParserError
|
37
|
+
# Remote server returned an invalid result (non-JSON response)
|
38
|
+
# meaning something went wrong. Raise an error that reflects this.
|
39
|
+
raise(
|
40
|
+
InvalidResponse,
|
41
|
+
"Remote endpoint returned: '#{response.code} #{response.msg}'"
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
def remote_execution_error(errors, block)
|
46
|
+
GraphQL::ExecutionError.new(errors).tap do |ex|
|
47
|
+
# Allow exception to be modified if needed
|
48
|
+
block.call(ex) if block
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Giraph
|
2
|
+
module Remote
|
3
|
+
# Field resolver to plug a remote GraphQL mutation root into a local type
|
4
|
+
class Mutation < Query
|
5
|
+
def self.bind(endpoint, &block)
|
6
|
+
new(
|
7
|
+
endpoint,
|
8
|
+
Remote::Connector.new(endpoint, mutation: true),
|
9
|
+
&block
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def query_type
|
16
|
+
'mutation'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Giraph
|
2
|
+
module Remote
|
3
|
+
# Field resolver to plug a remote GraphQL query root into a local type
|
4
|
+
class Query
|
5
|
+
def self.bind(endpoint, &block)
|
6
|
+
new(
|
7
|
+
endpoint,
|
8
|
+
Remote::Connector.new(endpoint),
|
9
|
+
&block
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(endpoint, connector, &block)
|
14
|
+
@endpoint = endpoint
|
15
|
+
@evaluator = block || method(:default_evaluator)
|
16
|
+
@connector = connector
|
17
|
+
end
|
18
|
+
|
19
|
+
# Reconstructs a valid GraphQL root-query from the current
|
20
|
+
# field in question, including all variables and params,
|
21
|
+
# hands over to connector to execute remotely.
|
22
|
+
def call(obj, args, ctx)
|
23
|
+
# Given an evaluator block, continue if only it evaluates to non-nil!
|
24
|
+
return unless (remote_root = @evaluator.call(obj, args, ctx))
|
25
|
+
|
26
|
+
subquery = Subquery.new(ctx)
|
27
|
+
|
28
|
+
# Continue with remote query execution
|
29
|
+
connector.resolve(
|
30
|
+
ctx,
|
31
|
+
query_string(subquery),
|
32
|
+
query_variables(subquery, remote_root)
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def query_type
|
39
|
+
'query'
|
40
|
+
end
|
41
|
+
|
42
|
+
def query_string(subquery)
|
43
|
+
# Full GraphQL query for remote
|
44
|
+
"#{query_type} #{subquery.subquery_string}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def query_variables(subquery, remote_root)
|
48
|
+
# Variable hash to send along
|
49
|
+
subquery.variable_string do |dict|
|
50
|
+
dict.merge(__giraph_root__: remote_root)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def default_evaluator(*args)
|
55
|
+
{}
|
56
|
+
end
|
57
|
+
|
58
|
+
attr_reader :endpoint, :connector
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Giraph
|
2
|
+
module Remote
|
3
|
+
# Dummy Hash-wrapper to enable precise `instance_of?` checks
|
4
|
+
# Allows us to differentiate JSON responses that are
|
5
|
+
# coming from remote GraphQL interface vs regular Hash objects
|
6
|
+
# including all nested hashes within a response.
|
7
|
+
class Response < Hash
|
8
|
+
# Factory method to encapsulate special parsing logic
|
9
|
+
def self.from_json(raw_json)
|
10
|
+
JSON.parse(raw_json, symbolize_names: true, object_class: self)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Giraph
|
2
|
+
# Proc-like class to allow declerative links to external
|
3
|
+
# resolution handlers (so the "definition" gem can stay pure resolution-wise)
|
4
|
+
class Resolver
|
5
|
+
class UnknownOperation < StandardError; end
|
6
|
+
|
7
|
+
def self.for(method_name)
|
8
|
+
new(method_name)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(method_name)
|
12
|
+
@method_name = method_name
|
13
|
+
end
|
14
|
+
|
15
|
+
# Resolves the field by calling the previously given method
|
16
|
+
# on the registered Resolver object for the current operation
|
17
|
+
# type (currently query or mutation)
|
18
|
+
def call(obj, args, ctx)
|
19
|
+
# Find out operation type (query, mutation, etc.)
|
20
|
+
op_type = ctx.query.selected_operation.operation_type.to_sym
|
21
|
+
|
22
|
+
# Ensure there is a registered resolver for it
|
23
|
+
unless (resolver = ctx[:__giraph_resolver__][op_type])
|
24
|
+
raise UnknownOperation, "No resolver found for '#{op_type}' op type"
|
25
|
+
end
|
26
|
+
|
27
|
+
# Call the requested method on resolver
|
28
|
+
resolver.public_send(@method_name, obj, args, ctx)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Giraph
|
2
|
+
# GraphQL::Schema wrapper allowing decleration of
|
3
|
+
# resolver objects per op type (query or mutation)
|
4
|
+
class Schema < DelegateClass(GraphQL::Schema)
|
5
|
+
# Extract special arguments for resolver objects,
|
6
|
+
# let the rest pass-through
|
7
|
+
def initialize(**args)
|
8
|
+
@query_resolver = args.delete(:query_resolver)
|
9
|
+
@mutation_resolver = args.delete(:mutation_resolver)
|
10
|
+
super(GraphQL::Schema.new(**args))
|
11
|
+
end
|
12
|
+
|
13
|
+
# Defer the execution only after setting up
|
14
|
+
# context and root_value with resolvers and remote arguments
|
15
|
+
def execute(query, **args)
|
16
|
+
args = args
|
17
|
+
.merge(with_giraph_root(args))
|
18
|
+
.merge(with_giraph_resolvers(args))
|
19
|
+
|
20
|
+
super(query, **args)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def with_giraph_root(args)
|
26
|
+
# Extract & remove the special __giraph_root__ key
|
27
|
+
# from variables passed in, if any
|
28
|
+
vars = args[:variables] || {}
|
29
|
+
root = vars.delete('__giraph_root__') || {}
|
30
|
+
|
31
|
+
# Set given pseudo-root as root_value for the execution
|
32
|
+
{ root_value: root }
|
33
|
+
end
|
34
|
+
|
35
|
+
def with_giraph_resolvers(args)
|
36
|
+
# Pass on resolver objects in context
|
37
|
+
# which will then be used by Giraph resolvers
|
38
|
+
# to direct per-field resolution
|
39
|
+
context = args[:context] || {}
|
40
|
+
context[:__giraph_resolver__] = {
|
41
|
+
query: @query_resolver,
|
42
|
+
mutation: @mutation_resolver
|
43
|
+
}
|
44
|
+
|
45
|
+
{ context: context }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Giraph
|
2
|
+
# Defines a thin & sane API for the sub-query extraction
|
3
|
+
# from the context provided to resolvers via AST, graphql-ruby API
|
4
|
+
# and a touch of regex.
|
5
|
+
class Subquery
|
6
|
+
attr_reader :query, :query_string
|
7
|
+
|
8
|
+
def initialize(context)
|
9
|
+
@context = context
|
10
|
+
|
11
|
+
@query = context.query
|
12
|
+
@query_string = context.ast_node.to_query_string
|
13
|
+
end
|
14
|
+
|
15
|
+
def subquery_string
|
16
|
+
"GiraphQuery #{query_variables} #{query_selections}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def variable_string
|
20
|
+
dict = variable_assignments
|
21
|
+
dict = yield dict if block_given?
|
22
|
+
|
23
|
+
dict.to_json
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def variable_assignments
|
29
|
+
# This re-encodes and passes on all the variable values
|
30
|
+
# paseed to the original query endpoint
|
31
|
+
query.instance_variable_get('@provided_variables')
|
32
|
+
end
|
33
|
+
|
34
|
+
def query_selections
|
35
|
+
# We get the following from node's sub-query:
|
36
|
+
# nodeName { field1 { field12 } field2(a: $a) field3 }
|
37
|
+
# we want:
|
38
|
+
# { field1 { field12 } field2(a: $a) field3 }
|
39
|
+
# as the name of node is local information to parent host
|
40
|
+
# and is no use to the remote host.
|
41
|
+
query_string.sub(/^[^{]+/, '')
|
42
|
+
end
|
43
|
+
|
44
|
+
def query_variables
|
45
|
+
# Recreates the declared query parameters to be passed on
|
46
|
+
# to the remote host.
|
47
|
+
declarations = query
|
48
|
+
.selected_operation
|
49
|
+
.variables
|
50
|
+
.select(&method(:variable_used?))
|
51
|
+
.map(&method(:variable_decleration))
|
52
|
+
|
53
|
+
"(#{declarations.join(', ')})" unless declarations.empty?
|
54
|
+
end
|
55
|
+
|
56
|
+
def variable_used?(variable)
|
57
|
+
query_string[/\$#{Regexp.quote(variable.name)}\W/]
|
58
|
+
end
|
59
|
+
|
60
|
+
def variable_decleration(variable)
|
61
|
+
"$#{variable.name}: #{variable_type(variable)}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def variable_type(variable)
|
65
|
+
if variable.type.is_a?(GraphQL::Language::Nodes::NonNullType)
|
66
|
+
variable.type.of_type.name + '!'
|
67
|
+
else
|
68
|
+
variable.type.name
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/giraph.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'graphql'
|
3
|
+
|
4
|
+
require 'giraph/version'
|
5
|
+
|
6
|
+
require 'giraph/subquery'
|
7
|
+
require 'giraph/extensions/field'
|
8
|
+
require 'giraph/remote/response'
|
9
|
+
require 'giraph/remote/connector'
|
10
|
+
require 'giraph/remote/query'
|
11
|
+
require 'giraph/remote/mutation'
|
12
|
+
require 'giraph/resolver'
|
13
|
+
require 'giraph/schema'
|
metadata
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: giraph
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Erman Celen
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-08-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: graphql
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.15.3
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.15.3
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.11'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.11'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry-byebug
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.0'
|
97
|
+
description: Expose a remote GraphQL endpoint within another as a regular field
|
98
|
+
email:
|
99
|
+
- erman@upserve.com
|
100
|
+
executables:
|
101
|
+
- console
|
102
|
+
- setup
|
103
|
+
extensions: []
|
104
|
+
extra_rdoc_files: []
|
105
|
+
files:
|
106
|
+
- ".gitignore"
|
107
|
+
- ".ruby-version"
|
108
|
+
- ".travis.yml"
|
109
|
+
- Gemfile
|
110
|
+
- LICENSE.txt
|
111
|
+
- README.md
|
112
|
+
- Rakefile
|
113
|
+
- bin/console
|
114
|
+
- bin/setup
|
115
|
+
- giraph.gemspec
|
116
|
+
- lib/giraph.rb
|
117
|
+
- lib/giraph/extensions/field.rb
|
118
|
+
- lib/giraph/remote/connector.rb
|
119
|
+
- lib/giraph/remote/mutation.rb
|
120
|
+
- lib/giraph/remote/query.rb
|
121
|
+
- lib/giraph/remote/response.rb
|
122
|
+
- lib/giraph/resolver.rb
|
123
|
+
- lib/giraph/schema.rb
|
124
|
+
- lib/giraph/subquery.rb
|
125
|
+
- lib/giraph/version.rb
|
126
|
+
homepage: https://github.com/upserve/giraph
|
127
|
+
licenses:
|
128
|
+
- MIT
|
129
|
+
metadata: {}
|
130
|
+
post_install_message:
|
131
|
+
rdoc_options: []
|
132
|
+
require_paths:
|
133
|
+
- lib
|
134
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '2.1'
|
139
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - ">="
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: '0'
|
144
|
+
requirements: []
|
145
|
+
rubyforge_project:
|
146
|
+
rubygems_version: 2.5.1
|
147
|
+
signing_key:
|
148
|
+
specification_version: 4
|
149
|
+
summary: Composable GraphQL for micro-services
|
150
|
+
test_files: []
|