Project

tinygql

0.03
The project is in a healthy, maintained state
Yet another GraphQL parser written in Ruby.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 5.14
~> 13.0
 Project Readme

TinyGQL

Very experimental GraphQL parser. It's mostly reusing the lexer from GraphQL-Ruby, but the parser is a hand-written recursive descent parser.

I want to target this at server side applications, so the parser eliminates some nice stuff for humans (namely line / column information, and it throws away comments).

Right now this code:

  1. Doesn't know how to execute anything. It just gives you an AST
  2. Isn't used anywhere (except in your heart, *but hopefully in production someday!)

Usage

You can get an AST like this:

ast = TinyGQL.parse "{ cool }"

The AST is iterable, so you can use the each method:

ast = TinyGQL.parse "{ cool }"
ast.each do |node|
  p node.class
end

Nodes have predicate methods, so if you want to find particular nodes just use a predicate:

ast = TinyGQL.parse "{ cool }"
p ast.find_all(&:field?).map(&:name) # => ["cool"]

If you need a more advanced way to iterate nodes, you can use a visitor:

class Viz
  include TinyGQL::Visitors::Visitor

  def handle_field obj
    p obj.name # => cool
    super
  end
end

ast = TinyGQL.parse "{ cool }"
ast.accept(Viz.new)

If you would like a functional way to collect data from the tree, use the Fold module:

module Fold
  extend TinyGQL::Visitors::Fold

  def self.handle_field obj, seed
    super(obj, seed + [obj.name])
  end
end

ast = TinyGQL.parse "{ neat { cool } }"
p ast.fold(Fold, []) # => ["neat", "cool"]

Nodes store their position in the source GraphQL document. If you'd like to extract the line number of the node, you'll need to keep a reference to the document and pass it to the line method on the node:

doc = <<-eod
mutation {
  likeStory(sturyID: 12345) {
    story {
      likeCount
    }
  }
}

eod

parser = TinyGQL::Parser.new doc
ast = parser.parse

ast.find_all(&:field?).each { |node|
  p node.name => node.line(doc)
}

LICENSE:

I've licensed this code as Apache 2.0, but the lexer is from GraphQL-Ruby and is under the MIT license.