Skip to content

Commit

Permalink
Added support for query variables and parameterized mutations.
Browse files Browse the repository at this point in the history
  • Loading branch information
dblock committed Oct 18, 2017
1 parent 7588e11 commit 984dd8b
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 28 deletions.
11 changes: 6 additions & 5 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2017-10-18 15:31:52 -0400 using RuboCop version 0.47.1.
# on 2017-10-18 16:23:41 -0400 using RuboCop version 0.47.1.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.

# Offense count: 7
# Offense count: 8
# Configuration parameters: CountComments, ExcludedMethods.
Metrics/BlockLength:
Max: 82
Expand All @@ -17,7 +17,7 @@ Metrics/BlockLength:
Metrics/LineLength:
Max: 177

# Offense count: 2
# Offense count: 3
# Configuration parameters: CountComments.
Metrics/MethodLength:
Max: 12
Expand All @@ -33,13 +33,14 @@ Style/Documentation:
- 'lib/graphlient/extensions/query.rb'
- 'lib/graphlient/query.rb'

# Offense count: 1
# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: line_count_dependent, lambda, literal
Style/Lambda:
Exclude:
- 'spec/support/queries/root_query.rb'
- 'spec/support/mutations/create_invoice_mutation.rb'
- 'spec/support/queries/query.rb'

