README.md in graphiti_graphql-0.1.1 vs README.md in graphiti_graphql-0.1.2

- old
+ new

@@ -1,35 +1,159 @@ # GraphitiGraphql -Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/graphiti_graphql`. To experiment with that code, run `bin/console` for an interactive prompt. +GraphQL (and Apollo Federation) support for Graphiti. Serve traditional Rails JSON, JSON:API or GraphQL with the same codebase. -TODO: Delete this and the text above, and describe your gem +Currently read-only, but you can add your own Mutations [manually](#blending-with-graphql-ruby). -## Installation +## Setup -Add this line to your application's Gemfile: +Add to your `Gemfile`: +```rb +gem 'graphiti', ">= 1.2.32" +gem "graphiti_graphql" +``` + +Mount the engine: + ```ruby -gem 'graphiti_graphql' +# config/routes.rb +Rails.application.routes.draw do + scope path: ApplicationResource.endpoint_namespace, defaults: { format: :jsonapi } do + # ... normal graphiti stuff ... + + mount GraphitiGraphQL::Engine, at: "/gql" + end +end ``` -And then execute: +For a default Graphiti app, you can now serve GraphQL by POSTing to `/api/v1/gql`. - $ bundle +That's it 🎉! -Or install it yourself as: +#### GraphiQL - $ gem install graphiti_graphql +You can add the GraphiQL editor to the project via [graphiql-rails](https://github.com/rmosolgo/graphiql-rails) as normal, but to save you the time here are the steps to make it work when Rails is running in API-only mode: +Add to the Gemfile: + +```ruby +gem "graphiql-rails" +gem 'sprockets', '~> 3' # https://github.com/rmosolgo/graphiql-rails/issues/53 +``` + +And then in `config/application.rb`: + +```ruby +# *Uncomment* this line! +# require "sprockets/railtie" +``` + ## Usage -TODO: Write usage instructions here +#### Blending with graphql-ruby -## Development +Define your Schema and Type classes as normal. Then in an initializer: -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. +```ruby +# config/initializers/graphiti.rb +GraphitiGraphQL.schema_class = MySchema +``` -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). +Any pre-existing GraphQL endpoint will continue working as normal. But the GQL endpoint you mounted in `config/routes.rb` will now serve BOTH your low-level `graphql-ruby` schema AND your Graphiti-specific schema. Note these cannot (currently) be served side-by-side on under `query` within the *same request*. -## Contributing +By default the GraphQL context will be `Graphiti.context[:object]`, which is the controller being called. You might want to customize this so your existing graphql-ruby code continues to expect the same context: -Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/graphiti_graphql. +```ruby +GraphitiGraphQL.define_context do |controller| + { current_user: controller.current_user } +end +``` + +#### Adding Federation Support + +Add to the Gemfile + +```ruby +gem "apollo-federation" +gem "graphql-batch" +``` + +And change the way we require `graphiti_graphql`: + +```ruby +gem "graphiti_graphql", require: "graphiti_graphql/federation" +``` + +To create a federated relationship: + +```ruby +# PositionResource +federated_belongs_to :employee +``` + +Or pass `type` and/or `foreign_key` to customize: + +```ruby +# type here is the GraphQL Type +federated_belongs_to :employee, type: "MyEmployee", foreign_key: :emp_id +``` + +For `has_many` it's a slightly different syntax because we're adding the relationship to the ***remote*** type: + +```ruby +federated_type("Employee").has_many :positions # foreign_key: optional +``` + +Finally, `has_many` accepts the traditional `params` block that works as normal: + +```ruby +federated_type("Employee").has_many :positions do + params do |hash| + hash[:filter][:active] = true + hash[:sort] = "-title" + end +end +``` + +Remember that any time you make a change that affects the schema, you will have to bounce your federation gateway. This is how Apollo Federation works when not in "managed" mode and is unrelated to `graphiti_graphql`. + +## Configuration + +#### Entrypoints + +By default all Graphiti resources will expose their `index` and `show` functionality. IOW `EmployeeResource` now serves a list at `Query#employees` and a single employee at `Query#employee(id: 123)`. To limit the entrypoints: + +```ruby +GraphitiGraphQL::Schema.entrypoints = [ + EmployeeResource +] +``` + +#### Schema Reloading + +You may want to automatically regenerate the GQL schema when when Rails reloads your classes, or you may not want to pay that performance penalty. To turn off the automatic reloading: + +```ruby +# config/initializers/graphiti.rb +GraphitiGraphQL.config.schema_reloading = false +``` + +#### `.graphql_entrypoint` + +If the field you want on `Query` can't be inferred from the class name: + +```ruby +class EmployeeResource < ApplicationResource + self.graphql_entrypoint = :workers +end +``` + +You can now + +``` +query { + workers { + firstName + } +} +```