/graphql

Primary LanguageRubyMIT LicenseMIT

graphql graphql-ruby

Build Status Gem Version Code Climate Test Coverage built with love

A Ruby implementation of GraphQL.

Installation

Install from RubyGems by adding it to your Gemfile, then bundling.

# Gemfile
gem 'graphql'
$ bundle install

Overview

Declare types & build a schema

# Declare a type...
PostType = GraphQL::ObjectType.define do
  name "Post"
  description "A blog post"

  field :id, !types.ID
  field :title, !types.String
  field :body, !types.String
  field :comments, types[!CommentType]
end

# ...and a query root
QueryType = GraphQL::ObjectType.define do
  name "Query"
  description "The query root of this schema"

  field :post do
    type PostType
    argument :id, !types.ID
    resolve -> (obj, args, ctx) { Post.find(args["id"]) }
  end
end

# Then create your schema
Schema = GraphQL::Schema.define do
  query QueryType
  max_depth 8
end

Execute queries

Execute GraphQL queries on a given schema, from a query string.

result_hash = Schema.execute(query_string)
# {
#   "data" => {
#     "post" => {
#        "id" => 1,
#        "title" => "GraphQL is nice"
#     }
#   }
# }

Use with Relay

If you're building a backend for Relay, you'll need:

Goals

  • Implement the GraphQL spec & support a Relay front end
  • Provide idiomatic, plain-Ruby API with similarities to reference implementation where possible
  • Support Ruby on Rails and Relay

Getting Involved

  • Say hi & ask questions in the #ruby channel on Slack or on Twitter!
  • Report bugs by posting a description, full stack trace, and all relevant code in a GitHub issue.
  • Features & patches are welcome! Consider discussing it in an issue or in the #ruby channel on Slack to make sure we're on the same page.
  • Run the tests with rake test or start up guard with bundle exec guard.
  • Build the site with rake site:serve, then visit localhost:4000.

Related Projects

Code

Blog Posts

To Do

  • StaticValidation improvements
    • Use catch-all type/field/argument definitions instead of terminating traversal
    • Reduce ad-hoc traversals?
    • Validators are order-dependent, is this a smell?
    • Tests for interference between validators are poor
    • Maybe this is a candidate for a rewrite?
  • Add Rails-y argument validations, eg less_than: 100, max_length: 255, one_of: [...]
    • Must be customizable
  • Relay:
    • GlobalNodeIdentification.to_global_id should receive the type name and object, not id. (Or, maintain the "type_name, id in, type_name, id out" pattern?)
    • Reduce duplication in ArrayConnection / RelationConnection
    • Improve API for creating edges (better RANGE_ADD support)
    • If the new edge isn't a member of the connection's objects, raise a nice error
  • Missing Enum value should raise a descriptive error, not "key not found"
  • args should whitelist keys -- if you request a key that isn't defined for the field, it should 💥
  • Fix middleware
    • Handle out-of-bounds lookup, eg graphql-batch
    • Handle non-serial execution, eg @defer
  • Support non-instance-eval .define, eg .define { |defn| ... }
  • First-class promise support
    • like graphql-batch but more local
    • support promises in connection resolves
  • Add immutable transformation API to AST
    • Support working with AST as data
    • Adding fields to selections (__typename can go anywhere, others are type-specific)
    • Renaming fragments from local names to unique names
  • Support AST subclasses? This would be hard, I think classes are used as hash keys in many places.
  • Support object deep-copy (schema, type, field, argument)? To support multiple schemas based on the same types.
  • Improve the website
    • Feature the logo in the header
    • Split readme.md into index.md (a homepage with code samples) and a technical readme (how to install, link to homepage)
    • Move "Related projects" to a guide
    • Revisit guides, maybe split them into smaller, more specific pages
    • Put guide titles into the <title />