# Offense count: 2
Style/MethodMissing:
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* [#13](https://github.com/ashkan18/graphlient/pull/13): Support named queries and make sure, this is braking change where we no longer support queries that don't start with `query` - [@ashkan18](https://github.com/ashkan18).
* [#17](https://github.com/ashkan18/graphlient/pull/17): Enable customizing of Faraday middleware - [@dblock](https://github.com/dblock).
* [#19](https://github.com/ashkan18/graphlient/pull/19): Expose `client.schema` - [@dblock](https://github.com/dblock).

* [#20](https://github.com/ashkan18/graphlient/pull/20): Added support for query variables and parameterized mutations - [@dblock](https://github.com/dblock).
* Your contribution here.

### 0.0.5 (10/5/2017)
Expand Down
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,37 @@ A successful response object always contains data which can be iterated upon. Th
response.data.invoice.line_items.first.price
```

### Executing Mutations

Graphlient can execute mutations by providing variables as query parameters.

```ruby
client.query(input: { fee_in_cents: 12_345 }) do
mutation(:$input => :createInvoiceInput!) do
createInvoice(input: :$input) do
id
fee_in_cents
end
end
end
```

Alternatively you can construct the query with variable values.

```ruby
client.query do
mutation do
createInvoice(input: { fee_in_cents: 12_345 }) do
id
fee_in_cents
end
end
end
```

### Generate Queries with Graphlient::Query

You can directly use `Graphlient::Query` to generate GraphQL queries.
You can directly use `Graphlient::Query` to generate raw GraphQL queries.

```ruby
query = Graphlient::Query.new do
Expand Down
7 changes: 5 additions & 2 deletions lib/graphlient/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ def initialize(url, options = {}, &_block)
yield self if block_given?
end

def query(&block)
def query(variables = nil, &block)
query_str = Graphlient::Query.new do
instance_eval(&block)
end
parsed_query = client.parse(query_str.to_s)
client.allow_dynamic_queries = true
client.query(parsed_query, context: @options)
query_params = {}
query_params[:context] = @options if @options
query_params[:variables] = variables if variables
client.query(parsed_query, query_params)
rescue GraphQL::Client::Error => e
raise Graphlient::Errors::Client.new(e.message, e)
end
Expand Down
4 changes: 2 additions & 2 deletions lib/graphlient/query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Graphlient
class Query
attr_accessor :query_str

ACTIONS = %w(query mutation subscription fragment).freeze
ACTIONS = %w(query subscription fragment).freeze

def initialize(&block)
@indents = 0
Expand All @@ -29,7 +29,7 @@ def respond_to_missing?(m, include_private = false)
end

def to_s
query_str
query_str.strip
end

private
Expand Down
55 changes: 52 additions & 3 deletions spec/graphlient/client_query_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
end
end
end.to raise_error Graphlient::Errors::Client do |e|
expect(e.to_s).to eq "Field 'invoice' doesn't exist on type 'RootQuery'"
expect(e.to_s).to eq "Field 'invoice' doesn't exist on type 'Query'"
end
end

it 'returns expected response with block' do
it 'returns a response from a query' do
response = client.query do
query do
invoices(ids: [10]) do
Expand All @@ -31,9 +31,58 @@
end

invoices = response.data.invoices
expect(invoices.first.id).to eq '1231'
expect(invoices.first.id).to eq 1231
expect(invoices.first.fee_in_cents).to eq 20_000
end

it 'returns a response from a mutation' do
response = client.query do
mutation do
createInvoice(input: { fee_in_cents: 12_345 }) do
id
fee_in_cents
end
end
end

invoice = response.data.create_invoice.first
expect(invoice.id).to eq 1231
expect(invoice.fee_in_cents).to eq 12_345
end
end

context 'parameterized query' do
it 'fails when missing input' do
response = client.query do
mutation('$input' => :createInvoiceInput!) do
createInvoice(input: :$input) do
id
fee_in_cents
end
end
end

expect(response.errors.messages['data']).to eq(
[
'Variable input of type createInvoiceInput! was provided invalid value'
]
)
end

it 'executes the mutation' do
response = client.query(input: { fee_in_cents: 12_345 }) do
mutation(:$input => :createInvoiceInput!) do
createInvoice(input: :$input) do
id
fee_in_cents
end
end
end

invoice = response.data.create_invoice.first
expect(invoice.id).to eq 1231
expect(invoice.fee_in_cents).to eq 12_345
end
end
end
end
20 changes: 13 additions & 7 deletions spec/support/dummy_app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,17 @@
end

post '/graphql' do
headers['Content-Type'] = 'application/json'
DummySchema.execute(
params[:query],
variables: params[:variables] ? JSON.parse(params[:variables]) : {},
context: {},
operation_name: params[:operationName]
).to_json
begin
headers['Content-Type'] = 'application/json'
DummySchema.execute(
params[:query],
variables: params[:variables] ? JSON.parse(params[:variables]) : {},
context: {},
operation_name: params[:operationName]
).to_json
rescue StandardError => e
warn e
warn e.backtrace.join("\n")
raise e
end
end
8 changes: 5 additions & 3 deletions spec/support/dummy_schema.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
require_relative 'queries/root_query'
require_relative 'types/invoice_type'

require_relative 'queries/query'
require_relative 'mutations/mutation'

DummySchema = GraphQL::Schema.define do
query RootQuery
max_depth 5
query Query
mutation Mutation
end
16 changes: 16 additions & 0 deletions spec/support/mutations/create_invoice_mutation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
CreateInvoiceMutation = GraphQL::Relay::Mutation.define do
name 'createInvoice'

input_field :fee_in_cents, !types.Int

return_type types[InvoiceType]

resolve ->(_object, inputs, _ctx) {
[
OpenStruct.new(
id: 1231,
fee_in_cents: inputs[:fee_in_cents]
)
]
}
end
7 changes: 7 additions & 0 deletions spec/support/mutations/mutation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require_relative './create_invoice_mutation'

Mutation = GraphQL::ObjectType.define do
name 'Mutation'

field :createInvoice, field: CreateInvoiceMutation.field
end
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
RootQuery = GraphQL::ObjectType.define do
name 'RootQuery'
description 'Root query'
Query = GraphQL::ObjectType.define do
name 'Query'

field :invoices, types[InvoiceType] do
argument :ids, types[types.ID]
Expand Down
2 changes: 1 addition & 1 deletion spec/support/types/invoice_type.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
InvoiceType = GraphQL::ObjectType.define do
name 'Invoice'
description 'An Invoice'
field :id, !types.ID
field :id, !types.Int
field :fee_in_cents, types.Int
end

0 comments on commit 984dd8b

Please sign in to comment.