graphql_rails 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile.lock +2 -2
- data/README.md +76 -8
- data/graphql_rails.gemspec +1 -1
- data/lib/graphql_rails/attribute.rb +7 -42
- data/lib/graphql_rails/attribute/attribute_type_parser.rb +99 -0
- data/lib/graphql_rails/controller.rb +17 -5
- data/lib/graphql_rails/controller/action.rb +93 -0
- data/lib/graphql_rails/controller/action_configuration.rb +1 -2
- data/lib/graphql_rails/controller/controller_function.rb +7 -6
- data/lib/graphql_rails/controller/request.rb +3 -3
- data/lib/graphql_rails/model.rb +1 -1
- data/lib/graphql_rails/model/configuration.rb +14 -50
- data/lib/graphql_rails/model/graphql_type_builder.rb +37 -0
- data/lib/graphql_rails/router.rb +36 -19
- data/lib/graphql_rails/router/{mutation_action.rb → mutation_route.rb} +2 -2
- data/lib/graphql_rails/router/{query_action.rb → query_route.rb} +2 -2
- data/lib/graphql_rails/router/resource_routes_builder.rb +82 -0
- data/lib/graphql_rails/router/route.rb +40 -0
- data/lib/graphql_rails/router/schema_builder.rb +9 -5
- data/lib/graphql_rails/rspec_controller_helpers.rb +94 -0
- data/lib/graphql_rails/version.rb +1 -1
- metadata +14 -29
- data/lib/graphiti.rb +0 -10
- data/lib/graphiti/attribute.rb +0 -86
- data/lib/graphiti/controller.rb +0 -54
- data/lib/graphiti/controller/action_configuration.rb +0 -46
- data/lib/graphiti/controller/configuration.rb +0 -32
- data/lib/graphiti/controller/controller_function.rb +0 -41
- data/lib/graphiti/controller/request.rb +0 -40
- data/lib/graphiti/errors/execution_error.rb +0 -18
- data/lib/graphiti/errors/validation_error.rb +0 -26
- data/lib/graphiti/model.rb +0 -33
- data/lib/graphiti/model/configuration.rb +0 -81
- data/lib/graphiti/router.rb +0 -65
- data/lib/graphiti/router/action.rb +0 -21
- data/lib/graphiti/router/mutation_action.rb +0 -18
- data/lib/graphiti/router/query_action.rb +0 -18
- data/lib/graphiti/router/resource_actions_builder.rb +0 -82
- data/lib/graphiti/router/schema_builder.rb +0 -37
- data/lib/graphiti/version.rb +0 -5
- data/lib/graphql_rails/controller/action_path_parser.rb +0 -75
- data/lib/graphql_rails/router/action.rb +0 -21
- data/lib/graphql_rails/router/resource_actions_builder.rb +0 -82
@@ -4,18 +4,22 @@ module GraphqlRails
|
|
4
4
|
class Router
|
5
5
|
# builds GraphQL::Schema based on previously defined grahiti data
|
6
6
|
class SchemaBuilder
|
7
|
-
attr_reader :queries, :mutations
|
7
|
+
attr_reader :queries, :mutations, :raw_actions
|
8
8
|
|
9
|
-
def initialize(queries:, mutations:)
|
9
|
+
def initialize(queries:, mutations:, raw_actions:)
|
10
10
|
@queries = queries
|
11
11
|
@mutations = mutations
|
12
|
+
@raw_actions = raw_actions
|
12
13
|
end
|
13
14
|
|
14
15
|
def call
|
15
16
|
query_type = build_type('Query', queries)
|
16
17
|
mutation_type = build_type('Mutation', mutations)
|
18
|
+
raw = raw_actions
|
17
19
|
|
18
20
|
GraphQL::Schema.define do
|
21
|
+
raw.each { |action| send(action[:name], *action[:args], &action[:block]) }
|
22
|
+
|
19
23
|
query(query_type)
|
20
24
|
mutation(mutation_type)
|
21
25
|
end
|
@@ -23,12 +27,12 @@ module GraphqlRails
|
|
23
27
|
|
24
28
|
private
|
25
29
|
|
26
|
-
def build_type(type_name,
|
30
|
+
def build_type(type_name, routes)
|
27
31
|
GraphQL::ObjectType.define do
|
28
32
|
name type_name
|
29
33
|
|
30
|
-
|
31
|
-
field
|
34
|
+
routes.each do |route|
|
35
|
+
field route.name, Controller::ControllerFunction.from_route(route)
|
32
36
|
end
|
33
37
|
end
|
34
38
|
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'graphql_rails'
|
4
|
+
|
5
|
+
module GraphqlRails
|
6
|
+
# provides all helpers neccesary for testing graphql controllers. It is similar to rspec controller specs
|
7
|
+
#
|
8
|
+
# Adds 3 helper methods in to rspec test:
|
9
|
+
# * mutation
|
10
|
+
# * query
|
11
|
+
# * result
|
12
|
+
# `mutation` and `query`` methods are identical
|
13
|
+
#
|
14
|
+
# Usage:
|
15
|
+
# it 'works' do
|
16
|
+
# mutation(:createUser, params: { name: 'John'}, context: { current_user_id: 1 })
|
17
|
+
# expect(response).to be_successful?
|
18
|
+
# expect(response)not_to be_failure?
|
19
|
+
# expect(response.result).to be_a(User)
|
20
|
+
# expect(response.errors).to be_empty
|
21
|
+
# end
|
22
|
+
module RSpecControllerHelpers
|
23
|
+
# contains all details about testing response. Similar as in rspec controllers tests
|
24
|
+
class Response
|
25
|
+
def initialize(request)
|
26
|
+
@request = request
|
27
|
+
end
|
28
|
+
|
29
|
+
def result
|
30
|
+
request.object_to_return
|
31
|
+
end
|
32
|
+
|
33
|
+
def errors
|
34
|
+
request.errors
|
35
|
+
end
|
36
|
+
|
37
|
+
def success?
|
38
|
+
request.errors.empty?
|
39
|
+
end
|
40
|
+
|
41
|
+
def successful?
|
42
|
+
success?
|
43
|
+
end
|
44
|
+
|
45
|
+
def failure?
|
46
|
+
!success?
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
attr_reader :request
|
52
|
+
end
|
53
|
+
|
54
|
+
# instance which has similar behavior as
|
55
|
+
class FakeContext
|
56
|
+
extend Forwardable
|
57
|
+
|
58
|
+
def_delegators :@provided_values, :[], :[]=, :to_h, :key?, :fetch
|
59
|
+
|
60
|
+
def initialize(values:)
|
61
|
+
@errors = []
|
62
|
+
@provided_values = values
|
63
|
+
end
|
64
|
+
|
65
|
+
def add_error(error)
|
66
|
+
@errors << error
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# controller request object more suitable for testing
|
71
|
+
class Request < GraphqlRails::Controller::Request
|
72
|
+
def initialize(params, context)
|
73
|
+
super(nil, params, context)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def query(query_name, params: {}, context: {})
|
78
|
+
context_object = FakeContext.new(values: context)
|
79
|
+
request = Request.new(params, context_object)
|
80
|
+
described_class.new(request).call(query_name)
|
81
|
+
|
82
|
+
@response = Response.new(request)
|
83
|
+
@response
|
84
|
+
end
|
85
|
+
|
86
|
+
def mutation(*args)
|
87
|
+
query(*args)
|
88
|
+
end
|
89
|
+
|
90
|
+
def response
|
91
|
+
@response
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Povilas Jurčys
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-05-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '4'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '4'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -102,29 +102,12 @@ files:
|
|
102
102
|
- bin/console
|
103
103
|
- bin/setup
|
104
104
|
- graphql_rails.gemspec
|
105
|
-
- lib/graphiti.rb
|
106
|
-
- lib/graphiti/attribute.rb
|
107
|
-
- lib/graphiti/controller.rb
|
108
|
-
- lib/graphiti/controller/action_configuration.rb
|
109
|
-
- lib/graphiti/controller/configuration.rb
|
110
|
-
- lib/graphiti/controller/controller_function.rb
|
111
|
-
- lib/graphiti/controller/request.rb
|
112
|
-
- lib/graphiti/errors/execution_error.rb
|
113
|
-
- lib/graphiti/errors/validation_error.rb
|
114
|
-
- lib/graphiti/model.rb
|
115
|
-
- lib/graphiti/model/configuration.rb
|
116
|
-
- lib/graphiti/router.rb
|
117
|
-
- lib/graphiti/router/action.rb
|
118
|
-
- lib/graphiti/router/mutation_action.rb
|
119
|
-
- lib/graphiti/router/query_action.rb
|
120
|
-
- lib/graphiti/router/resource_actions_builder.rb
|
121
|
-
- lib/graphiti/router/schema_builder.rb
|
122
|
-
- lib/graphiti/version.rb
|
123
105
|
- lib/graphql_rails.rb
|
124
106
|
- lib/graphql_rails/attribute.rb
|
107
|
+
- lib/graphql_rails/attribute/attribute_type_parser.rb
|
125
108
|
- lib/graphql_rails/controller.rb
|
109
|
+
- lib/graphql_rails/controller/action.rb
|
126
110
|
- lib/graphql_rails/controller/action_configuration.rb
|
127
|
-
- lib/graphql_rails/controller/action_path_parser.rb
|
128
111
|
- lib/graphql_rails/controller/configuration.rb
|
129
112
|
- lib/graphql_rails/controller/controller_function.rb
|
130
113
|
- lib/graphql_rails/controller/request.rb
|
@@ -132,12 +115,14 @@ files:
|
|
132
115
|
- lib/graphql_rails/errors/validation_error.rb
|
133
116
|
- lib/graphql_rails/model.rb
|
134
117
|
- lib/graphql_rails/model/configuration.rb
|
118
|
+
- lib/graphql_rails/model/graphql_type_builder.rb
|
135
119
|
- lib/graphql_rails/router.rb
|
136
|
-
- lib/graphql_rails/router/
|
137
|
-
- lib/graphql_rails/router/
|
138
|
-
- lib/graphql_rails/router/
|
139
|
-
- lib/graphql_rails/router/
|
120
|
+
- lib/graphql_rails/router/mutation_route.rb
|
121
|
+
- lib/graphql_rails/router/query_route.rb
|
122
|
+
- lib/graphql_rails/router/resource_routes_builder.rb
|
123
|
+
- lib/graphql_rails/router/route.rb
|
140
124
|
- lib/graphql_rails/router/schema_builder.rb
|
125
|
+
- lib/graphql_rails/rspec_controller_helpers.rb
|
141
126
|
- lib/graphql_rails/version.rb
|
142
127
|
homepage: https://github.com/povilasjurcys/graphql_rails
|
143
128
|
licenses:
|
data/lib/graphiti.rb
DELETED
data/lib/graphiti/attribute.rb
DELETED
@@ -1,86 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'graphql'
|
4
|
-
|
5
|
-
module GraphqlRails
|
6
|
-
# contains info about single graphql attribute
|
7
|
-
class Attribute
|
8
|
-
attr_reader :name, :type
|
9
|
-
|
10
|
-
def initialize(name, type = nil, required: false, hidden: false)
|
11
|
-
@name = name.to_s
|
12
|
-
@type = parse_type(type || type_by_attribute_name)
|
13
|
-
@required = required
|
14
|
-
@hidden = hidden
|
15
|
-
end
|
16
|
-
|
17
|
-
def graphql_field_type
|
18
|
-
@graphql_field_type ||= required? ? type.to_non_null_type : type
|
19
|
-
end
|
20
|
-
|
21
|
-
def required?
|
22
|
-
@required
|
23
|
-
end
|
24
|
-
|
25
|
-
def hidden?
|
26
|
-
@hidden
|
27
|
-
end
|
28
|
-
|
29
|
-
def field_name
|
30
|
-
field =
|
31
|
-
if name.end_with?('?')
|
32
|
-
"is_#{name.remove(/\?\Z/)}"
|
33
|
-
else
|
34
|
-
name
|
35
|
-
end
|
36
|
-
|
37
|
-
field.camelize(:lower)
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def type_by_attribute_name
|
43
|
-
case name
|
44
|
-
when 'id', /_id\Z/
|
45
|
-
GraphQL::ID_TYPE
|
46
|
-
when /\?\Z/
|
47
|
-
GraphQL::BOOLEAN_TYPE
|
48
|
-
else
|
49
|
-
GraphQL::STRING_TYPE
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def parse_type(type)
|
54
|
-
if graphql_type?(type)
|
55
|
-
type
|
56
|
-
elsif type.is_a?(String) || type.is_a?(Symbol)
|
57
|
-
map_type_name_to_type(type.to_s.downcase)
|
58
|
-
else
|
59
|
-
raise "Unsupported type #{type.inspect} (class: #{type.class})"
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def graphql_type?(type)
|
64
|
-
type.is_a?(GraphQL::BaseType) ||
|
65
|
-
type.is_a?(GraphQL::ObjectType) ||
|
66
|
-
(defined?(GraphQL::Schema::Member) && type.is_a?(Class) && type < GraphQL::Schema::Member)
|
67
|
-
end
|
68
|
-
|
69
|
-
def map_type_name_to_type(type_name)
|
70
|
-
case type_name
|
71
|
-
when 'id'
|
72
|
-
GraphQL::ID_TYPE
|
73
|
-
when 'int', 'integer'
|
74
|
-
GraphQL::INT_TYPE
|
75
|
-
when 'string', 'str', 'text', 'time', 'date'
|
76
|
-
GraphQL::STRING_TYPE
|
77
|
-
when 'bool', 'boolean', 'mongoid::boolean'
|
78
|
-
GraphQL::BOOLEAN_TYPE
|
79
|
-
when 'float', 'double', 'decimal'
|
80
|
-
GraphQL::FLOAT_TYPE
|
81
|
-
else
|
82
|
-
raise "Don't know how to parse type with name #{type_name.inspect}"
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
data/lib/graphiti/controller.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support/hash_with_indifferent_access'
|
4
|
-
require_relative 'controller/configuration'
|
5
|
-
require_relative 'controller/request'
|
6
|
-
|
7
|
-
module GraphqlRails
|
8
|
-
# base class for all graphql_rails controllers
|
9
|
-
class Controller
|
10
|
-
class << self
|
11
|
-
def before_action(action_name)
|
12
|
-
controller_configuration.add_before_action(action_name)
|
13
|
-
end
|
14
|
-
|
15
|
-
def action(method_name)
|
16
|
-
controller_configuration.action(method_name)
|
17
|
-
end
|
18
|
-
|
19
|
-
def controller_configuration
|
20
|
-
@controller_configuration ||= Controller::Configuration.new(self)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def initialize(graphql_request)
|
25
|
-
@graphql_request = graphql_request
|
26
|
-
end
|
27
|
-
|
28
|
-
def call(method_name)
|
29
|
-
self.class.controller_configuration.before_actions.each { |action_name| send(action_name) }
|
30
|
-
|
31
|
-
begin
|
32
|
-
response = public_send(method_name)
|
33
|
-
render response if graphql_request.no_object_to_return?
|
34
|
-
rescue StandardError => error
|
35
|
-
render error: error
|
36
|
-
end
|
37
|
-
|
38
|
-
graphql_request.object_to_return
|
39
|
-
end
|
40
|
-
|
41
|
-
protected
|
42
|
-
|
43
|
-
attr_reader :graphql_request
|
44
|
-
|
45
|
-
def render(object = nil, error: nil, errors: Array(error))
|
46
|
-
graphql_request.errors = errors
|
47
|
-
graphql_request.object_to_return = object
|
48
|
-
end
|
49
|
-
|
50
|
-
def params
|
51
|
-
@params = HashWithIndifferentAccess.new(graphql_request.params)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support/core_ext/string/filters'
|
4
|
-
require 'graphql_rails/attribute'
|
5
|
-
|
6
|
-
module GraphqlRails
|
7
|
-
class Controller
|
8
|
-
# stores all graphql_rails contoller specific config
|
9
|
-
class ActionConfiguration
|
10
|
-
attr_reader :attributes, :return_type
|
11
|
-
|
12
|
-
def initialize
|
13
|
-
@attributes = {}
|
14
|
-
@can_return_nil = false
|
15
|
-
end
|
16
|
-
|
17
|
-
def permit(*no_type_attributes, **typed_attributes)
|
18
|
-
no_type_attributes.each { |attribute| permit_attribute(attribute) }
|
19
|
-
typed_attributes.each { |attribute, type| permit_attribute(attribute, type) }
|
20
|
-
self
|
21
|
-
end
|
22
|
-
|
23
|
-
def can_return_nil
|
24
|
-
@can_return_nil = true
|
25
|
-
self
|
26
|
-
end
|
27
|
-
|
28
|
-
def returns(new_return_type)
|
29
|
-
@return_type = new_return_type
|
30
|
-
self
|
31
|
-
end
|
32
|
-
|
33
|
-
def can_return_nil?
|
34
|
-
@can_return_nil
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def permit_attribute(name, type = nil)
|
40
|
-
field_name = name.to_s.remove(/!\Z/)
|
41
|
-
required = name.to_s.end_with?('!')
|
42
|
-
attributes[field_name] = Attribute.new(field_name, type, required: required)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support/core_ext/string/inflections'
|
4
|
-
require 'graphql_rails/attribute'
|
5
|
-
require 'graphql_rails/controller/action_configuration'
|
6
|
-
|
7
|
-
module GraphqlRails
|
8
|
-
class Controller
|
9
|
-
# stores all graphql_rails contoller specific config
|
10
|
-
class Configuration
|
11
|
-
attr_reader :before_actions
|
12
|
-
|
13
|
-
def initialize(controller)
|
14
|
-
@controller = controller
|
15
|
-
@before_actions = Set.new
|
16
|
-
@action_by_name = {}
|
17
|
-
end
|
18
|
-
|
19
|
-
def add_before_action(name)
|
20
|
-
before_actions << name
|
21
|
-
end
|
22
|
-
|
23
|
-
def action(method_name)
|
24
|
-
@action_by_name[method_name.to_s] ||= ActionConfiguration.new
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
attr_reader :controller
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|