Skip to content

Commit

Permalink
Pass in schema as an option
Browse files Browse the repository at this point in the history
  • Loading branch information
kbaum committed Oct 12, 2023
1 parent f1ebb33 commit 56495fd
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 2 deletions.
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ A friendlier Ruby client for consuming GraphQL-based APIs. Built on top of your

- [Installation](#installation)
- [Usage](#usage)
- [Schema storing and loading on disk](#schema-storing-and-loading-on-disk)
- [Schema Storing and Loading on Disk](#schema-storing-and-loading-on-disk)
- [Preloading Schema Once](#preloading-schema-once)
- [Error Handling](#error-handling)
- [Executing Parameterized Queries and Mutations](#executing-parameterized-queries-and-mutations)
- [Parse and Execute Queries Separately](#parse-and-execute-queries-separately)
Expand Down Expand Up @@ -140,6 +141,30 @@ client = Client.new(url, schema_path: 'config/your_graphql_schema.json')
client.schema.dump! # you only need to call this when graphql schema changes
```

### Preloading schema once

Even if caching the schema on disk, instantiating `Graphlient::Client` often can be both time and memory intensive due to reading in the schema for each instance. This is especially true if the schema is a large file. To get around these performance issues, instantiate your schema once and pass it in as a configuration option.

One time in an initializer

```ruby
$schema = Graphlient::Schema.new(
'https://graphql.foo.com/graphql', 'lib/graphql_schema_foo.json'
)
```

Pass in each time you initialize a client

```
client = Graphlient::Client.new(
$schema.http,
$schema: schema,
headers: {
'Authorization' => 'Bearer 123',
}
)
```

### Error Handling

Unlike graphql-client, Graphlient will always raise an exception unless the query has succeeded.
Expand Down
11 changes: 10 additions & 1 deletion lib/graphlient/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ module Graphlient
class Client
attr_accessor :uri, :options

class InvalidConfigurationError < StandardError; end

def initialize(url, options = {}, &_block)
@url = url
@options = options.dup
raise_error_if_invalid_configuration!
yield self if block_given?
end

Expand Down Expand Up @@ -51,11 +54,17 @@ def http(&block)
end

def schema
@schema ||= Graphlient::Schema.new(http, schema_path)
@schema ||= options[:schema] || Graphlient::Schema.new(http, schema_path)
end

private

def raise_error_if_invalid_configuration!
if options.key?(:schema_path) && options.key?(:schema)
raise InvalidConfigurationError, 'schema_path and schema cannot both be provided'
end
end

def schema_path
return options[:schema_path].to_s if options[:schema_path]
end
Expand Down
20 changes: 20 additions & 0 deletions spec/graphlient/client_schema_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,25 @@
expect(client.schema.path).to eq 'config/schema.json'
end
end

context 'when preloaded schema is provided' do
let(:schema) { Graphlient::Schema.new(url, 'spec/support/fixtures/invoice_api.json') }
let(:client) { described_class.new(url, schema: schema) }

it 'returns the passed in schema' do
expect(client.schema).not_to be_nil
expect(client.schema).to eq(schema)
end
end

context 'when and a schema and a schema path are provided' do
let(:schema) { Graphlient::Schema.new(url, 'spec/support/fixtures/invoice_api.json') }
let(:client) { described_class.new(url, schema: schema, schema_path: 'spec/support/fixtures/invoice_api.json') }

it 'raises an invalid configuration error' do
expect { client }.to raise_error(Graphlient::Client::InvalidConfigurationError,
/schema_path and schema cannot both be provided/)
end
end
end
end

0 comments on commit 56495fd

Please sign in to comment.